jcleng / hyperf-opentelemetry-zincsearch
Hyperf tracer driver for OpenTelemetry with ZincSearch exporter
Package info
github.com/jcleng/hyperf-opentelemetry-zincsearch
pkg:composer/jcleng/hyperf-opentelemetry-zincsearch
Requires
- php: >=8.1
- hyperf/contract: ~3.1.0
- hyperf/tracer: ~3.1.0
- jcleng/opentelemetry-exporter-zincsearch: ^1.0
- open-telemetry/opentracing-shim: ^0.0.3
- open-telemetry/sdk: ^1.9
- open-telemetry/sem-conv: ^1.0
- opentracing/opentracing: ^1.0
- psr/log: ^1.1 || ^2.0 || ^3.0
This package is not auto-updated.
Last update: 2026-07-29 06:47:11 UTC
README
Hyperf tracer driver for OpenTelemetry with ZincSearch exporter.
This package provides a Hyperf tracer driver that uses the OpenTelemetry SDK with a ZincSearch exporter, bridged to Hyperf's OpenTracing abstraction via the opentracing-shim.
Architecture
Hyperf Tracer (OpenTracing)
│
▼
OpenTelemetry Shim (OpenTracing → OpenTelemetry)
│
▼
OpenTelemetry SDK (TracerProvider + CoroutineSafeSpanProcessor)
│
▼
ZincSearch Exporter (SpanConverter → NDJSON)
│
▼
ZincSearch Transport (Guzzle HTTP → /api/_bulk)
│
▼
ZincSearch Instance
Installation
composer require jcleng/hyperf-opentelemetry-zincsearch
The dependency jcleng/opentelemetry-exporter-zincsearch will be resolved
automatically from Packagist.
Configuration
Publish the config file (or create config/autoload/opentracing.php manually):
php bin/hyperf.php vendor:publish jcleng/hyperf-opentelemetry-zincsearch
Set the default driver and ZincSearch connection in .env:
TRACER_DRIVER=zincsearch APP_NAME=my-service ZINCSEARCH_URL=http://127.0.0.1:4080 ZINCSEARCH_PASSWORD=BASE64_ENCODED_CREDENTIALS ZINCSEARCH_INDEX=exporter_zincsearch ZINCSEARCH_TIMEOUT=5.0
Config Reference
The opentracing.tracer.zincsearch config block:
| Key | Type | Required | Default | Description |
|---|---|---|---|---|
driver |
string | Yes | - | Must be ZincSearchTracerFactory::class |
app.name |
string | No | skeleton |
Service name used in trace resource attributes |
zinc_url |
string | Yes | http://127.0.0.1:4080 |
ZincSearch base URL |
zinc_password |
string | Yes | - | Base64-encoded Basic auth credential |
index_name |
string | No | exporter_zincsearch |
Target ZincSearch index name |
timeout |
float | No | 5.0 |
HTTP request timeout in seconds |
Usage
Once configured, Hyperf's built-in tracer aspects (Guzzle, Redis, DB, RPC, etc.) will automatically create spans and export them to ZincSearch.
Enable specific tracers in .env:
TRACER_ENABLE_GUZZLE=true TRACER_ENABLE_DB=true TRACER_ENABLE_REDIS=true TRACER_ENABLE_METHOD=true
Swoole Coroutine Compatibility
This package uses a custom CoroutineSafeSpanProcessor instead of the
OpenTelemetry SDK's SimpleSpanProcessor. The official SimpleSpanProcessor
activates/detaches an OpenTelemetry context scope around every export call.
In a Swoole coroutine environment, Fiber::getCurrent() returns null inside
coroutines, so all coroutines share the same context scope stack. When the
export HTTP request yields the coroutine, another coroutine's scope activation
corrupts the shared stack, causing Scope: unexpected call to Scope::detach()
errors.
CoroutineSafeSpanProcessor eliminates this by not activating any context
scope during export — the ZincSearch exporter only makes an HTTP POST and does
not depend on the OpenTelemetry context.
If you use other OpenTelemetry components that also activate scopes, you can additionally suppress debug scope warnings via environment variable:
OTEL_PHP_DEBUG_SCOPES_DISABLED=1
Trace Export Recursion Prevention
When TRACER_ENABLE_GUZZLE=true, Hyperf's HttpClientAspect intercepts all
GuzzleHttp\Client requests via AOP and creates trace spans. Without protection,
the Transport's own Guzzle request to ZincSearch would be intercepted, creating
a new span that triggers another export, forming an infinite recursion:
span finish → export → Guzzle POST → AOP intercept → new span → span finish → ...
This package prevents the loop by passing 'no_aspect' => true in the Guzzle
request options via the guzzle_options config key. HttpClientAspect
checks this option and skips tracing when set. In non-Hyperf environments,
Guzzle silently ignores unknown options, so the exporter package remains
framework-agnostic.
You can customize guzzle_options in config/autoload/opentracing.php:
'zincsearch' => [ // ... 'guzzle_options' => [ 'no_aspect' => true, // add any other Guzzle request options here ], ],
License
Apache-2.0