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

Log Bridge Bundle Laravel Package

m6web/log-bridge-bundle

M6Web LogBridgeBundle provides a Symfony logging bridge that integrates PSR-3/Monolog-compatible loggers into the service container, making it easy to configure and route application logs consistently across services with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and register

composer require m6web/log-bridge-bundle

Symfony Flex auto-registers bundles; on older apps add it manually:

// config/bundles.php
M6Web\Bundle\LogBridgeBundle\M6WebLogBridgeBundle::class => ['all' => true],

Minimal configuration — one filter, one level, log the response too:

# config/packages/m6_web_log_bridge.yaml
m6_web_log_bridge:
    logger:
        filters:
            api_errors:
                options:
                    level: error
                    response: true
                    request: true
                routes: ['app_api_orders_create', 'app_api_payments']

Then give the bundle a dedicated Monolog channel so records don't get lost among app logs:

# config/packages/monolog.yaml
monolog:
    channels: ['log_bridge']
    handlers:
        log_bridge:
            type: stream
            path: '%kernel.logs_dir%/%kernel.environment%.log_bridge.log'
            level: info
            channels: ['log_bridge']

Where to look first

  1. The bundle's README for the exact config tree shipped with your version.
  2. vendor/m6web/log-bridge-bundle/DependencyInjection/Configuration.php — this is the authoritative schema. Config keys here are cheaper to read than to debug via InvalidConfigurationException.
  3. EventListener/ / EventSubscriber/ — tells you when the log record is emitted (typically on kernel.terminate, after the response has been flushed to the client).

First use case: don't log everything. Start by capturing exactly what you'd otherwise tail -f for — failed write operations and 5xx responses on your most critical endpoints — with full request/response context in one record. That's the bundle's actual value proposition: a complete request/response pair correlated with a single Monolog line, without hand-rolling a listener.

Implementation Patterns

One filter per audience, not one filter for everything. Filters are matched by route name and carry their own options. Use that to split severity:

m6_web_log_bridge:
    logger:
        filters:
            mutations:
                options: { level: info, request: true, response: true }
                routes: ['app_api_order_create', 'app_api_order_cancel']
            server_errors:
                options: { level: critical, response: true }
                routes: ['app_api_.*']   # verify regex vs. exact-match in your version

Pair it with a correlation ID. The bundle logs the request, but the useful part is tying that record to your other logs and your error tracker. Add a Monolog processor that stamps request_id (from a UID header or generated in a kernel.request listener) and make sure it's applied to the log_bridge channel:

services:
    App\Monolog\RequestIdProcessor:
        tags: [{ name: monolog.processor, channel: log_bridge }]

Use it as a cheap black box instead of building one. For non-idempotent endpoints (payments, refunds, stock decrements) a kernel.terminate-time log of method + path + status + payload is often enough to reconstruct "what did the client actually send" during an incident, without an APM license.

Structured output. If you already ship JSON logs, don't fight the default formatter — implement the bundle's formatter interface (check Formatter/ for the exact contract and tag name; typically a service tagged for the log_bridge channel) and return a JSON-serializable array/string. Then point the handler at type: stream with formatter: monolog.formatter.json. This makes the records queryable in whatever you actually use to search logs.

Sample instead of mute. High-traffic read endpoints are the classic reason people rip this bundle out again. Either scope filters tightly or gate the logger service behind a small decorator that drops N% of records — cheaper than maintaining an exclusion list of forty route names.

Testing pattern: functional-test the contract, not the bundle. Boot a kernel, hit an endpoint with KernelBrowser, and assert a record landed on the channel via a Monolog test handler or a spy on the bundle's logger service. This catches the two regressions that actually happen: a route rename silently unmatching your filter, and a channel misconfiguration swallowing records.

Gotchas and Tips

Logging on kernel.terminate cuts both ways. You get zero latency added to the response — but the record appears after the client already has the response, so log ordering in your file is not request ordering. Don't build dashboards that assume adjacency.

Response body capture is the main footgun. Large payloads, StreamedResponse, BinaryFileResponse, and file downloads can serialize into megabytes of garbage or explode memory. Exclude download/export routes from any filter with response: true, and check whether your version offers a truncation/size option before you ship it.

Monolog drops records silently if the channel isn't configured. If nothing appears, the first thing to check is channels: on your handlers and that monolog.channels includes the bundle's channel. bin/console monolog:debug or a temporary type: test handler resolves this in one minute.

Sanitize before it reaches disk. request: true will happily capture Authorization headers, session cookies, API keys in query strings, and password fields in bodies. That is a GDPR/PCI problem, not a cosmetic one. Either extend the formatter to redact a known key list, or restrict body capture to explicitly safe routes. Never rely on "we'll clean the logs later."

Filters match on route name, not URL. Routes generated by annotations with empty names, or routes renamed during refactors, will silently stop matching — no error, no warning, just missing logs. Add a test that asserts each critical filter still matches. Also confirm behaviour for sub-requests (ESI/fragments): check whether the listener guards on master request, or you'll get several records per page view.

Level escalation is manual. A filter has one level. If you want warning for 4xx and critical for 5xx you need two filters with status-based conditions, or you handle the mapping in a custom formatter/logger. Don't assume per-status levels are automatic.

Config is cached. bin/console cache:clear after editing the bundle config, especially in dev when you're iterating on regexes.

Verify the wiring before debugging your own code:

bin/console debug:container --tag=<bundle tag>   # confirm formatter/logger services
bin/console debug:event-dispatcher kernel.terminate

Adoption risk is real and should shape your usage. 18 stars and zero dependents means you are close to the only consumer — this is a BedrockStreaming-internal-shaped bundle, not a de-facto standard. Two mitigations: (1) pin the version explicitly, and (2) keep your customizations in a formatter service rather than forking the bundle, so replacing it with a 60-line kernel.terminate listener later is an afternoon rather than a quarter. The extension points — custom formatter, custom filter — are the parts worth designing around.

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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin