philkra/elastic-apm-php-agent
PHP agent for Elastic APM that instruments your application to capture transactions, spans, errors, and performance metrics. Sends telemetry to Elastic APM Server for tracing and monitoring, with support for web and CLI workloads and configurable sampling.
composer require philkra/elastic-apm-php-agent
.env (Laravel):
APM_SERVER_URL=http://localhost:8200
APM_SERVICE_NAME=my-laravel-app
APM_SERVICE_VERSION=1.0.0
APM_ENVIRONMENT=production
bootstrap/app.php (Laravel 9+):
$app->register(\PhilKra\ElasticApm\ElasticApmServiceProvider::class);
Or manually in AppServiceProvider@boot():
\PhilKra\ElasticApm\ElasticApm::initialize();
// app/Http/Middleware/SetApmUserContext.php
public function handle($request, Closure $next)
{
\PhilKra\ElasticApm\ElasticApm::setUserContext([
'id' => auth()->id(),
'email' => auth()->email(),
]);
return $next($request);
}
app/Http/Kernel.php before other middleware.use PhilKra\ElasticApm\ElasticApm;
// In your job's handle() method
$span = ElasticApm::startSpan('process_order');
try {
// Business logic
} finally {
$span->end();
}
Database Queries:
$span = ElasticApm::startSpan('fetch_user_data');
DB::table('users')->where('id', 1)->get();
$span->end();
ElasticApm::startSpan() around Eloquent/Query Builder calls.HTTP Clients (Guzzle, HTTP Client):
$span = ElasticApm::startSpan('call_external_api');
Http::withOptions(['debug' => false])->get('https://api.example.com');
$span->end();
Custom Transactions:
ElasticApm::startTransaction('custom_background_job');
// Job logic
ElasticApm::endTransaction();
// Set global metadata (e.g., in AppServiceProvider)
ElasticApm::setMetadata([
'labels' => ['team' => 'backend'],
'environment' => config('app.env'),
]);
// Per-request metadata
ElasticApm::setTransactionName('api.v1.users.index');
Double Initialization:
RuntimeException: APM agent already initialized.ElasticApm::initialize() is called once (e.g., in AppServiceProvider@register()).Missing Transactions:
ElasticApm::startTransaction('cli.command');
// Command logic
ElasticApm::endTransaction();
Span Nesting:
ElasticApm::startSpan() with a parent span (if applicable):
$parent = ElasticApm::getCurrentSpan();
$child = ElasticApm::startSpan('child_task', $parent);
Performance Overhead:
APM_ENVIRONMENT=development
APM_LOG_LEVEL=debug
if (!ElasticApm::isInitialized()) {
// Handle error
}
Custom Error Handlers:
ElasticApm::setErrorHandler(function (Throwable $e) {
ElasticApm::captureException($e, [
'custom_context' => ['user_id' => 123],
]);
});
Span Context Propagation: For distributed tracing, attach context to HTTP requests:
$span = ElasticApm::startSpan('rpc_call');
Http::withHeaders([
'X-Elastic-Apm-Traceparent' => ElasticApm::getTraceparent(),
])->get('...');
Async Processing:
ElasticApm::flush() to force-send data before app shutdown:
register_shutdown_function(function() {
ElasticApm::flush();
});
http:// or https:// (no trailing slashes).production, staging).How can I help you explore Laravel packages today?