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

Datadog Bundle Laravel Package

presta/datadog-bundle

Symfony bundle for Datadog integration: send StatsD metrics and APM traces from your app with minimal configuration, plus helpers for timing code and tracking custom events. A lightweight way to add Datadog monitoring to existing Symfony projects.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check before anything else: this is still a Symfony bundle, not a Laravel package. There's no service provider, no config/datadog.php, no extra.laravel block. Composer will install it, but nothing in Laravel will pick it up. Treat the bundle as a reference implementation of a Monolog → Datadog log intake handler rather than a dependency you "use."

What changed in v2.0.0 that you need to know up front: the minimum platform moved to Symfony ^6.4|^7.0 and PHP 8.1+ (8.2+ for Symfony 7), and — critically for Laravel porters — the DatadogHandler constructor no longer takes Symfony\Component\Security\Core\Security. It takes a TokenStorageInterface (security.token_storage) instead, because Security was deprecated in Symfony 6.2 and removed in 7.0. On Symfony with default config this is a no-op. On Laravel it means the handler now has a hard type-hint on a Symfony Security interface that your app does not have wired up.

Where to look first:

  1. README.md — still small; note the YAML config keys shown.
  2. DependencyInjection/Configuration.php — the authoritative config tree (key names, defaults, required fields). The README historically lags behind this.
  3. DependencyInjection/PrestaDatadogExtension.php — now extends Extension rather than ConfigurableExtension (internal, the class is final), but still the place to see how config values are mapped into the handler constructor.
  4. Resources/config/services.* — the handler service definition. Check how security.token_storage is injected; you'll need to replicate or stub that argument.
  5. The handler class itself (Presta\DatadogBundle\Monolog\Handler\DatadogHandler) — confirm the full constructor signature, transport (curl vs. HTTP client vs. UDP), and formatter before copying anything.

Minimal steps on Symfony: composer require presta/datadog-bundle:^2.0, register the bundle in config/bundles.php, set presta_datadog.api_key, env, service, then attach the handler to a Monolog channel. First use case: ship application logs to Datadog Log Management while keeping a local file handler for development. If you were on 1.x with Symfony 6.4, upgrading the package alone is sufficient unless you instantiate the handler or redefine its service yourself.

Minimal steps on Laravel: vendor the handler class into app/Logging/ (or require the package and reference its FQCN), then add a channel:

// config/logging.php
'datadog' => [
    'driver'  => 'monolog',
    'level'   => env('LOG_LEVEL', 'info'),
    'handler' => \Presta\DatadogBundle\Monolog\Handler\DatadogHandler::class,
    'handler_with' => [
        'apiKey' => config('services.datadog.key'),
        // v2: a TokenStorageInterface is now required — see Gotchas
        'tokenStorage' => new \Symfony\Component\Security\Core\Authentication\Token\Storage\NullTokenStorage(),
    ],
],

Then set LOG_CHANNEL=datadog in production. Verify the constructor args against the class — this is the single most common porting failure, and v2 has changed the arg list, so any snippet you find from a 1.x-era blog post is now wrong.

Implementation Patterns

  • Dedicated channel, not the default. Create datadog as its own channel and select it via env (LOG_CHANNEL, or a stack in logging.php). Keeps local/daily behavior untouched and makes rollback a one-line env change.
  • Account for the new TokenStorage dependency. In v2 the handler resolves the current user from Symfony's token storage rather than the deprecated Security helper. On Laravel, either pass NullTokenStorage and add user_id yourself via tap, or (better, if you're vendoring anyway) strip the token-storage argument out of your copy entirely — you already have auth()->id(). Don't pull symfony/security-core into a Laravel app just to satisfy a null check.
  • Use tap for request context. Add request_id, user_id, route name, tenant, and release version once at the channel level rather than sprinkling them into every Log::info() call. Datadog facets need consistent top-level attributes.
  • Structured logs win. Log arrays (Log::info('order.paid', ['order_id' => $id, 'amount_cents' => $cents])) so fields become facets and can be filtered/aggregated. Preformatted strings defeat the purpose.
  • Buffer before you hit the wire. If the handler does a synchronous outbound HTTP call per flush, wrap it in a BufferHandler (or FingersCrossedHandler) so a burst of errors doesn't spawn one request per record. Logging must never be your slowest code path.
  • Prefer the local Datadog Agent when available. If your infra already runs datadog-agent, sending to localhost (UDP/HTTP) is cheaper, lower-latency, and survives intake outages better than the HTTP intake handler. The bundle's handler is fine as a fallback for environments without an agent.
  • Environment split. Only register the Datadog channel for staging/production. Locally, a failing remote log should be a no-op, not a stack trace in your console.
  • Isolate the integration. Wrap the handler behind your own channel config so that replacing it later with the official Datadog handler, an OTel exporter, or a queue-based shipper is a config change, not a refactor.

Gotchas and Tips

  • Breaking change: constructor signature. If you instantiate DatadogHandler manually — which is exactly what the Laravel port above does — you must swap the Security argument for a TokenStorageInterface. handler_with does no transformation, so an old 'security' => ... key will now throw a TypeError or an unresolvable-argument exception from Monolog's handler factory. This is the single most likely upgrade break in a Laravel context.
  • Platform floor moved. v2 requires PHP 8.1+ (8.2+ on Symfony 7) and Symfony ^6.4|^7.0; Symfony 5.x and 6.0–6.3 are dropped. If you're maintaining an older Laravel app on PHP 8.0, this release is not installable — stay on 1.x. Note also that CI covers 8.1 / 8.2 / 8.5 against 6.4 and 7.4, so 8.3 and 8.4 aren't explicitly in the matrix; they'll almost certainly work, but they haven't been tested by the maintainer.
  • New explicit requirements. monolog/monolog (3.x) and symfony/http-foundation are now declared dependencies rather than assumed. Monolog 3 is what Laravel 10/11 already ship, so that aligns fine — but if you're on an older Laravel pinned to Monolog 2, this package will fight your composer resolution.
  • Still a maturity risk. Tiny install base, sparse release history (previous tag was Feb 2023). The v2 bump is a good sign — PHPStan 2.x at level max with an empty baseline and a real CI matrix is better hygiene than most abandoned bundles get — but it's still a single-handler package. The handler plus DI glue is small enough to vendor and own; that remains the correct move for most Laravel teams.
  • No Laravel auto-discovery. You wire everything manually via handler_with. Confirm constructor parameter names exactly (apiKey vs api_key, tokenStorage vs token_storage, etc.) — Monolog does not transform keys.
  • Config key translation. On Symfony the YAML keys (api_key, source, tags) are mapped to constructor arguments by the extension. When porting to Laravel, read Configuration.php and the extension to get the real names and defaults; the README is not reliable for this. Re-read them after v2 regardless of what you had at 1.x.
  • Key types are not interchangeable. Datadog has a logs intake API key, an application key (API management), and a client token (RUM). Passing the wrong one produces silent 403s. Store in config/services.php → env('DD_API_KEY'), never commit it, and always run php artisan config:cache after changes.
  • Don't let logging take down requests. Set a short timeout and make the handler tolerant of failures (ignore_exceptions on the channel or a WhatFailureGroupHandler wrapper). A Datadog outage should degrade observability, not your app.
  • Volume and cost. Datadog bills on ingestion. Default to info, drop debug in prod, and sample noisy paths. The handler choice matters far less than what you send.
  • Debugging the wiring. On Symfony: bin/console debug:config presta_datadog and debug:container <handler.service.id> to see resolved arguments — with v2 this is the fastest way to confirm the token-storage injection is what you expect. On Laravel: dump config('logging.channels.datadog') after config:cache and temporarily add a single channel in parallel to confirm records are actually leaving the app.
  • Network assumptions. If the handler shells out to curl or an unbounded Guzzle client, verify TLS, proxy, and DNS in your container. Silent failures are common — always pair the Datadog channel with a local fallback handler (e.g., a StreamHandler to stderr) so logs aren't lost when intake is unreachable.
  • Extension point (if you stay on Symfony): decorate or override the handler service, or supply a JsonFormatter if you want a specific wire format. PrestaDatadogExtension is now final, so subclassing it is out — use decoration, not inheritance. Avoid forking the bundle unless you're already committed to owning it.
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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle