OpenTelemetry Tracing API for PHP
TIP
This document teaches how to use OpenTelemetry PHP API. To learn how to install and configure OpenTelemetry PHP SDK, see Getting started with OpenTelemetry PHP.
Installation
OpenTelemetry-PHP is the PHP implementation of OpenTelemetry. It provides OpenTelemetry PHP API which you can use to instrument your application with OpenTelemetry traces.
First, install Composer using the installation instructions and add the following line to your project's composer.json
file, as this library has not reached a stable release status yet:
"minimum-stability": "dev"
Then, you can install uptrace-php:
composer require uptrace/uptrace
Quickstart
Step 1. Let's instrument the following function:
function insertUser(string $name, string $email) {
DB::insert('insert into users (name, email) values (?, ?)', [$name, $email]);
}
Step 2. Wrap the operation with a span:
$tracerProvider = $uptrace->createTracerProvider();
$tracer = $tracerProvider->getTracer('app_or_package_name');
function insertUser(string $name, string $email) {
$span = $tracer->spanBuilder('insert-user')->startSpan();
$spanScope = $span->activate();
DB::insert('insert into users (id, name) values (?, ?)', [$name, $email]);
$spanScope->detach();
$span->end();
}
Step 3. Record exceptions and set status code:
function insertUser(string $name, string $email) {
$span = $tracer->spanBuilder('insert-user')->startSpan();
$spanScope = $span->activate();
try {
DB::insert('insert into users (name, email) values (?, ?)', [$name, $email]);
} catch (\Exception $exc) {
$span->recordException($exc);
$span->setStatus("error", $exc->getMessage());
}
$spanScope->detach();
$span->end();
}
Step 4. Record contextual information with attributes:
function insertUser(string $name, string $email) {
$span = $tracer->spanBuilder('insert-user')->startSpan();
$spanScope = $span->activate();
if ($span.isRecording()) {
$span->setAttribute('enduser.name', $name);
$span->setAttribute('enduser.email', $email);
}
DB::insert('insert into users (name, email) values (?, ?)', [$name, $email]);
$spanScope->detach();
$span->end();
}
And that's it! The operation is fully instrumented.
Tracer
To start creating spans, you need a tracer. You can create a tracer by providing the name and version of the library/application doing the instrumentation:
$tracerProvider = $uptrace->createTracerProvider();
$tracer = $tracerProvider->getTracer("app_or_package_name");
You can have as many tracers as you want, but usually you need only one tracer for an app or a library. Later, you can use tracer names to identify the instrumentation that produces the spans.
Creating spans
Once you have a tracer, creating spans is easy:
use OpenTelemetry\API\Trace\SpanKind;
// Create a span with name "operation-name" and kind="server".
$span = $tracer->spanBuilder('operation-name')->setSpanKind(SpanKind::KIND_SERVER)->startSpan();
$spanScope = $span->activate();
doSomeWork();
// End the span when the operation we are measuring is done.
$spanScope->detach();
$span->end();
Adding span attributes
To record contextual information, you can annotate spans with attributes. For example, an HTTP endpoint may have such attributes as http.method = GET
and http.route = /projects/:id
.
// To avoid expensive computations, check that the span was sampled
// before setting any attributes.
if ($span->isRecording()) {
$span->setAttribute("http.method", "GET");
$span->setAttribute("http.route", "/projects/:id");
}
You can name attributes as you want, but for common operations you should use semantic attributes convention.
Adding span events
You can annotate spans with events, for example, you can use events to record log messages:
$span->addEvent("log", [
"log.severity" => "error",
"log.message" => "User not found",
"enduser.id" => "123",
]);
Setting status code
You can set error
status code to indicate that the operation contains an error:
} catch (\Exception $exc) {
$span->setStatus("error", $exc->getMessage());
}
Recording errors
OpenTelemetry provides a shortcut to record exceptions which is usually used together with setStatus
:
} catch (\Exception $exc) {
$span->setStatus("error", $exc->getMessage());
$span->recordException($exc);
}
Context
OpenTelemetry stores the active span in a context and saves the context in a pluggable context storage. You can nest contexts inside each other and OpenTelemetry will automatically activate the parent span context when you end the span.
The following code creates a new context and saves the span in it:
$span = $tracer->spanBuilder('operation-name')->startSpan();
$spanScope = $span->activate();
To get the active span from the current context:
use OpenTelemetry\API\Trace\Span;
$span = Span::getCurrent();
OpenTelemetry APM
Uptrace is an OpenTelemetry backend with an intuitive query builder, rich dashboards, alerting rules, and integrations for most languages and frameworks. It can process billions of spans and metrics on a single server and allows to monitor your applications at 10x lower cost.
Uptrace uses ClickHouse database to store traces, metrics, and logs. You can use it to monitor applications and set up automatic alerts to receive notifications via email, Slack, Telegram, and more.
You can get started with Uptrace by downloading a DEB/RPM package or a pre-compiled Go binary.