Skip to content

Commit

Permalink
Adding PHP documentation for exporters, resources, propagation (#2415)
Browse files Browse the repository at this point in the history
  • Loading branch information
brettmc authored Mar 1, 2023
1 parent f99b39a commit 100e517
Show file tree
Hide file tree
Showing 6 changed files with 322 additions and 52 deletions.
128 changes: 128 additions & 0 deletions content/en/docs/instrumentation/php/exporters.md
Original file line number Diff line number Diff line change
@@ -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');
```
2 changes: 1 addition & 1 deletion content/en/docs/instrumentation/php/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
55 changes: 4 additions & 51 deletions content/en/docs/instrumentation/php/manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -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].
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down
96 changes: 96 additions & 0 deletions content/en/docs/instrumentation/php/propagation.md
Original file line number Diff line number Diff line change
@@ -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();
}
```
Loading

0 comments on commit 100e517

Please sign in to comment.