thereddot/monolog-extra-bundle
A Symfony bundle that extends Monolog with extra handlers, processors, and configuration options for richer application logging. It integrates with MonologBundle to add ready-to-use logging utilities with minimal setup.
Reality check first: this is a Symfony bundle, not a Laravel package. There is no service provider, no config/monolog-extra.php, and composer require thereddot/monolog-extra-bundle in a Laravel app will install code that never boots. Treat it as a reference implementation for logging PSR-7 request/response bodies, not a dependency you can adopt. It's archived (last release Feb 2021), 2 stars, zero dependents — assume no fixes for modern PHP or Laravel/Symfony versions.
If you are actually on Symfony (or evaluating the source):
composer require thereddot/monolog-extra-bundle — check composer.json constraints against your PHP/Symfony versions first; a 2021 bundle likely caps at PHP 7.x/8.0 and Symfony 4/5.config/bundles.php:
TheRedDot\MonologExtraBundle\MonologExtraBundle::class => ['all' => true],
DependencyInjection/Configuration.php before writing YAML — that is the only reliable source for the real root key and option names. Do not trust blog snippets.config/packages/monolog.yaml rather than assuming the bundle auto-injects them:
monolog:
handlers:
http_traffic:
type: stream
path: '%kernel.logs_dir%/http.log'
level: debug
channels: ['http_traffic']
processors: ['the_red_dot_monolog_extra.processor.request'] # verify service id in `debug:container`
bin/console debug:container "the_red_dot" and bin/console debug:event-dispatcher.First use case: logging outbound HTTP client calls (request body, response status, response body) to a dedicated channel so you can replay/inspect third-party API traffic without touching your application log.
For a Laravel developer, the equivalent first step is not this package — it's a Monolog tap or a middleware. See Implementation Patterns.
Pattern 1 — Dedicated channel per traffic type. The core value of the bundle is "don't pollute app.log with request/response bodies." Reproduce it in Laravel with a custom channel in config/logging.php:
'http_traffic' => [
'driver' => 'monolog',
'handler' => StreamHandler::class,
'with' => ['stream' => storage_path('logs/http_traffic.log')],
'tap' => [App\Logging\RedactBodies::class],
],
Pattern 2 — Processor-style enrichment. The bundle's processors append contextual fields (request method, URI, headers, status) to every record. In Laravel, the idiomatic port is a Monolog processor pushed from a service provider:
Log::channel('http_traffic')->pushProcessor(function (array $record) {
$record['extra']['method'] = request()->method();
$record['extra']['uri'] = request()->fullUrl();
$record['extra']['status'] = app()->bound('http_status') ? app('http_status') : null;
return $record;
});
Pattern 3 — Wrap the outbound client, not the kernel. The bundle logs PSR-7 messages, which map to outbound calls. In Laravel, wrap Http:: with a macro instead of adding global middleware:
Http::macro('logged', function (string $channel) {
return Http::withMiddleware(new LogHttpTraffic($channel));
});
Keep it opt-in per client — logging every request (including health checks and queue polling) is the fastest way to fill a disk.
Pattern 4 — Redaction as a processor, not at call sites. If you port the bundle's request/response logger, add a redaction processor that walks the body array/JSON and masks keys like password, token, authorization, card. Centralize it once; call-site redaction always drifts.
Pattern 5 — Sampling for high-traffic paths. The bundle has no sampling. Add it yourself (e.g. log 1 in 100 successful 2xx, 100% of 4xx/5xx), or the "log everything" default will bite you in production.
Integration tip: if you genuinely need this in a Symfony legacy app, keep the bundle isolated — do not let RequestResponseLogger become the only path where request data exists, or you'll couple your debugging workflow to an archived dependency.
register()/boot(). Any Laravel guide you find that says composer require and "it just works" is wrong.Illuminate\Http\Request is HttpFoundation; Symfony's HttpClient returns its own Response. You will lose half the payload converting between them — log from the transport layer before conversion.the_red_dot_monolog_extra.* convention, but confirm with bin/console debug:container | grep the_red_dot — guessing wrong produces a silently-empty handler, which is the worst failure mode.debug), and the channel actually being used by the code path.$response->getBody()->getContents() moves the pointer); use __toString only if the stream is seekable.max_files/max_file_size (Monolog rotating_file) and a separate retention policy for the traffic channel.LoggerInterface with a channel name already bound. Both are ~20 lines in Laravel and remove any need for the archived dependency.Symfony\Component\HttpClient and GuzzleHttp\Client, and add the redaction and sampling layers the original lacks. Budget a day; the package is small enough that a clean reimplementation is often faster than a fork.Bottom line for a Laravel team: don't adopt. Use it as a spec for two things you should build natively — a http_traffic channel and a redacting outbound-HTTP middleware. You'll get 100% of the value with 0% of the archived-dependency risk.
How can I help you explore Laravel packages today?