Skip to main content
The OpenTelemetry PHP SDK builds its providers from environment variables, so logs, metrics, and traces reach Bronto with almost no code. The opentelemetry extension auto-instruments Laravel, Symfony, Slim, PDO, and HTTP clients, and a Monolog handler bridges your existing log calls into the OTLP logs pipeline. The application exports to an OpenTelemetry Collector, which forwards to Bronto. If you don’t run a Collector, export directly to Bronto instead — the code is identical, only two environment variables change.

Prerequisites

Install dependencies

The auto-instrumentation extension is a PECL package:
Add extension=opentelemetry to your php.ini, then install the SDK and the instrumentation packages for your framework:
Replace opentelemetry-auto-laravel with the package for your framework — -symfony, -slim, -psr18, -pdo, and others. See PHP instrumentation libraries for the full list.

Configure the environment

OTEL_PHP_AUTOLOAD_ENABLED is what builds the tracer, meter, and logger providers from these variables at startup — without it the SDK stays inert. The exporters append the signal path (/v1/logs, /v1/metrics, /v1/traces) to the endpoint automatically. Two resource attributes determine how Bronto organises your data:
http://localhost:4318 is the standard OTLP/HTTP address for a Collector on the same host. Use the address reachable from your application if the Collector runs in another container, pod, or host. No authentication is needed between the application and the Collector — the Collector holds the Bronto API key.

Bridge your logs

Traces and metrics need no code. To route Monolog through the same pipeline, attach the OTel handler to your logger, taking the provider the autoloader already configured:
logging.php
On Monolog 2, use Logger::DEBUG in place of Level::Debug.

Instrument your application

Existing Monolog calls need no changes. For spans and instruments around your own business logic:
Any log emitted inside an active span automatically carries that span’s trace_id and span_id, so you can jump from a log line to its trace in Bronto.

Verify

Run your application, then check each signal in Bronto, filtering by the service.name you set:
  • Logs — the Search page, in the dataset named after your service
  • Metrics — the Metric Explorer
  • Traces — the Explore Traces page
If nothing arrives:
  • Confirm OTEL_PHP_AUTOLOAD_ENABLED=true is set in the environment the PHP process actually runs in — under PHP-FPM that means the pool config, not your shell.
  • Confirm the Collector is running and reachable at OTEL_EXPORTER_OTLP_ENDPOINT, and that its pipelines include an otlp receiver and the Bronto exporters.
  • Check php -m | grep opentelemetry lists the extension — without it, the auto-instrumentation packages do nothing.
For signal-specific reference material, see Send Metrics to Bronto and Send Traces to Bronto.
PHP’s request-per-process model means each request exports its own batch. In high-throughput deployments, point the SDK at a local Collector rather than at Bronto directly so batching and retries happen outside the request lifecycle.

Direct export to Bronto

Without a Collector, the application exports straight to Bronto over OTLP/HTTP. Point the endpoint at your Bronto region and add your API key:
See API Keys for how to create a key with ingestion permissions.
Prefer the Collector for multi-service environments — it batches, filters, and enriches telemetry, and keeps the API key out of every application. Direct export suits single services and simple architectures.

GenAI semantic conventions

If your application calls an LLM, OpenTelemetry’s GenAI semantic conventions define gen_ai.* span attributes for model, token usage, and prompt and response content.

Manual spans

PHP contrib has OpenAI client instrumentation, but it emits openai.* rather than the standard gen_ai.* fields. For portable attributes, set them yourself around each model call:
Message content (gen_ai.input.messages / gen_ai.output.messages) is opt-in by convention and off by default in the languages that have auto-instrumentation. Since you are setting attributes by hand, apply the same discipline — gate prompt and response content behind your own config flag rather than always sending it. See the GenAI span conventions for the full attribute list. For the recommended attribute set and Bronto search queries, see LLM Observability.