This guide shows you how to instrument your PHP application with OpenTelemetry and send traces to SigNoz. The auto-instrumentation approach works with Laravel, WordPress, Symfony, Slim, and other PHP frameworks.
Prerequisites
- PHP 8.0 or newer
- PECL package manager
- Composer dependency manager
- A SigNoz Cloud account or self-hosted SigNoz instance
Send traces to SigNoz
Step 1. Set environment variables
export OTEL_PHP_AUTOLOAD_ENABLED=true
export OTEL_SERVICE_NAME=<service-name>
export OTEL_TRACES_EXPORTER=otlp
export OTEL_METRICS_EXPORTER=none
export OTEL_LOGS_EXPORTER=none
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.<region>.signoz.cloud:443
export OTEL_EXPORTER_OTLP_HEADERS=signoz-ingestion-key=<your-ingestion-key>
export OTEL_PROPAGATORS=baggage,tracecontext
Verify these values:
<region>: Your SigNoz Cloud region (us,eu, orin). See endpoints.<your-ingestion-key>: Your SigNoz ingestion key.<service-name>: A descriptive name for your service (e.g.,payment-service).
Step 2. Install the OpenTelemetry extension
sudo apt-get install gcc make autoconf
pecl install opentelemetry
Add to php.ini:
extension=opentelemetry.so
Verify: php --ri opentelemetry
PHP needs the OpenTelemetry extension loaded globally so that all processes can access it, including those spawned by web servers or commands like php artisan serve. Without this, auto-instrumentation packages will fail to install and no traces will be generated.
Add extension=opentelemetry.so to your main php.ini file. Run php --ini to find its location.
Step 1. Set environment variables
Add these environment variables to your deployment manifest:
env:
- name: OTEL_PHP_AUTOLOAD_ENABLED
value: "true"
- name: OTEL_SERVICE_NAME
value: "<service-name>"
- name: OTEL_TRACES_EXPORTER
value: "otlp"
- name: OTEL_METRICS_EXPORTER
value: "none"
- name: OTEL_LOGS_EXPORTER
value: "none"
- name: OTEL_EXPORTER_OTLP_PROTOCOL
value: "http/protobuf"
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "https://ingest.<region>.signoz.cloud:443"
- name: OTEL_EXPORTER_OTLP_HEADERS
value: "signoz-ingestion-key=<your-ingestion-key>"
- name: OTEL_PROPAGATORS
value: "baggage,tracecontext"
Verify these values:
<region>: Your SigNoz Cloud region (us,eu, orin). See endpoints.<your-ingestion-key>: Your SigNoz ingestion key.<service-name>: A descriptive name for your service.
Step 2. Install the OpenTelemetry extension in your Dockerfile
RUN pecl install opentelemetry \
&& docker-php-ext-enable opentelemetry
Step 1. Set environment variables
Set in your Dockerfile:
ENV OTEL_PHP_AUTOLOAD_ENABLED=true
ENV OTEL_SERVICE_NAME="<service-name>"
ENV OTEL_TRACES_EXPORTER="otlp"
ENV OTEL_METRICS_EXPORTER="none"
ENV OTEL_LOGS_EXPORTER="none"
ENV OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
ENV OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.<region>.signoz.cloud:443"
ENV OTEL_EXPORTER_OTLP_HEADERS="signoz-ingestion-key=<your-ingestion-key>"
ENV OTEL_PROPAGATORS="baggage,tracecontext"
Or pass them at runtime:
docker run -d -p 8080:80 \
-e OTEL_PHP_AUTOLOAD_ENABLED=true \
-e OTEL_SERVICE_NAME="<service-name>" \
-e OTEL_TRACES_EXPORTER="otlp" \
-e OTEL_METRICS_EXPORTER="none" \
-e OTEL_LOGS_EXPORTER="none" \
-e OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf" \
-e OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.<region>.signoz.cloud:443" \
-e OTEL_EXPORTER_OTLP_HEADERS="signoz-ingestion-key=<your-ingestion-key>" \
-e OTEL_PROPAGATORS="baggage,tracecontext" \
<your-image>
Verify these values:
<region>: Your SigNoz Cloud region (us,eu, orin). See endpoints.<your-ingestion-key>: Your SigNoz ingestion key.<service-name>: A descriptive name for your service.
Step 2. Install the OpenTelemetry extension in your Dockerfile
RUN pecl install opentelemetry \
&& docker-php-ext-enable opentelemetry
Step 1. Set environment variables
$env:OTEL_PHP_AUTOLOAD_ENABLED = "true"
$env:OTEL_SERVICE_NAME = "<service-name>"
$env:OTEL_TRACES_EXPORTER = "otlp"
$env:OTEL_METRICS_EXPORTER = "none"
$env:OTEL_LOGS_EXPORTER = "none"
$env:OTEL_EXPORTER_OTLP_PROTOCOL = "http/protobuf"
$env:OTEL_EXPORTER_OTLP_ENDPOINT = "https://ingest.<region>.signoz.cloud:443"
$env:OTEL_EXPORTER_OTLP_HEADERS = "signoz-ingestion-key=<your-ingestion-key>"
$env:OTEL_PROPAGATORS = "baggage,tracecontext"
Verify these values:
<region>: Your SigNoz Cloud region (us,eu, orin). See endpoints.<your-ingestion-key>: Your SigNoz ingestion key.<service-name>: A descriptive name for your service.
Step 2. Install the OpenTelemetry extension
- Download the DLL from the releases page
- Choose the version matching your PHP version and architecture (x64/x86, thread-safe/non-thread-safe)
- Place the DLL in your PHP
extdirectory - Add to
php.ini:extension=opentelemetry - Verify:
php --ri opentelemetry
Step 3. Install Composer dependencies
composer config allow-plugins.php-http/discovery false
composer require \
open-telemetry/sdk \
open-telemetry/exporter-otlp \
php-http/guzzle7-adapter
For framework-specific auto-instrumentation, add the corresponding package. See Framework instrumentation below.
Step 4. Create a custom span (optional)
Without a framework auto-instrumentation package, you need to create spans manually. Here's a minimal example:
<?php
require __DIR__ . '/vendor/autoload.php';
use OpenTelemetry\API\Globals;
$tracer = Globals::tracerProvider()->getTracer('my-app');
$span = $tracer->spanBuilder('handle-request')->startSpan();
try {
$span->setAttribute('http.method', $_SERVER['REQUEST_METHOD'] ?? 'GET');
// Your application logic here
echo json_encode(['message' => 'Hello!']);
} finally {
$span->end();
}
Step 5. Run your application
php -S localhost:8080 app.php
Framework instrumentation
OpenTelemetry PHP provides auto-instrumentation packages for popular frameworks and libraries. These packages automatically capture traces for HTTP requests, database queries, and other operations without requiring code changes.
Frameworks
Laravel
Additional package
composer require open-telemetry/opentelemetry-auto-laravel
Run command
php artisan serve
Validate
With your application running, verify traces are being sent to SigNoz:
- Trigger an action in your app that generates a web request. Hit the endpoint a few times.
- In SigNoz, open the Services tab and click Refresh. Your application should appear.
- Go to the Traces tab to see your application's traces.
Troubleshooting
Why don't traces appear in SigNoz?
Check that the OpenTelemetry extension is loaded:
php --ri opentelemetry
If you see "Extension 'opentelemetry' not present", the extension isn't installed correctly. Check your php.ini configuration.
Check environment variables are set:
echo $OTEL_EXPORTER_OTLP_ENDPOINT
echo $OTEL_SERVICE_NAME
Verify network connectivity:
curl -v https://ingest.<region>.signoz.cloud:443/v1/traces
Enable console exporter to verify spans are being created:
OTEL_TRACES_EXPORTER=console OTEL_PHP_AUTOLOAD_ENABLED=true php -S localhost:8080 app.php
If you see span output in your terminal but traces don't appear in SigNoz, the issue is with export configuration (endpoint, auth, or network). If no output appears, the instrumentation isn't capturing your requests.
PECL installation fails
If pecl install opentelemetry fails:
- Ensure build tools are installed (
gcc,make,autoconf) - Check your PHP version is 8.0 or higher:
php -v - Try installing with verbose output:
pecl install -v opentelemetry
Composer dependency conflicts
If you see dependency conflicts, try:
composer require open-telemetry/sdk --with-all-dependencies
Setup OpenTelemetry Collector (Optional)
What is the OpenTelemetry Collector?
Think of the OTel Collector as a middleman between your app and SigNoz. Instead of your application sending data directly to SigNoz, it sends everything to the Collector first, which then forwards it along.
Why use it?
- Cleaning up data - Filter out noisy traces you don't care about, or remove sensitive info before it leaves your servers.
- Keeping your app lightweight - Let the Collector handle batching, retries, and compression instead of your application code.
- Adding context automatically - The Collector can tag your data with useful info like which Kubernetes pod or cloud region it came from.
- Future flexibility - Want to send data to multiple backends later? The Collector makes that easy without changing your app.
See Switch from direct export to Collector for step-by-step instructions to convert your setup.
For more details, see Why use the OpenTelemetry Collector? and the Collector configuration guide.
Next steps
- Add manual instrumentation for custom spans and attributes
- Set up alerts for your PHP application
- Create dashboards to visualize metrics
- Explore supported PHP instrumentation libraries for automatic instrumentation of additional frameworks and libraries
Sample application: