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

Riemann Logging Bundle Laravel Package

trademachines/riemann-logging-bundle

Integrates Riemann event logging into Symfony applications. Ships a Monolog handler and service configuration so application logs and custom events stream to your Riemann server for real-time monitoring, alerting, and dashboards. Configurable via bundle settings with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

Read the source before you composer require anything. This package has no stars, no dependents, and no documentation, so the repository is the documentation. Budget 20 minutes:

  1. composer.json — identifies the Riemann client it wraps (most likely mjansen/riemann-php-client or php-riemann/riemann-client) and the supported PHP/Symfony versions. If it pins symfony/* to ^3.x or ^4.x, it will not install cleanly alongside a modern Laravel and you should stop here and go straight to the underlying client.
  2. src/DependencyInjection/Configuration.php — the authoritative list of config keys (host, port, protocol, tags, ttl, service name, level threshold).
  3. The Monolog handler class in src/ (probably RiemannHandler or Monolog/Handler/...) — this is the only part you actually care about. Everything else is Symfony DI glue.
  4. README.md — usually the Symfony service config example; treat it as a sample, not a contract.

The key framing for a Laravel developer: this is a Symfony bundle, not a Laravel package. The Bundle subclass and Extension class are dead code in a Laravel app — there is no bundle auto-registration. What you are actually buying is a Monolog handler that translates a LogRecord into a Riemann event. That handler is almost certainly a few dozen lines. Install it, then wire the handler manually in config/logging.php; ignore the DI layer entirely.

Minimal first use case: ship error and above to Riemann so a failure in production shows up on the same dashboard as your host metrics, instead of only in a log file nobody is tailing.

// config/logging.php
'riemann' => [
    'driver'  => 'monolog',
    'level'   => env('LOG_LEVEL', 'error'),
    'handler' => \TradeMachines\RiemannLoggingBundle\Monolog\Handler\RiemannHandler::class,
    'handler_with' => [
        'host' => env('RIEMANN_HOST', '127.0.0.1'),
        'port' => (int) env('RIEMANN_PORT', 5555),
    ],
],

Confirm the constructor signature against the source before trusting the handler_with keys — this is the step people skip and then spend an hour on a BindingResolutionException.

Implementation Patterns

Attach it as a non-exclusive sink, not the default channel. Logs should still go to a file/stderr. Use a stack channel so a Riemann outage cannot take down your logging:

'stack' => [
    'driver'   => 'stack',
    'channels' => ['single', 'riemann'],
],

Wrap the Riemann handler in WhatFailureGroupHandler (or BufferHandler → Riemann) so a connection failure degrades to silence rather than a 500.

Map the record fields deliberately. A Riemann event has service, host, state, description, tags, ttl, metric. The handler will derive most of these from the record, but you want to control them:

  • service must be stable and low-cardinality (checkout-api.errors), not checkout-api.errors.Order 1234 failed. If the service name embeds a dynamic value you cannot aggregate or alert on it in Riemann.
  • state should come from the Monolog level, mapped explicitly: error/critical/alert/emergency → critical, warning/notice → warning, everything else → ok. Do not let the package's default mapping stand unexamined; a notice arriving as critical will page someone at 3am.
  • ttl must be longer than your send interval (see Gotchas).

Use processors for correlation, not the handler. Laravel's RequestIdProcessor / a custom processor adding trace_id, user_id, env, and release into extra is the clean extension point — the handler will fold context into the event. Adding these inside the handler means forking it.

Distinguish "logs as events" from "metrics". The bundle only covers the logging path. For counters and timings (queue depth, external API latency, job durations) call the underlying Riemann client directly in a small service — Riemann::event() with metric set — rather than encoding numbers into log strings and parsing them downstream.

Batch off the request path for anything high-volume. If you are logging at info on a busy endpoint, a synchronous TCP write per record will dominate your latency. Put the Riemann write behind ->via('queue') in a queued listener, or buffer and flush in a terminating callback.

Wire the failure path too. The most valuable single event this package produces is "the app threw an unhandled exception." Make sure that path is covered — a report() hook or the exception handler's reportable closure that force-emits a critical event with the exception class in the service name and the message in the description.

Gotchas and Tips

The Symfony bundle layer is unusable in Laravel, and that's fine. No registerBundles(), no autoloaded Extension, no %riemann.host% parameter resolution. Everything under src/DependencyInjection/ and src/Resources/config/ is inert. Read it for the intended defaults, then hand-wire. If the handler's constructor takes a pre-built client object rather than scalars, you'll need a small service provider binding — expect this and check first.

Riemann down must not mean app down. Older PHP Riemann clients have spotty timeout handling. UDP is fire-and-forget (fast, silently lossy); TCP blocks and will hang a request if the socket is up but Riemann is wedged. Prefer UDP with a generous TTL for logs, or TCP strictly behind a buffer + WhatFailureGroupHandler. Test it: stop Riemann, hit a route that throws, confirm the response is normal and the next request still logs.

TTL is the setting people get wrong. Riemann expires an event after ttl and the state disappears or flips. Set ttl to roughly 3× your send cadence — long enough that ordinary jitter doesn't cause flapping, short enough that a dead app stops showing a green ok quickly. A 10s TTL with a 5-minute heartbeat gives you a dashboard that is wrong 96% of the time.

Level thresholds are enforced per-handler, not globally. Monolog passes every record to every handler; the level key in handler_with is what filters. Omitting it means debug logs hit Riemann and you'll blow through your write budget and your cardinaility budget simultaneously.

Context is a footgun. An exception object, an Eloquent model, or a 200KB request payload in context will either fatal on serialization or produce an unqueryable event. Add a normalizer that flattens to scalars and truncates strings (a few hundred chars is plenty for description).

Debugging the pipeline. Three layers can fail: Laravel → Monolog → client → Riemann. Isolate them:

# does anything arrive at all?
nc -u -l 5555
# is the event well-formed? query Riemann directly
riemann-client query 'service = "myapp.errors"'

If nothing arrives at nc, the problem is your handler wiring. If it arrives at nc but not in Riemann's index, it's the protocol/format or the TTL. If it's in the index with the wrong state, it's the level mapping.

Abandonment risk is the headline. Zero stars and zero dependents means no upstream fixes, no security patches, no one to file a bug with. Three mitigations, in order of preference:

  1. Depend on the underlying Riemann client directly and write your own ~60-line Monolog handler. Given what you just read in src/, this is genuinely a half-day of work and you own it.
  2. composer require the package but pin the exact version, and vendor-copy the handler class into app/Logging/ so a PHP upgrade can't strand you.
  3. Fork it under your org and treat it as internal.

Extension points worth knowing about if you keep the bundle: the handler class itself (subclass it to override field mapping rather than editing vendor code), Monolog processors for enrichment, and a custom formatter if you need the description string in a specific shape for a dashboard. There is almost certainly no events/dispatcher hook — don't go looking for one.

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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums