Adding PHP documentation for exporters, resources, propagation (#2415)

This commit is contained in:
Brett McBride 2023-03-01 23:23:39 +11:00 committed by GitHub
parent f99b39ab2b
commit 100e517d1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 322 additions and 52 deletions

View File

@ -0,0 +1,128 @@
---
title: Exporters
weight: 5
---
In order to visualize and analyze your telemetry, you will need to export it to
a backend. OpenTelemetry PHP provides exporters for some common open source
backends.
## OTLP
To send trace data to a OTLP endpoint (like the [collector](/docs/collector) or
Jaeger) you'll need to use the `open-telemetry/exporter-otlp` package:
```shell
composer require open-telemetry/exporter-otlp
```
If you use gRPC, you will also need to install the
`open-telemetry/transport-grpc` package:
```shell
composer require open-telemetry/transport-grpc
```
Next, configure the exporter with an OTLP endpoint. For example, you can update
`GettingStarted.php` from [Getting Started](../getting-started/) like the
following:
<!-- prettier-ignore-start -->
{{< tabpane >}}
{{< tab gRPC >}}
use OpenTelemetry\API\Common\Signal\Signals;
use OpenTelemetry\Contrib\Grpc\GrpcTransportFactory;
use OpenTelemetry\Contrib\Otlp\OtlpUtil;
use OpenTelemetry\Contrib\Otlp\SpanExporter;
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
use OpenTelemetry\SDK\Trace\TracerProvider;
$transport = (new GrpcTransportFactory())->create('http://collector:4317' . OtlpUtil::method(Signals::TRACE));
$exporter = new SpanExporter($transport);
{{< /tab >}}
{{< tab protobuf >}}
use OpenTelemetry\Contrib\Otlp\OtlpHttpTransportFactory;
use OpenTelemetry\Contrib\Otlp\SpanExporter;
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
use OpenTelemetry\SDK\Trace\TracerProvider;
$transport = (new OtlpHttpTransportFactory())->create('http://collector:4318/v1/traces', 'application/x-protobuf');
$exporter = new SpanExporter($transport);
{{< /tab>}}
{{< tab json >}}
use OpenTelemetry\Contrib\Otlp\OtlpHttpTransportFactory;
use OpenTelemetry\Contrib\Otlp\SpanExporter;
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
use OpenTelemetry\SDK\Trace\TracerProvider;
$transport = (new OtlpHttpTransportFactory())->create('http://collector:4318/v1/traces', 'application/json');
$exporter = new SpanExporter($transport);
{{< /tab >}}
{{< tab nd-json >}}
/* newline-delimited JSON */
use OpenTelemetry\Contrib\Otlp\OtlpHttpTransportFactory;
use OpenTelemetry\Contrib\Otlp\SpanExporter;
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
use OpenTelemetry\SDK\Trace\TracerProvider;
$transport = (new OtlpHttpTransportFactory())->create('http://collector:4318/v1/traces', 'application/x-ndjson');
$exporter = new SpanExporter($transport);
{{< /tab >}}
{{< /tabpane >}}
<!-- prettier-ignore-end -->
Then, register the exporter in a tracer provider:
```php
$tracerProvider = new TracerProvider(
new SimpleSpanProcessor($exporter)
);
$tracer = $tracerProvider->getTracer('io.opentelemetry.contrib.php');
```
To try out the example locally, you can run
[Jaeger](https://www.jaegertracing.io/) in a docker container:
```shell
docker run -d --name jaeger \
-e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \
-e COLLECTOR_OTLP_ENABLED=true \
-p 6831:6831/udp \
-p 6832:6832/udp \
-p 5778:5778 \
-p 16686:16686 \
-p 4317:4317 \
-p 4318:4318 \
-p 14250:14250 \
-p 14268:14268 \
-p 14269:14269 \
-p 9411:9411 \
jaegertracing/all-in-one:latest
```
## Zipkin
If you're using [Zipkin](https://zipkin.io/) to visualize traces, you'll need to
set it up first. Here's how to run it locally in a docker container.
```shell
docker run --rm -d -p 9411:9411 --name zipkin openzipkin/zipkin
```
Install the exporter package as a dependency for your application:
```shell
composer require open-telemetry/exporter-zipkin
```
Update the example to use the Zipkin exporter and to send data to your zipkin
backend:
```php
$transport = PsrTransportFactory::discover()->create('http://zipkin:9411/api/v2/spans', 'application/json');
$zipkinExporter = new ZipkinExporter($transport);
$tracerProvider = new TracerProvider(
new SimpleSpanProcessor($zipkinExporter)
);
$tracer = $tracerProvider->getTracer('io.opentelemetry.contrib.php');
```

View File

@ -80,7 +80,7 @@ composer require "php-http/guzzle7-adapter"
Now you can install the OpenTelemetry SDK:
```sh
composer require open-telemetry/opentelemetry
composer require open-telemetry/sdk
```
The example uses the `ConsoleSpanExporter`, which prints Spans to stdout. A Span

View File

@ -78,8 +78,8 @@ To do [Tracing](/docs/concepts/signals/traces/) you'll need to acquire a
**Note:** Methods of the OpenTelemetry SDK should never be called.
First, a `Tracer` must be acquired, which is responsible for creating spans and
interacting with the [Context](#context-propagation). A tracer is acquired by
using the OpenTelemetry API specifying the name and version of the [library
interacting with the [Context](../propagation/). A tracer is acquired by using
the OpenTelemetry API specifying the name and version of the [library
instrumenting][instrumentation library] the [instrumented library] or
application to be monitored. More information is available in the specification
chapter [Obtaining a Tracer].
@ -120,7 +120,7 @@ Most of the time, we want to correlate
[spans](/docs/concepts/signals/traces/#spans-in-opentelemetry) for nested
operations. OpenTelemetry supports tracing within processes and across remote
processes. For more details how to share context between remote processes, see
[Context Propagation](#context-propagation).
[Context Propagation](../propagation/).
For a method `a` calling a method `b`, the spans could be manually linked in the
following way:
@ -210,7 +210,7 @@ $span = $tracer->spanBuilder("span-with-links")
```
For more details how to read context from remote processes, see
[Context Propagation](#context-propagation).
[Context Propagation](../propagation/).
### Set span status and record exceptions
@ -240,53 +240,6 @@ try {
}
```
### Context Propagation
OpenTelemetry provides a text-based approach to propagate context to remote
services using the [W3C Trace Context](https://www.w3.org/TR/trace-context/)
HTTP headers.
The following presents an example of an outgoing HTTP request:
```php
$request = new Request('GET', 'http://localhost:8080/resource');
$outgoing = $tracer->spanBuilder('/resource')->setSpanKind(SpanKind::CLIENT)->startSpan();
$outgoing->setAttribute(TraceAttributes::HTTP_METHOD, $request->getMethod());
$outgoing->setAttribute(TraceAttributes::HTTP_URL, (string) $request->getUri());
$carrier = [];
TraceContextPropagator::getInstance()->inject($carrier);
foreach ($carrier as $name => $value) {
$request = $request->withAddedHeader($name, $value);
}
try {
$response = $client->send($request);
} finally {
$outgoing->end();
}
```
Similarly, the text-based approach can be used to read the W3C Trace Context
from incoming requests. The following presents an example of processing an
incoming HTTP request:
```php
$request = ServerRequestCreator::createFromGlobals();
$context = TraceContextPropagator::getInstance()->extract($request->getHeaders());
$root = $tracer->spanBuilder('HTTP ' . $request->getMethod())
->setStartTimestamp((int) ($request->getServerParams()['REQUEST_TIME_FLOAT'] * 1e9))
->setParent($context)
->setSpanKind(SpanKind::KIND_SERVER)
->startSpan();
$scope = $root->activate();
try {
/* do stuff */
} finally {
$root->end();
$scope->detach();
}
```
#### Sampler
It is not always feasible to trace and export every user request in an

View File

@ -0,0 +1,96 @@
---
title: Propagation
description: Context propagation for the PHP API
weight: 7
---
Propagation is the mechanism that moves data between services and processes.
Although not limited to tracing, it is what allows traces to build causal
information about a system across services that are arbitrarily distributed
across process and network boundaries.
OpenTelemetry provides a text-based approach to propagate context to remote
services using the [W3C Trace Context](https://www.w3.org/TR/trace-context/)
HTTP headers.
## Context propagation with frameworks and libraries
Auto-instrumentation exists for some popular PHP frameworks (eg Symfony,
Laravel, Slim) and HTTP libraries propagate context for incoming and outgoing
HTTP requests.
**We highly recommend that you use auto-instrumentation or instrumentation
libraries to propagate context**. Although it is possible to propagate context
manually, the PHP auto-instrumentation and instrumentation libraries are
well-tested and easier to use.
### Incoming
Auto-instrumentation for frameworks which implement the
[PSR-15](https://www.php-fig.org/psr/psr-15/) `RequestHandlerInterface` will
automatically extract W3C tracecontext headers, create a root span, and set a
remote parent for the root span.
```shell
composer require open-telemetry/opentelemetry-auto-psr15
```
### Outgoing
[PSR-18](https://www.php-fig.org/psr/psr-18/) auto-instrumentation will
automatically apply W3C tracecontext headers to outgoing HTTP requests for any
library which implements the PSR-18 interface.
```shell
open-telemetry/opentelemetry-auto-psr18
```
## Manual W3C Trace Context Propagation
In some cases, it is not possible to propagate context with an instrumentation
library. There may not be an instrumentation library that matches a library
you're using to have services communicate with one another. Or you many have
requirements that instrumentation libraries cannot fulfill, even if they exist.
When you must propagate context manually, you can use the context api.
The following presents an example of an outgoing HTTP request:
```php
$request = new Request('GET', 'http://localhost:8080/resource');
$outgoing = $tracer->spanBuilder('/resource')->setSpanKind(SpanKind::CLIENT)->startSpan();
$outgoing->setAttribute(TraceAttributes::HTTP_METHOD, $request->getMethod());
$outgoing->setAttribute(TraceAttributes::HTTP_URL, (string) $request->getUri());
$carrier = [];
TraceContextPropagator::getInstance()->inject($carrier);
foreach ($carrier as $name => $value) {
$request = $request->withAddedHeader($name, $value);
}
try {
$response = $client->send($request);
} finally {
$outgoing->end();
}
```
Similarly, the text-based approach can be used to read the W3C Trace Context
from incoming requests. The following presents an example of processing an
incoming HTTP request:
```php
$request = ServerRequestCreator::createFromGlobals();
$context = TraceContextPropagator::getInstance()->extract($request->getHeaders());
$root = $tracer->spanBuilder('HTTP ' . $request->getMethod())
->setStartTimestamp((int) ($request->getServerParams()['REQUEST_TIME_FLOAT'] * 1e9))
->setParent($context)
->setSpanKind(SpanKind::KIND_SERVER)
->startSpan();
$scope = $root->activate();
try {
/* do stuff */
} finally {
$root->end();
$scope->detach();
}
```

View File

@ -0,0 +1,85 @@
---
title: Resources
weight: 6
---
A resource represents the entity producing telemetry as resource attributes. For
example, a process producing telemetry that is running in a container on
Kubernetes has a Pod name, a namespace, and possibly a deployment name. All
three of these attributes can be included in the resource.
In your observability backend, you can use resource information to better
investigate interesting behavior. For example, if your trace or metrics data
indicate latency in your system, you can narrow it down to a specific container,
pod, or Kubernetes deployment.
## Resource Detection
The PHP SDK detects resources from a variety of sources, and by default will use
all available resource detectors:
- environment (`OTEL_RESOURCE_ATTRIBUTES`, `OTEL_SERVICE_NAME`)
- host information
- host operating system
- current process
- runtime
## Disabling resource detection
By default, all SDK resource detectors are used, but you can use the environment
variable `OTEL_PHP_RESOURCE_DETECTORS` to enable only certain detectors, or
completely disable them:
- `env`
- `host`
- `os`
- `process`
- `process_runtime`
- `sdk`
- `sdk_provided`
- `all` - enable all resource detectors
- `none` - disable resource detection
For example, to enable only the `env`, `host` and `sdk` detectors:
```shell
env OTEL_PHP_RESOURCE_DETECTORS=env,host,sdk \
php example.php
```
## Adding resources with environment variables
If there is not an SDK detector for the resource you need, you can add arbitrary
resources via the `OTEL_RESOURCE_ATTRIBUTES` environment variable, which is
interpreted by the `env` detector. This variable takes a comma-separated list of
key=value pairs, for example:
```shell
env OTEL_RESOURCE_ATTRIBUTES="service.name=my_service,service.namespace=demo,service.version=1.0,deployment.environment=development" \
php example.php
```
## Adding resources in code
Custom resources can also be configured in your code. Here, the default
resources (detected as described above) are merged with custom resources. The
resources are then passed to the tracer provider, where they will be associated
with all generated spans.
```php
$resource = ResourceInfoFactory::merge(ResourceInfo::create(Attributes::create([
ResourceAttributes::SERVICE_NAMESPACE => 'foo',
ResourceAttributes::SERVICE_NAME => 'bar',
ResourceAttributes::SERVICE_INSTANCE_ID => 1,
ResourceAttributes::SERVICE_VERSION => '0.1',
ResourceAttributes::DEPLOYMENT_ENVIRONMENT => 'development',
])), ResourceInfoFactory::defaultResource());
$tracerProvider = new TracerProvider(
new SimpleSpanProcessor(
(new ConsoleSpanExporterFactory())->create()
),
null,
$resource
);
```

View File

@ -3739,6 +3739,14 @@
"StatusCode": 200,
"LastSeen": "2023-02-18T13:46:19.448057-05:00"
},
"https://www.php-fig.org/psr/psr-15/": {
"StatusCode": 206,
"LastSeen": "2023-02-28T03:33:34.741771102Z"
},
"https://www.php-fig.org/psr/psr-18/": {
"StatusCode": 206,
"LastSeen": "2023-02-28T03:33:35.061283512Z"
},
"https://www.python.org/dev/peps/pep-3333/": {
"StatusCode": 206,
"LastSeen": "2023-02-18T13:41:14.813514-05:00"