PHPackages                             openzipkin/zipkin - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Logging &amp; Monitoring](/categories/logging)
4. /
5. openzipkin/zipkin

ActiveLibrary[Logging &amp; Monitoring](/categories/logging)

openzipkin/zipkin
=================

A Zipkin instrumentation for PHP

3.2.1(1y ago)2774.3M—6.2%60[11 issues](https://github.com/openzipkin/zipkin-php/issues)[3 PRs](https://github.com/openzipkin/zipkin-php/pulls)20Apache-2.0PHPPHP ^7.4 || ^8.0CI passing

Since Nov 15Pushed 1y ago8 watchersCompare

[ Source](https://github.com/openzipkin/zipkin-php)[ Packagist](https://packagist.org/packages/openzipkin/zipkin)[ Docs](https://github.com/openzipkin/zipkin-php)[ RSS](/packages/openzipkin-zipkin/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (13)Versions (51)Used By (20)

Zipkin PHP
==========

[](#zipkin-php)

[![CI](https://github.com/openzipkin/zipkin-php/workflows/CI/badge.svg)](https://github.com/openzipkin/zipkin-php/workflows/CI/badge.svg)[![Latest Stable Version](https://camo.githubusercontent.com/6e302658a88bc944e6deabfc791e24bc6b4618c8c1b0429dd2f21b31979dcda0/68747470733a2f2f706f7365722e707567782e6f72672f6f70656e7a69706b696e2f7a69706b696e2f762f737461626c65)](https://packagist.org/packages/openzipkin/zipkin)[![Minimum PHP Version](https://camo.githubusercontent.com/0e9ac047546796cfdbe1423d1f4d91c8f37d2fbb11614a7900bb7686aaa5401f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253345253344253230372e342d3838393242462e737667)](https://php.net/)[![Total Downloads](https://camo.githubusercontent.com/48e0b0620fc190a5ce7fe1349ce4d68e09d705e136cd31aa6d499c16b8ea5435/68747470733a2f2f706f7365722e707567782e6f72672f6f70656e7a69706b696e2f7a69706b696e2f646f776e6c6f616473)](https://packagist.org/packages/openzipkin/zipkin)[![License](https://camo.githubusercontent.com/99358fccbcd79d2f905cdee3c5905034ce1e826eaa70a53dd7baf6c7406255c2/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6f70656e7a69706b696e2f7a69706b696e2e737667)](https://github.com/openzipkin/zipkin-php/blob/master/LICENSE)

Zipkin PHP is the official PHP Tracer implementation for Zipkin, supported by the OpenZipkin community.

Installation
------------

[](#installation)

```
composer require openzipkin/zipkin
```

Setup
-----

[](#setup)

```
use Zipkin\Annotation;
use Zipkin\Endpoint;
use Zipkin\Samplers\BinarySampler;
use Zipkin\TracingBuilder;
use Zipkin\Reporters\Http;

// First we create the endpoint that describes our service
$endpoint = Endpoint::create('my_service');

$reporter = new Http(['endpoint_url' => 'http://myzipkin:9411/api/v2/spans']);
$sampler = BinarySampler::createAsAlwaysSample();
$tracing = TracingBuilder::create()
    ->havingLocalEndpoint($endpoint)
    ->havingSampler($sampler)
    ->havingReporter($reporter)
    ->build();

$tracer = $tracing->getTracer();

...

$tracer->flush();
```

**Obs.** for a more complete frontend/backend example, check [this repository](https://github.com/openzipkin/zipkin-php-example).

Tracing
-------

[](#tracing)

The tracer creates and joins spans that model the latency of potentially distributed work. It can employ sampling to reduce overhead in process or to reduce the amount of data sent to Zipkin.

Spans returned by a tracer report data to Zipkin when finished, or do nothing if unsampled. After starting a span, you can annotate events of interest or add tags containing details or lookup keys.

Spans have a context which includes trace identifiers that place it at the correct spot in the tree representing the distributed operation.

### Local Tracing

[](#local-tracing)

When tracing local code, just run it inside a span

```
$span = $tracer->newTrace();
$span->setName('encode');
$span->start();

try {
  doSomethingExpensive();
} finally {
  $span->finish();
}
```

In the above example, the span is the root of the trace. In many cases, you will be a part of an existing trace. When this is the case, call `newChild` instead of `newTrace`

```
$span = $tracer->newChild($root->getContext());
$span->setName('encode');
$span->start();
try {
  doSomethingExpensive();
} finally {
  $span->finish();
}
```

### Customizing spans

[](#customizing-spans)

Once you have a span, you can add tags to it, which can be used as lookup keys or details. For example, you might add a tag with your runtime version.

```
$span->tag('http.status_code', '200');
```

### RPC tracing

[](#rpc-tracing)

RPC tracing is often done automatically by interceptors. Under the scenes, they add tags and events that relate to their role in an RPC operation.

Here's an example of a client span:

```
// before you send a request, add metadata that describes the operation
$span = $tracer->newTrace();
$span->setName('get');
$span->setKind(Kind\CLIENT);
$span->tag('http.status_code', '200');
$span->tag(Tags\HTTP_PATH, '/api');
$span->setRemoteEndpoint(Endpoint::create('backend', 127 start();

// if you have callbacks for when data is on the wire, note those events
$span->annotate(Annotation\WIRE_SEND);
$span->annotate(Annotation\WIRE_RECV);

// when the response is complete, finish the span
$span->finish();
```

Sampling
--------

[](#sampling)

Sampling may be employed to reduce the data collected and reported out of process. When a span isn't sampled, it adds no overhead (noop).

Sampling is an up-front decision, meaning that the decision to report data is made at the first operation in a trace, and that decision is propagated downstream.

By default, there's a global sampler that applies a single rate to all traced operations. `Sampler` is how you indicate this, and it defaults to trace every request.

### Custom sampling

[](#custom-sampling)

You may want to apply different policies depending on what the operation is. For example, you might not want to trace requests to static resources such as images, or you might want to trace all requests to a new api.

Most users will use a framework interceptor which automates this sort of policy. Here's how they might work internally.

```
private function newTrace(Request $request) {
  $flags = SamplingFlags::createAsEmpty();
  if (strpos($request->getUri(), '/experimental') === 0) {
    $flags = DefaultSamplingFlags::createAsSampled();
  } else if (strpos($request->getUri(), '/static') === 0) {
    $flags = DefaultSamplingFlags::createAsSampled();
  }
  return $tracer->newTrace($flags);
}
```

Propagation
-----------

[](#propagation)

Propagation is needed to ensure activity originating from the same root are collected together in the same trace. The most common propagation approach is to copy a trace context from a client sending an RPC request to a server receiving it.

For example, when an downstream Http call is made, its trace context is sent along with it, encoded as request headers:

```
   Client Span                                                Server Span
┌──────────────────┐                                       ┌──────────────────┐
│                  │                                       │                  │
│   TraceContext   │           Http Request Headers        │   TraceContext   │
│ ┌──────────────┐ │          ┌───────────────────┐        │ ┌──────────────┐ │
│ │ TraceId      │ │          │ X-B3-TraceId      │        │ │ TraceId      │ │
│ │              │ │          │                   │        │ │              │ │
│ │ ParentSpanId │ │ Extract  │ X-B3-ParentSpanId │ Inject │ │ ParentSpanId │ │
│ │              ├─┼─────────>│                   ├────────┼>│              │ │
│ │ SpanId       │ │          │ X-B3-SpanId       │        │ │ SpanId       │ │
│ │              │ │          │                   │        │ │              │ │
│ │ Sampled      │ │          │ X-B3-Sampled      │        │ │ Sampled      │ │
│ └──────────────┘ │          └───────────────────┘        │ └──────────────┘ │
│                  │                                       │                  │
└──────────────────┘                                       └──────────────────┘

```

The names above are from [B3 Propagation](https://github.com/openzipkin/b3-propagation), which is built-in to Brave and has implementations in many languages and frameworks.

Most users will use a framework interceptor which automates propagation. Here's how they might work internally.

Here's what client-side propagation might look like

```
// configure a function that injects a trace context into a request
$injector = $tracing->getPropagation()->getInjector(new RequestHeaders);

// before a request is sent, add the current span's context to it
$injector($span->getContext(), $request);
```

Here's what server-side propagation might look like

```
// configure a function that extracts the trace context from a request
$extractor = $tracing->getPropagation()->getExtractor(new RequestHeaders);
$extracted = $extractor($request);

$span = $tracer->newChild($extracted);
$span->setKind(Kind\SERVER);
```

If you aren't using a framework or don't have access to the Request object, you can extract the context from the $\_SERVER variable

```
$extractor = $tracing->getPropagation()->getExtractor(new ServerHeaders);
$extracted = $extractor($_SERVER);
```

### Extracting a propagated context

[](#extracting-a-propagated-context)

The `Extractor` reads trace identifiers and sampling status from an incoming request or message. The carrier is usually a request object or headers.

`SamplingFlags|TraceContext` is usually only used with `$tracer->newChild(extracted)`, unless you are sharing span IDs between a client and a server.

### Implementing Propagation

[](#implementing-propagation)

`Extractor` will output a `SamplingFlags|TraceContext` with one of the following:

- `TraceContext` if trace and span IDs were present.
- `SamplingFlags` if no identifiers were present

Current Span
------------

[](#current-span)

Zipkin supports a "current span" concept which represents the in-flight operation. `Tracer::currentSpan()` can be used to add custom tags to a span and `Tracer::nextSpan()` can be used to create a child of whatever is in-flight.

A common use case for the current span is to instrument RPC clients. For example:

```
/**
  * This http clients composes an http client using PSR7
  */
class TraceClient implements ClientInterface
{
    public function request($method, $uri = '', array $options = [])
    {
        /* Gets the child Span of the current one */
        $span = $this->tracer->nextSpan();
        $span->setKind(Zipkin\Kind\CLIENT);
        $span->tag(Tags\HTTP_PATH, $uri);

        try {
            $response = $this->client->request($method, $uri, $options);
            $span->tag(Tags\HTTP_STATUS_CODE, (string) $response->getStatusCode());

            return $response;
        catch (Throwable $e) {
            $span->setError($e);
            throw $e;
        } finally {
            $span->finish();
        }
    }
}
```

### Setting a span in scope manually

[](#setting-a-span-in-scope-manually)

When writing new instrumentation, it is important to place a span you created in scope as the current span.

In edge cases, you may need to clear the current span temporarily. For example, launching a task that should not be associated with the current request. To do this, simply pass null to `openScope`.

Instrumentation
---------------

[](#instrumentation)

- [PSR18 HTTP Client](src/Zipkin/Instrumentation/Http/Client/Psr18)
- [PSR15 HTTP Server](src/Zipkin/Instrumentation/Http/Server/Psr15)

Tests
-----

[](#tests)

Tests can be run by

```
composer test
```

Whereas static checks can be run by:

```
composer static-check
```

Reference
---------

[](#reference)

- [Instrumenting a library](http://zipkin.io/pages/instrumenting.html)
- [openzipkin/zipkin-api](https://github.com/openzipkin/zipkin-api)

###  Health Score

61

—

FairBetter than 99% of packages

Maintenance47

Moderate activity, may be stable

Popularity63

Solid adoption and visibility

Community41

Growing community involvement

Maturity81

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 88.1% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~77 days

Recently: every ~316 days

Total

36

Last Release

390d ago

Major Versions

1.3.4 → v2.x-dev2019-11-16

v1.x-dev → 2.0.0-beta12020-07-29

2.0.2 → 3.0.0-rc.12021-10-25

PHP version history (4 changes)1.0.0-beta1PHP ^5.6||^7.0

1.3.0PHP ^5.6 || ^7.0

v2.x-devPHP ^7.1

3.0.0-rc.1PHP ^7.4 || ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/8b5352392ac3b571d5e5d144f6e992040e46726c0863552882cdd8d2577c2eb7?d=identicon)[jcchavezs](/maintainers/jcchavezs)

---

Top Contributors

[![jcchavezs](https://avatars.githubusercontent.com/u/3075074?v=4)](https://github.com/jcchavezs "jcchavezs (236 commits)")[![anensshiya-govinthas-ck](https://avatars.githubusercontent.com/u/28936995?v=4)](https://github.com/anensshiya-govinthas-ck "anensshiya-govinthas-ck (7 commits)")[![peter279k](https://avatars.githubusercontent.com/u/9021747?v=4)](https://github.com/peter279k "peter279k (3 commits)")[![drolando](https://avatars.githubusercontent.com/u/3317638?v=4)](https://github.com/drolando "drolando (3 commits)")[![xiian](https://avatars.githubusercontent.com/u/133872?v=4)](https://github.com/xiian "xiian (2 commits)")[![localheinz](https://avatars.githubusercontent.com/u/605483?v=4)](https://github.com/localheinz "localheinz (2 commits)")[![draco2003](https://avatars.githubusercontent.com/u/196891?v=4)](https://github.com/draco2003 "draco2003 (1 commits)")[![andrei-dascalu](https://avatars.githubusercontent.com/u/20300994?v=4)](https://github.com/andrei-dascalu "andrei-dascalu (1 commits)")[![dzvon](https://avatars.githubusercontent.com/u/3402811?v=4)](https://github.com/dzvon "dzvon (1 commits)")[![altitude](https://avatars.githubusercontent.com/u/1770991?v=4)](https://github.com/altitude "altitude (1 commits)")[![adiachenko](https://avatars.githubusercontent.com/u/10194667?v=4)](https://github.com/adiachenko "adiachenko (1 commits)")[![minbaby](https://avatars.githubusercontent.com/u/3191858?v=4)](https://github.com/minbaby "minbaby (1 commits)")[![nirnanaaa](https://avatars.githubusercontent.com/u/1064750?v=4)](https://github.com/nirnanaaa "nirnanaaa (1 commits)")[![pauci](https://avatars.githubusercontent.com/u/2421146?v=4)](https://github.com/pauci "pauci (1 commits)")[![Aideen-Nasirishargh-CK](https://avatars.githubusercontent.com/u/35582732?v=4)](https://github.com/Aideen-Nasirishargh-CK "Aideen-Nasirishargh-CK (1 commits)")[![qiqizjl](https://avatars.githubusercontent.com/u/7540584?v=4)](https://github.com/qiqizjl "qiqizjl (1 commits)")[![telemmaite](https://avatars.githubusercontent.com/u/4275711?v=4)](https://github.com/telemmaite "telemmaite (1 commits)")[![temuulens](https://avatars.githubusercontent.com/u/7126736?v=4)](https://github.com/temuulens "temuulens (1 commits)")[![Tinywan](https://avatars.githubusercontent.com/u/14959876?v=4)](https://github.com/Tinywan "Tinywan (1 commits)")[![wesolydexter](https://avatars.githubusercontent.com/u/15888895?v=4)](https://github.com/wesolydexter "wesolydexter (1 commits)")

---

Tags

distributed-tracinghacktoberfestinstrumentationobservabilityopenzipkinphpzipkintracingzipkinopenzipkindistributed-tracing

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/openzipkin-zipkin/health.svg)

```
[![Health](https://phpackages.com/badges/openzipkin-zipkin/health.svg)](https://phpackages.com/packages/openzipkin-zipkin)
```

###  Alternatives

[sentry/sentry

PHP SDK for Sentry (http://sentry.io)

1.9k227.1M273](/packages/sentry-sentry)[open-telemetry/sdk

SDK for OpenTelemetry PHP.

2322.9M248](/packages/open-telemetry-sdk)[open-telemetry/api

API for OpenTelemetry PHP.

1933.0M214](/packages/open-telemetry-api)[vinelab/tracing-laravel

Distributed tracing for Laravel made easy

80118.7k1](/packages/vinelab-tracing-laravel)[open-telemetry/opentelemetry-auto-wordpress

OpenTelemetry auto-instrumentation for Wordpress

17166.0k](/packages/open-telemetry-opentelemetry-auto-wordpress)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
