Skip to content

APM for Laravel

falak/apm-laravel is Falak’s Nightwatch-style instrumentation for Laravel 11, 12 and 13 (PHP 8.2+). It records what your app does and sends it to the local agent as OTLP/HTTP JSON, after the response is sent. Traces go to Tempo; exceptions and slow operations become Insights issues.

  1. Require the package:

    Terminal window
    composer require falak/apm-laravel
  2. Optionally publish the configuration:

    Terminal window
    php artisan vendor:publish --tag=falak-apm-config
  3. Commit and deploy. On a Falak server nothing else is needed: the service provider is auto-discovered and sends to unix:/run/falak/otlp.sock, falling back to http://127.0.0.1:4318.

Event type Captured from Key attributes
request Global middleware method, route, status, path, user id, route name/action; 5xx → error. Timeline spans bootstrap → middleware → controller → response
query QueryExecuted SQL with placeholders only (bindings are never captured, quoted literals stripped), connection, repeat count for N+1 detection
job Queue events queue, job class, attempt, status (processed, released, failed). Each async job is its own trace, linked to the dispatching request
outgoing_request Laravel Http client method, URL (query redacted), status, host; sends traceparent
mail MessageSending / MessageSent mailable class, recipient count, mailer
notification Notification events class, channel, status
cache Cache events operation (hit, miss, write, forget), key, store
command Artisan commands name, exit code (non-zero → error)
scheduled_task Scheduler events name, cron expression, status
exceptions reportable() + shutdown handler type, message, stack trace, handled/unhandled, the user
logs Laravel’s logger level, message, redacted context, trace and span ids
  • The hot path only appends small structs; redaction, N+1 analysis and JSON encoding happen at flush time.
  • Flushes happen after the response is sent (terminating), after each queue job, after each command and scheduled task, on Octane’s RequestTerminated, and in a shutdown safety net.
  • Transport is HTTP/1.1 over a socket with a 250 ms budget. If the agent is down, the payload is dropped silently; the package never throws into your app.
  • No OpenTelemetry SDK, ext-grpc or ext-protobuf needed. Octane state is reset per request, task and tick.

config/falak-apm.php:

Key Env Default
enabled FALAK_APM_ENABLED true
service_name FALAK_SERVICE_NAME / OTEL_SERVICE_NAME slug of app.name
socket FALAK_OTLP_SOCKET unix:/run/falak/otlp.sock
fallback_endpoint FALAK_OTLP_ENDPOINT http://127.0.0.1:4318 (null disables)
timeout FALAK_APM_TIMEOUT 0.25 s
sample_rates.{request,job,command,scheduled_task} FALAK_APM_*_SAMPLE_RATE 1.0 (whole trace kept or dropped)
sample_rates.{query,outgoing_request,cache,mail,notification} 1.0 (per span)
sample_rates.logs FALAK_APM_LOG_SAMPLE_RATE 1.0
events.* all true; a disabled type registers no listeners
timeline true
max_spans_per_trace FALAK_APM_MAX_SPANS 1000
max_logs, log_level, logs_via FALAK_APM_LOG_LEVEL, FALAK_APM_LOGS_VIA 1000, debug, listener
redaction.keys password, token, secret, authorization, cookie, api_key
redaction.cache_keys [] (Str::is patterns)
redaction.query_literals true
ignore.paths / ignore.commands / ignore.jobs up, telescope*, horizon*… / queue:work, horizon, octane:*… / []

Resource attributes come from FALAK_ORG_ID, FALAK_SITE_ID, FALAK_SERVER_ID, FALAK_DEPLOYMENT_ID and FALAK_RELEASE_ID, which Falak injects into every release.

AppServiceProvider::boot()
app(\Falak\Apm\Recorder::class)->redactUsing(function (array $attributes, string $type) {
unset($attributes['client.address']);
return $attributes;
});

Set FALAK_APM_LOGS_VIA=handler and add the Monolog handler to the channels you want:

config/logging.php
'channels' => [
'falak' => ['driver' => 'monolog', 'handler' => Falak\Apm\Logging\OtlpHandler::class],
],
  • Observability → Traces: request and job traces with their timelines.
  • Observability → Issues: grouped exceptions and threshold breaches. See Insights.
  • The service panel’s Observability tab: this site’s issues, slow routes, jobs and queries.
  • Grafana: the “Laravel site” and “Queues” dashboards.

Observability → Traces: a list of request traces with route, status and duration.