- How do I install herdwatch-oss/monolog-ecs-formatter in a Laravel application?
- Install it with Composer using composer require herdwatch-oss/monolog-ecs-formatter. In Laravel you only need the formatter class, which you reference by fully qualified class name in config/logging.php. No service provider registration or application code changes are required because Laravel never reads the Symfony bundle registration shipped in the package. After installing, run php artisan config:clear so the new channel configuration is picked up.
- Does this Monolog ECS formatter work with both Monolog 2 and Monolog 3?
- Monolog 3 passes a LogRecord object to formatters while Monolog 2 passes an array, and a formatter typed against one will fail at runtime on the other. Laravel 10 and 11 pin Monolog 3, so verify the FormatterInterface signature against your locked version before adopting it. Check whether the package publishes a 2.x branch if you still run Laravel 9 or earlier. Add a small contract test that formats a real record so a Composer update cannot silently break your logging path.
- How are Monolog levels like warning and critical mapped to the ECS log.level field?
- ECS only permits trace, debug, info, warn, error and fatal, whereas Monolog emits WARNING, CRITICAL, ALERT and EMERGENCY. A naive lowercase conversion produces warning and critical, which are off-spec and quietly corrupt severity aggregations in Kibana because nothing throws an error. Confirm what the formatter actually outputs for critical, alert and emergency, and consider collapsing those three to fatal. Test the mapping explicitly rather than assuming it is correct.
- Do I need the Symfony bundle to use this package in Laravel?
- No. Laravel does not read Symfony bundle registration and the package ships no extra.laravel provider, so the bundle half is inert in a Laravel application. Treat the deliverable as one formatter class plus a config array, which keeps the integration surface very small. You wire it up purely through the formatter and formatter_with keys on a channel in config/logging.php. The Symfony bundle only matters if you also run Symfony services that share the same logging stack.
- How do I configure an ECS channel in Laravel's config/logging.php?
- Add a dedicated channel, for example ecs, using the daily or single driver and set its formatter key to the package's formatter class. Then compose that channel into your existing stack so production traffic writes ECS documents while you keep the legacy channel for comparison during migration. The happy path is roughly ten lines of configuration and no application code changes. Keep the stack composition explicit so you can drop the legacy channel once the Elasticsearch dashboards are validated.
- Will the @timestamp field be correct ISO 8601 with timezone and millisecond precision?
- ECS requires ISO 8601 with an explicit timezone offset and millisecond precision, and Monolog's legacy Y-m-d H:i:s datetime string satisfies neither. Confirm the formatter derives @timestamp from the record's DateTimeImmutable rather than the stringified datetime field. Also verify behaviour under Octane workers when the application timezone is overridden, since a stale or local-time timestamp will break time-based index routing and Kibana histograms. A single assertion in your test suite is enough to lock this down.
- What index template do I need in Elasticsearch for this formatter's output?
- The package formats fields but does not manage mappings, so you own the index template. Define labels as a flattened type and tags as keyword, because both are unbounded when fed from request or user data and dynamic keys against an object mapping cause field-limit blowups or rejected documents. Pin ecs.version in the template and align it with the ECS release the formatter targets. Without an explicit template, Elasticsearch's dynamic mapping will produce something you cannot query reliably later.
- How do I populate service.name, trace.id, user.id and event.dataset in the ECS logs?
- The formatter only reshapes what Monolog gives it, so enrichment is your responsibility. Push a request-scoped array with Log::withContext from middleware, including service.name, service.version, service.environment, event.dataset and user.id, and map your context keys to ECS names explicitly. Under Octane, scope that context to the request lifecycle so values do not leak between requests. Budget two to five developer days for a working vertical slice and two to three weeks including index template, dual-write and dashboard port.
- Is herdwatch-oss/monolog-ecs-formatter production ready and actively maintained?
- There is currently no social proof: zero stars, zero dependents and no visible production users, so the dominant risk is supply chain and bus factor rather than capability. Review commit cadence, CI configuration and test coverage, and check whether there is any evidence of use beyond the author's own environment. If you adopt it, consider vendoring or forking the formatter, which is small enough to own outright. Established alternatives include writing a short custom formatter or using a community ECS formatter with an active maintainer base.
- Can the formatter break my request if log context contains non-UTF8 strings or cyclic objects?
- Yes, a formatter that throws on invalid UTF-8 or a cyclic object graph can fail the request that was merely trying to log. Wrap the ECS channel in a WhatFailureGroupHandler with a fallback channel so logging failures never surface as application errors. Sanitise or truncate context before it reaches the formatter, particularly request payloads and exception dumps. Also confirm whether exceptions are normalised into error.type, error.message and error.stack_trace rather than dumped whole into context.