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

Monolog Extra Bundle Laravel Package

m6web/monolog-extra-bundle

Symfony bundle that extends Monolog with extra handlers and processors, making it easier to route, format, and enrich application logs through standard bundle configuration. A practical add-on when built-in Monolog options need additional integrations without custom wiring.

View on GitHub
Deep Wiki
Context7

Getting Started

First, the reality check. m6web/monolog-extra-bundle is a Symfony bundle, not a Laravel package. It requires symfony/framework-bundle and symfony/monolog-bundle, ships no service provider, and offers nothing you can composer require into a Laravel app without dragging half of Symfony's kernel in behind it. So "getting started" splits into two realistic paths:

  1. You're touching a Symfony service (consulting, a migration, a shared platform like Bedrock Streaming's) — install and use it directly.
  2. You're in Laravel — you don't install it; you read it as a reference implementation of the patterns Laravel makes you assemble by hand (custom Monolog processors, a correlation-ID middleware, exception report()).

Minimal steps (Symfony context)

composer require m6web/monolog-extra-bundle
  1. Register the bundle (config/bundles.php — Flex does this automatically).
  2. Add the monolog_extra root key to config/packages/ and enable the pieces you want.
  3. Attach the bundle's processors to your Monolog handlers (they're registered under the monolog.processor tag, so monolog.yaml wiring is usually just ordering).

Where to look first

  • README.md — short, but it's the only doc.
  • DependencyInjection/Configuration.php — the authoritative list of config keys. With 6 stars and 0 dependents, treat this file as the docs.
  • Processor/ — the actual classes: request/context enrichment, tags, and the like.
  • Resources/config/*.xml — real service ids (they'll look like monolog_extra.*), which is what you need for debug:container.

First use case

Structured log enrichment: every log record carries request_id, uri, method, user_id, plus whatever domain tags you push, so a grep in Kibana/CloudWatch is enough to reconstruct a request. That's the 20% of the bundle that pays for itself.

Implementation Patterns

Pattern 1 — Request/context processor (the workhorse)

A processor decorates every Monolog\LogRecord with request metadata. In a Symfony app you enable it and forget it; in Laravel you build the equivalent in a middleware plus a channel tap:

// Laravel equivalent
Log::withContext([
    'request_id' => $requestId,
    'uri'        => $request->path(),
    'method'     => $request->method(),
]);

Pattern 2 — Correlation ID propagation

The bundle's real value in a microservice mesh is threading one ID from the ingress header through every log line — including the ones emitted by a queue worker hours later. In Symfony that means a kernel.request listener that reads X-Request-Id (or generates one) before anything logs. In Laravel:

// app/Http/Middleware/CorrelationId.php
$id = $request->header('X-Request-Id') ?? (string) Str::uuid();
Context::add('request_id', $id);
$response = $next($request);
return $response->header('X-Request-Id', $id);

And on jobs, push the ID onto the payload so the worker re-adds it.

Pattern 3 — Loggable exceptions

The bundle's nicest idea: an exception implements a marker interface exposing its own log level and context, and a listener logs it automatically — controllers stop doing catch { $logger->error(...); throw $e; }. Laravel's analogue is report()/Handler::report() combined with a renderable-style convention:

interface LoggableException {
    public function logLevel(): string;
    public function logContext(): array;
}

// App\Exceptions\Handler
protected function shouldReport(Throwable $e): bool { /* ... */ }

Wire a small listener in Handler::report() that reads logLevel()/logContext() when the interface is present.

Pattern 4 — Tags as first-class fields

Rather than interpolating into the message ("order {$id} failed"), push order_id as a structured field. In Laravel this is Log::withContext() scoped to the request, or a channel tap that merges a Context repository:

// config/logging.php
'daily' => [
    'driver' => 'daily',
    'tap'    => [App\Logging\AttachContext::class],
],

Pattern 5 — JSON formatter, non-negotiable

Processors attach arrays. LineFormatter will flatten or stringify them. Use monolog.formatter.json in Symfony, or 'formatter' => JsonFormatter::class per channel in Laravel, otherwise the enrichment is invisible.

Laravel ↔ bundle concept map

Bundle Laravel equivalent
Loggable exception interface Handler::report() / shouldntReport
Request processor Middleware + Log::withContext
Tag/context processor Context facade, channel tap
Logger service Typed wrapper around Log::channel()
Log levels per exception LogLevel::from($e) in report()

Gotchas and Tips

  • Don't install it in Laravel. Composer will resolve symfony/framework-bundle, which conflicts with illuminate/* in subtle ways (duplicate EventDispatcherInterface implementations, kernel bootstrapping). The patterns port; the package does not.
  • Processor ordering is semantic. Monolog runs processors in registration order and later ones overwrite keys. If your request_id disappears, something downstream is clobbering it — reorder in monolog.yaml / your tap array.
  • CLI and queue workers have no request. A request processor will emit nulls or throw on getCurrentRequest() === null. Guard on php_sapi_name() === 'cli' and rely on the job payload instead. This is the #1 source of "why are all my worker logs missing context."
  • Never serialize the user object. The classic mistake: pushing the full User entity into the context. It bloats every record, leaks PII into your log vendor, and blows up on lazy-loading proxies. Push user_id; join elsewhere.
  • Cardinality is a bill. High-cardinality fields (user_id, order_id, full URIs with IDs) are fine as fields in Datadog/ELK but ruinous if you key indexes or tag names off them. Normalize paths, keep IDs as attributes.
  • Propagate, don't regenerate. If the queue worker mints its own correlation ID, you've broken the trace exactly where it's most valuable. Serialize it onto the job.
  • Monolog 2 vs 3. Monolog 3 changed the processor contract to Monolog\LogRecord. The bundle's last release is dated 2026-07-21, so verify the major you're on before assuming a processor works — a mismatched ProcessorInterface signature fails loudly at boot, which is at least easy to spot.
  • Debugging: bin/console debug:container monolog_extra (or debug:container --tag=monolog.processor) tells you what's actually registered; config/packages/monolog.yaml tells you what's actually attached. Most "it doesn't work" reports are a processor that's registered but not attached to the handler.
  • Extension point: write your own Monolog\Processor\ProcessorInterface and tag it monolog.processor — no bundle config needed, and it's trivially ported to Laravel later by moving the class into app/Logging/.
  • Adoption risk is real. Six stars and zero dependents means: no Stack Overflow answers, no Laravel equivalents, no community bug reports. It's MIT and backed by an active streaming platform that runs it internally, so it's not abandoned — but budget an hour to read Configuration.php and the processors before committing. For a large Symfony codebase that's cheap; for a Laravel one, copy the ideas and skip the dependency.
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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
cgv/localized-resource