SolarWinds APM PHP is an OpenTelemetry-based library for distributed tracing and observability in PHP applications. It provides automatic and manual instrumentation, seamless integration with the SolarWinds Observability platform, and supports modern PHP frameworks.
Before you begin, ensure you have:
Check your versions:
php -v
composer -vInstall the SolarWinds APM library:
composer require solarwinds/apmInstall a PSR-compatible HTTP client (required for OTLP exporter):
composer require guzzlehttp/guzzleSet your service key (via environment variable):
export SW_APM_SERVICE_KEY=<your-service-key>Set the APM collector endpoint which provides sampling settings, default is apm.collector.na-01.cloud.solarwinds.com. Also note down the OTLP ingestion endpoint that corresponds to your tenant, e.g. otel.collector.na-01.cloud.solarwinds.com:443. By default telemetry exports to a local OTLP endpoint, see the example section below on exporting directly or through a local OpenTelemetry Collector to SolarWinds Observability.
export SW_APM_COLLECTOR=<your-apm-collector-url>Install solarwinds/apm_ext which caches sampling settings to reduce request latency:
pie install solarwinds/apm_extTo minimize export delays, opentelemetry-php recommends an agent collector to receive the telemetry. We recommend using the SolarWinds OpenTelemetry Collector for better integration with SolarWinds Observability. Please refer to Solarwinds OpenTelemetry Collector documentation for install instructions, and the example section below on configuring it to receive telemetry from the PHP application and export to SolarWinds Observability.
This section demonstrates automatic instrumentation using Slim and SolarWinds APM.
composer init --no-interaction --require slim/slim:"^4" --require slim/psr7:"^1"
composer updateCreate index.php:
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
require __DIR__ . '/vendor/autoload.php';
$app = AppFactory::create();
$app->get('/rolldice', function (Request $request, Response $response) {
$result = random_int(1,6);
$response->getBody()->write(strval($result));
return $response;
});
$app->run();Run the app:
php -S localhost:8080Visit http://localhost:8080/rolldice to test.
Install the OpenTelemetry PHP extension (instructions) and verify:
php --ri opentelemetryAdd SolarWinds APM Library, the OTLP exporter dependency, and the Slim instrumentation. More instrumentation libraries can be found here:
composer config allow-plugins.php-http/discovery false
composer require solarwinds/apm guzzlehttp/guzzle open-telemetry/opentelemetry-auto-slimGet your <solarwinds-token> from SolarWinds SaaS Free Trial, and find the OTLP ingestion endpoint that corresponds to your tenant, e.g. otel.collector.na-01.cloud.solarwinds.com:443.
Start the app with tracing, make sure to replace <solarwinds-otlp-endpoint> and <solarwinds-token> with your actual value:
env OTEL_PHP_AUTOLOAD_ENABLED=true \
OTEL_SERVICE_NAME=php-example \
OTEL_TRACES_SAMPLER=solarwinds_http \
OTEL_PROPAGATORS=baggage,tracecontext,swotracestate,xtraceoptions \
OTEL_EXPERIMENTAL_RESPONSE_PROPAGATORS=xtrace,xtraceoptionsresponse \
OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=delta \
OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION=base2_exponential_bucket_histogram \
OTEL_EXPORTER_OTLP_ENDPOINT=<solarwinds-otlp-endpoint> \
OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer <solarwinds-token>" \
SW_APM_SERVICE_KEY=<solarwinds-token>:php-example \
php -S localhost:8080Reload http://localhost:8080/rolldice and make several requests, the Service and its telemetry will show up in SolarWinds Observability within a few minutes. We have automatic tracing with zero code change! Let's continue to install the following to optimize performance and reduce latency.
pie install solarwinds/apm_ext
## verify installation
php --ri apm_extCreate a config.yaml file with the following content. Make sure to replace <collector-name> and <solarwinds-otlp-endpoint> with your actual values.
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
extensions:
solarwinds:
collector_name: "<collector-name>" # Required parameter e.g. "my-collector"
grpc: &grpc_settings
endpoint: "<solarwinds-otlp-endpoint>" # Required parameter e.g. "otel.collector.na-01.cloud.solarwinds.com:443"
tls:
insecure: false
headers:
Authorization: "Bearer ${env:SOLARWINDS_TOKEN}"
swi-reporter: "otel solarwinds-otel-collector"
exporters:
otlp:
<<: *grpc_settings
service:
extensions: [solarwinds]
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlp]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [otlp]
logs:
receivers: [otlp]
processors: [batch]
exporters: [otlp]You can run the collector in a Docker container, make sure to replace <solarwinds-token> with your actual value:
docker run -e SOLARWINDS_TOKEN="<solarwinds-token>" -p 127.0.0.1:4317:4317 -p 127.0.0.1:4318:4318 -v ./config.yaml:/opt/default-config.yaml solarwinds/solarwinds-otel-collector:latest-verifiedRestart the app with tracing using the following to send data to the local collector:
env OTEL_PHP_AUTOLOAD_ENABLED=true \
OTEL_SERVICE_NAME=php-example \
OTEL_TRACES_SAMPLER=solarwinds_http \
OTEL_PROPAGATORS=baggage,tracecontext,swotracestate,xtraceoptions \
OTEL_EXPERIMENTAL_RESPONSE_PROPAGATORS=xtrace,xtraceoptionsresponse \
OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=delta \
OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION=base2_exponential_bucket_histogram \
SW_APM_SERVICE_KEY=<solarwinds-token>:php-example \
php -S localhost:8080Set a custom transaction name at the beginning of your application:
use Solarwinds\ApmPhp\API\TransactionName;
TransactionName::set('custom-transaction-name');If you are upgrading from version 8.x, fully uninstall the previous version before installing 9.x or later to avoid conflicts. Instruction can be found in the UPGRADE.md.
Contributions are welcome! See CONTRIBUTING.md for details.
For troubleshooting, refer to the Troubleshooting Guide.
Apache-2.0. See LICENSE for details.