auxmoney/jaeger-php
OpenTracing-compatible PHP client for Jaeger distributed tracing (fork of jukylin/jaeger-php). Create a Config to init a Tracer, extract SpanContext from headers/server vars, start spans, add tags/logs/baggage, then flush to send traces.
Installation
composer require auxmoney/jaeger-php
Ensure your project uses OpenTracing PHP (opentracing/opentracing) as a dependency.
Basic Initialization
use Jaeger\Reporter\RemoteReporter;
use Jaeger\Sampler\ConstSampler;
use Jaeger\Tracer;
use Jaeger\Sender\UdpSender;
use OpenTracing\Tracer as OpenTracingTracer;
$reporter = new RemoteReporter(
new UdpSender('jaeger-agent-host', 6831),
'my-service'
);
$sampler = new ConstSampler(true); // Sample all traces (for dev)
$tracer = new Tracer(
'my-service',
$reporter,
$sampler
);
// Register as OpenTracing Tracer
OpenTracingTracer::register($tracer);
First Use Case: Instrumenting a Request
use OpenTracing\Span;
use OpenTracing\Tracer;
$tracer = Tracer::get();
$span = $tracer->buildSpan('http-request')->start();
try {
// Your logic here (e.g., HTTP call, DB query)
$span->setTag('http.method', 'GET');
$span->setTag('http.url', '/api/users');
} finally {
$span->finish();
}
vendor/auxmoney/jaeger-php/src/ – Core classes (e.g., Tracer.php, Reporter.php).vendor/opentracing/opentracing/src/ – OpenTracing API reference.AppServiceProvider) or Laravel’s bootstrap/app.php to ensure it’s available globally.// app/Providers/AppServiceProvider.php
public function boot()
{
$this->initializeJaeger();
}
protected function initializeJaeger()
{
$reporter = new RemoteRepporter(
new UdpSender(config('jaeger.agent_host'), config('jaeger.agent_port')),
config('app.name')
);
$tracer = new Tracer(
config('app.name'),
$reporter,
new ConstSampler(config('jaeger.sampling_rate'))
);
OpenTracingTracer::register($tracer);
}
// app/Http/Middleware/TraceRequests.php
public function handle($request, Closure $next)
{
$tracer = Tracer::get();
$span = $tracer->buildSpan('http.request')
->withTag('http.method', $request->method())
->withTag('http.url', $request->fullUrl())
->start();
try {
$response = $next($request);
$span->setTag('http.status_code', $response->getStatusCode());
return $response;
} finally {
$span->finish();
}
}
app/Http/Kernel.php:
protected $middleware = [
\App\Http\Middleware\TraceRequests::class,
];
use OpenTracing\Scope;
public function getUser($id)
{
$tracer = Tracer::get();
$span = $tracer->buildSpan('query.users')->start();
try {
$scope = $tracer->activateSpan($span);
$user = User::find($id);
$span->setTag('db.query', 'SELECT * FROM users WHERE id = ?');
return $user;
} finally {
$scope->detach();
$span->finish();
}
}
uber-trace-id) to propagate traces across services.// Extract context from incoming request
$tracer = Tracer::get();
$extractor = new HttpHeaderExtractor();
$scopeManager = new ScopeManager();
$tracer->inject(
$extractor->extract($request->header()),
'http_headers',
$request->headers
);
// Inject into outgoing requests
$tracer->inject($span->context(), 'http_headers', $response->headers);
ConstSampler with probabilistic sampling (e.g., ProbabilisticSampler) for production.$sampler = new ProbabilisticSampler(0.1); // Sample 10% of traces
uber-trace-id.$logger = Log::getMonolog();
$logger->pushHandler(new \Monolog\Handler\StreamHandler(
storage_path('logs/jaeger.log')
));
$logger->pushProcessor(new \Monolog\Processor\UidProcessor());
$logger->pushProcessor(function ($record) {
$record['extra']['trace_id'] = Tracer::get()->activeSpan()?->context()->toTraceId();
return $record;
});
jaeger-agent) is running and accessible. Default UDP port is 6831.
docker run -d -p 6831:6831/udp -p 6832:6832/udp -p 16686:16686 jaegertracing/all-in-one
0.01) to avoid overwhelming the agent.$span->finish() in a finally block to avoid memory leaks.
trait AutoFinishSpan
{
protected function withSpan(string $name, Closure $callback)
{
$tracer = Tracer::get();
$span = $tracer->buildSpan($name)->start();
try {
return $callback($span);
} finally {
$span->finish();
}
}
}
trace_id and span_id for debugging:
$span->context()->toTraceId(); // e.g., "a1b2c3d4..."
operation_name or tags (e.g., http.url).telnet jaeger-agent-host 6831).6831 must be open).RemoteReporter in a try-catch to log failures).Jaeger\Reporter\ReporterInterface for custom storage (e.g., database).Jaeger\SpanProcessor to add custom logic before sending spans.span->setBaggageItem() to pass structured data across services:
$span->setBaggageItem('user.id', $user->id);
queue.name, cache.hit).BatchReporter to reduce network calls:
$reporter = new BatchReporter(
new RemoteReporter($sender, 'my-service'),
100, // Max queue
How can I help you explore Laravel packages today?