Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Opentelemetry Laravel Package

keepsuit/laravel-opentelemetry

OpenTelemetry integration for Laravel: automatically instrument HTTP requests, database queries, queues, Redis, and more, then export traces and metrics via OTLP to your observability backend. Simple configuration and Laravel-native APIs.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal steps

  1. Install into a non-critical service first:
    composer require keepsuit/laravel-opentelemetry
    php artisan vendor:publish --tag=opentelemetry-config
    
  2. Configure the exporter with OTEL_* environment variables. Start with a local or staging OTLP endpoint — an OpenTelemetry Collector, Jaeger, or Grafana Tempo — not a production backend.
  3. Set at minimum:
    • OTEL_SERVICE_NAME (use a stable, low-cardinality name such as checkout-api)
    • OTEL_EXPORTER_OTLP_ENDPOINT
    • deployment/environment resource attributes (deployment.environment, service version, region)
  4. Verify the service provider and middleware are registered. The package should auto-instrument the HTTP kernel, so the first trace should be an inbound request without writing any application code.
  5. Send one request, open the backend, and confirm a root HTTP span exists with expected resource attributes.

Where to look first

  • config/opentelemetry.php — instrumentation toggles, exporter settings, middleware, and any sampling/resource configuration.
  • The package README for the current manual-span API and supported instrumentation list.
  • The installed OTel PHP SDK version in composer.lock — this is the real behavior boundary for exporters, batching, and semantic conventions.
  • Your Laravel bootstrap/app.php / HTTP kernel and queue configuration, because that is where instrumentation hooks in and where context propagation can break.

First use case

Pick one request path with a known latency or reliability problem — for example, “create order” or “fetch account summary.” Instrument that path end to end:

  • inbound request (automatic),
  • database queries (automatic, subject to redaction),
  • one outbound HTTP call (automatic),
  • one manual span around the highest-value domain operation.

The goal of the first use case is not full coverage. It is to prove that a developer can answer “where did this request spend its time, and which dependency failed?” from the trace alone, without adding ad hoc logging.

Implementation Patterns

Automatic-first, manual where it matters

Treat framework instrumentation as the baseline: HTTP requests, DB queries, queue jobs, Redis/cache, and outbound HTTP client calls. Do not manually re-instrument those. Reserve manual spans for domain behavior the framework cannot see:

  • pricing/discount calculation,
  • payment authorization,
  • saga/step orchestration,
  • external partner calls wrapped in application-specific retry logic,
  • batch operations where one job processes many records.

Use manual spans at transaction boundaries, not around every private method. A useful rule: add a span when you would otherwise add a temporary timer or log line during an incident.

Span naming conventions

Agree on conventions before broad rollout:

  • HTTP server spans: route template or controller action, not raw URL.
  • Outbound calls: dependency name plus operation, e.g. payment-gateway.authorize.
  • DB spans: leave the package/SDK defaults; do not rewrite them to include raw SQL.
  • Manual business spans: verb-noun, stable across refactors, e.g. order.calculate_totals.

Stable naming matters more than perfect naming. Dashboards and alerts will depend on it.

Request → DB → queue → outbound tracing

The primary day-to-day value is one trace showing the full path. Pattern:

  1. Inbound HTTP span starts automatically.
  2. Controller dispatches a job. The package should propagate trace context into the queue payload.
  3. The worker continues the same trace; verify the queue job span is a child of the HTTP span, not a new root.
  4. Outbound HTTP from the worker is a child of the job span.

Explicitly test each async boundary. Context propagation across queues, scheduled jobs, and console commands is where “distributed tracing” usually degrades into disconnected traces.

Queue and console jobs

For jobs, prefer one span per job and child spans per meaningful unit of work. Avoid creating a span per record in a large batch unless you are actively debugging that batch; it inflates volume and backend cost.

For scheduled/console commands, add a manual root span if the package does not create one automatically. Without it, command work appears as orphaned child spans or disappears from trace-based analysis.

Outbound HTTP integration

Instrument the shared HTTP client, not individual call sites. Then add application context at call sites through span attributes or events that describe the operation, not the payload. Include a deliberately failing outbound call in acceptance testing — failed-request spans are the ones that drive error-rate SLOs and incident triage.

Collector as the architectural boundary

Day-to-day developer workflow should assume:

Laravel app -> OTLP -> OpenTelemetry Collector -> backend

Developers instrument and emit; the platform team owns sampling, redaction, routing, and backend choice at the Collector. This keeps backend migration and attribute scrubbing out of application deploys. It also means developers should not hard-code vendor-specific endpoints or SDK exporters in application config.

Local development pattern

  • Run a local Collector or all-in-one Jaeger/Tempo container.
  • Use a distinct OTEL_SERVICE_NAME suffix such as -local and deployment.environment=local.
  • Keep trace export asynchronous and short-timeout so a stopped local Collector does not slow down or break local requests.
  • Use traces for local performance debugging when logs are insufficient; do not expect them to replace logs.

Testing and rollout pattern

  1. Staging pilot on a non-critical service.
  2. Add manual spans for two or three high-value business transactions.
  3. Run in parallel with existing APM/logging if one exists.
  4. Compare trace completeness, incident MTTR, and error visibility.
  5. Extend to queues, scheduled jobs, and outbound dependencies.
  6. Roll out fleet-wide only after conventions and redaction rules are written down.

Gotchas and Tips

Pin a minimum of 2.2.7

Release 2.2.7 fixed HTTP client traces failing to record failed outbound requests. Treat anything ≤2.2.6 as an unreliable baseline for outbound error analysis. Require >=2.2.7 in any pilot or production constraint, and add a deliberately failing outbound request to your acceptance tests so this class of regression is caught locally.

Do not use a synchronous exporter

The classic production mistake is synchronous span export. Under Collector degradation it adds tail latency or turns telemetry loss into request failures. Use asynchronous/batched export with short timeouts, and make telemetry loss explicitly non-fatal to the request path.

Flush on shutdown, especially with long-lived workers

Under Octane, Swoole, or long-running queue workers, batch buffers and memory behave differently than under PHP-FPM. Verify:

  • spans flush on graceful shutdown and worker restart,
  • final batches are not silently dropped,
  • memory does not grow across many requests/jobs,
  • queue workers explicitly flush before termination.

Test with a synthetic job that is deliberately terminated mid-run.

Redact before production, not after

SQL text, query bindings, URLs, headers, and exception messages can carry PII or secrets. This is a policy and configuration problem, not just a package setting. Establish:

  • which attributes are allowed,
  • where redaction happens (application SDK vs Collector),
  • retention rules,
  • who signs off.

Prefer Collector-level scrubbing for defense in depth, but do not rely on it alone; avoid emitting sensitive values from application code in the first place.

Watch metric and attribute cardinality

Raw user IDs, full URLs, request IDs, and unbounded exception messages as span or metric attributes will damage backend performance and cost. Keep high-cardinality values as span attributes only where needed for debugging, and keep metric labels low-cardinality. If the package or your manual spans emit route paths, normalize them to route templates.

Verify context propagation across async boundaries

Do not assume queue, scheduled-job, and console propagation works because HTTP tracing does. Check parent/child relationships explicitly for:

  • dispatched jobs and retries,
  • chained jobs,
  • scheduled commands,
  • outbound HTTP from workers,
  • events/listeners that dispatch further work.

Orphaned traces usually indicate missing context injection or a worker that starts a new root span.

Patch releases matter more than semver suggests

2.2.7 is a one-line-looking patch that changes what is visible in production error analysis. Read patch changelogs before bumping and treat package + OTel PHP SDK as a single upgrade unit. Pin them together and test upgrades together; upstream semantic conventions and SDK behavior still move.

Upstream SDK is part of your dependency surface

This package is an integration layer. Reliability depends on the OTel PHP SDK, exporter configuration, Collector, and backend. Check whether the native PHP extension is available in your build images; the pure-PHP path is simpler operationally but slower. Validate PHP version and extension availability in every runtime image, not just locally.

Auto-instrumentation will not cover domain logic

Expect gaps in pricing engines, saga orchestration, business-rule evaluation, and internal service boundaries. Manual spans are a developer-experience and training obligation. Publish short examples and a naming guide so different teams do not invent incompatible span names.

Adoption and support risk is real

Low stars, zero listed dependents, and effectively single-maintainer status mean you are an early production user. Mitigations:

  • name an internal owner for the package and Collector,
  • maintain a fork or vendored config overlay,
  • document a fallback to direct OTel SDK instrumentation,
  • pre-agree a minimum-version policy and changelog review process,
  • avoid relying on GitHub issues as primary support for tier-1 services.

Keep backend choice out of application code

Because the output is OTLP, the backend should be a procurement and Collector concern. Do not let vendor-specific exporters or endpoints leak into controllers, jobs, or package config. This preserves the main advantage of the package and keeps a backend migration to a Collector configuration change rather than an application rewrite.

Pilot success criteria should be explicit

Define them before rollout: end-to-end trace visibility for a named transaction, acceptable overhead, verified error-path coverage, documented redaction rules, queue/console coverage, and a named owner for the Collector and the package. Without these, the pilot becomes an open-ended instrumentation project.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager