laravel-ai-observability maintained by tracefast
Laravel AI Observability
OpenInference traces for the Laravel AI SDK.
This package listens to laravel/ai events and exports agent runs, model calls, tool calls, inputs, outputs, usage, and errors to logs, OTLP receivers, or a local database.
Requirements
- PHP 8.4+
- Laravel 12 or 13
laravel/ai^0.7
Installation
composer require tracefast/laravel-ai-observability
That is enough to start capturing traces. Observability is enabled by default and writes to your Laravel log.
Publish the config only when you want to customize exporters:
php artisan vendor:publish --tag=ai-observability-config
Quick Start
The default exporter is log:
# Optional. This is the default.
AI_OBSERVABILITY_EXPORTER=log
V1 captures full LLM input and output by default.
Exporters
Set AI_OBSERVABILITY_EXPORTER to one exporter name:
AI_OBSERVABILITY_EXPORTER=phoenix
Or send traces to multiple receivers:
AI_OBSERVABILITY_EXPORTER=phoenix,langfuse
Phoenix
AI_OBSERVABILITY_EXPORTER=phoenix
PHOENIX_COLLECTOR_ENDPOINT=http://localhost:6006/v1/traces
Langfuse
AI_OBSERVABILITY_EXPORTER=langfuse
LANGFUSE_OTEL_ENDPOINT=https://cloud.langfuse.com/api/public/otel/v1/traces
LANGFUSE_OTEL_AUTHORIZATION="Basic <base64-public-key-colon-secret-key>"
Braintrust
AI_OBSERVABILITY_EXPORTER=braintrust
BRAINTRUST_API_KEY=<braintrust-api-key>
BRAINTRUST_PARENT=project_name:<project-name>
The Braintrust endpoint defaults to https://api.braintrust.dev/otel/v1/traces.
Log
AI_OBSERVABILITY_EXPORTER=log
Advanced log options:
AI_OBSERVABILITY_LOG_CHANNEL=stack
AI_OBSERVABILITY_LOG_LEVEL=debug
Content Capture
By default, this package captures full input and output. That may include prompts, system messages, tool arguments, tool results, uploaded content, PII, secrets, and sensitive business data.
Disable content capture when needed:
AI_OBSERVABILITY_CAPTURE_CONTENT=off
Conversation Correlation
Use AiObservability::withSession() when your app has its own conversation id:
use Tracefast\LaravelAiObservability\Facades\AiObservability;
$response = AiObservability::withSession(
sessionId: $conversation->uuid,
callback: fn () => $agent->prompt($message),
userId: $user->id,
);
Each turn remains its own trace, and every turn carries the same session.id.
Database Exporter
The database exporter is opt-in.
php artisan vendor:publish --tag=ai-observability-migrations
php artisan migrate
AI_OBSERVABILITY_EXPORTER=database
Use a specific connection when needed:
AI_OBSERVABILITY_DB_CONNECTION=mysql
The migration creates ai_observability_traces and ai_observability_spans.
Advanced Options
AI_OBSERVABILITY_ENABLED=true
AI_OBSERVABILITY_EXPORT_MODE=defer
AI_OBSERVABILITY_SAMPLE_RATE=1.0
AI_OBSERVABILITY_EXPORT_TIMEOUT=2.0
AI_OBSERVABILITY_EXPORT_CONNECT_TIMEOUT=0.5
AI_OBSERVABILITY_MAX_PAYLOAD_BYTES=1048576
AI_OBSERVABILITY_EXPORT_MODE accepts defer, sync, queue, or background. The default is defer, which exports after the response when Laravel can defer work. Deferred exports also run at Laravel command and queue job boundaries through Laravel's deferred callback lifecycle.
Use queue when you want exports handled by a normal queue worker:
AI_OBSERVABILITY_EXPORT_MODE=queue
AI_OBSERVABILITY_EXPORT_CONNECTION=redis
AI_OBSERVABILITY_EXPORT_QUEUE=observability
Use background when your Laravel app has a background queue connection and you want to release the current PHP worker quickly:
AI_OBSERVABILITY_EXPORT_MODE=background
Production Transport Hardening
AI_OBSERVABILITY_EXPORT_TIMEOUT=2.0
AI_OBSERVABILITY_EXPORT_CONNECT_TIMEOUT=0.5
AI_OBSERVABILITY_MAX_PAYLOAD_BYTES=1048576
AI_OBSERVABILITY_EXPORT_RETRY_ATTEMPTS=1
AI_OBSERVABILITY_EXPORT_RETRY_DELAY_MS=100
AI_OBSERVABILITY_OTLP_COMPRESSION=gzip
AI_OBSERVABILITY_CIRCUIT_BREAKER=true
AI_OBSERVABILITY_CIRCUIT_BREAKER_FAILURE_THRESHOLD=3
AI_OBSERVABILITY_CIRCUIT_BREAKER_OPEN_SECONDS=30
Payloads over AI_OBSERVABILITY_MAX_PAYLOAD_BYTES are dropped and reported locally instead of being sent. OTLP retries are bounded and only intended for transient collector failures such as network errors, 408, 425, 429, and 5xx responses. The circuit breaker skips sends for a short window after repeated failures so a dead collector does not keep taxing request workers.
Generic OTLP
AI_OBSERVABILITY_EXPORTER=otlp
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://collector.example.com/v1/traces
OTEL_EXPORTER_OTLP_TRACES_HEADERS="Authorization=Bearer <token>"
OTLP payloads include OpenInference and versioned Tracefast metadata such as openinference.schema.version, tracefast.ai.sdk.version, tracefast.ai.package.version, and gen_ai.* attributes where the Laravel AI SDK exposes the source data.
Custom Exporters
Custom exporters implement Tracefast\LaravelAiObservability\Contracts\Exporter:
use Tracefast\LaravelAiObservability\Contracts\Exporter;
use Tracefast\LaravelAiObservability\Data\Trace;
final class WebhookExporter implements Exporter
{
public function export(Trace $trace): void
{
// Send $trace->toArray() to your destination.
}
}
Register the driver from a service provider:
use App\Observability\WebhookExporter;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\ServiceProvider;
use Tracefast\LaravelAiObservability\AiObservability;
use Tracefast\LaravelAiObservability\Contracts\Exporter;
final class AppServiceProvider extends ServiceProvider
{
public function boot(AiObservability $observability): void
{
$observability->extend(
'webhook',
fn (Application $app, array $config, string $name): Exporter => new WebhookExporter(),
);
}
}
Then configure it:
'exporters' => [
'webhook' => [
'driver' => 'webhook',
],
],
Testing
composer test
License
Laravel AI Observability is open-sourced software licensed under the MIT license.