trademachines/riemann-logger
Laravel package that connects your application logging to Riemann monitoring. It forwards log records and events to a Riemann server via Monolog, helping centralize observability, alerts, and metrics.
trademachines/riemann-logger is a thin PSR-3-ish logger that turns log records into Riemann events via trademachines/riemann-client-php. Riemann is an event stream processor, not a log store — you're feeding it short-lived state/metric events that streams index, alert on, and forward. Treat this package as a metrics/alerting side-channel, not a replacement for your file/stdout log stack.
Minimal steps:
composer require trademachines/riemann-logger (this should pull in trademachines/riemann-client-php; if not, require it explicitly).5555: nc -zv riemann.internal 5555.src/ before writing a line of config. With 0 stars and 0 dependents there is effectively no documentation, no changelog, and no third-party usage to crib from. You need to know exactly:
Riemann\Client instance plus options),Psr\Log\LoggerInterface or only a subset,state values,service, host, description, tags, attributes) and which it lets you override.use Riemann\Client;
use Riemann\Transport\TcpSocket;
$client = new Client(new TcpSocket('riemann.internal', 5555));
$logger = new \TradeMachines\RiemannLogger\Logger($client); // verify class name in src/
$logger->info('order.sync.completed', ['count' => 42]);
Then in riemann-client or the Riemann dashboard, confirm the event arrived and note its service/state/description shape — that shape is what every stream you write will match on.
Wire it through Monolog, not directly. In a Laravel app the sane integration is as a log channel, not scattered new Logger(...) calls. Register a custom channel in a service provider:
Log::extend('riemann', function ($app, array $config) {
$client = new Client(new TcpSocket($config['host'], $config['port']));
return new \Monolog\Logger('riemann', [
new RiemannHandler(new RiemannLogger($client)),
]);
});
Keep this channel off the default stack. Use it via Log::channel('riemann')->info(...) at deliberate call sites (job completion, queue depth, payment failures), or attach it alongside your normal channel only for error and above.
Map levels to states explicitly. Riemann streams branch on state (ok, warning, critical, unknown). PSR-3's eight levels don't map cleanly. Decide once — e.g. debug/info → ok, notice/warning → warning, error/critical/alert/emergency → critical — and either configure it or wrap the logger in a small adapter you control. Do not leave this to the package default without reading it.
Use tags and attributes for queryable dimensions. Riemann tags are indexed and cheap to filter on; attributes are arbitrary key/value. Push your trace/correlation ID, environment, and tenant into tags so a stream can group by them:
$logger->error('payment.failed', [
'tags' => ['env:' . app()->environment(), 'trace:' . $traceId],
'attrs' => ['order_id' => $order->id],
]);
Split transports by purpose. TCP for anything you'd page on (delivery matters, and you accept the latency); UDP for high-volume debug/metric noise where dropped packets are fine. Construct two clients/logger instances if you need both.
Isolate failures. The logger should never be able to take down a request. Wrap the client in a decorator that catches transport exceptions, or configure a short connect timeout on the socket so a dead Riemann host costs you milliseconds, not seconds.
Test by faking the client. Because the logger takes a client, you can inject a mock and assert on the Riemann\Event objects it emits — level→state mapping, tag propagation, description templating. This is the cheapest way to lock down behaviour the package doesn't document.
try/catch decorator is mandatory, not optional.{placeholder} substitution and exception handling are common gaps in small loggers — verify against src/ rather than assuming.service; if service includes a user ID, order ID, or full message string you'll blow up index cardinality and slow every stream. Keep service low-cardinality and push identifiers into tags/attributes/description.time (Unix seconds, float). Confirm the logger sets it; if it defaults to zero, streams that rely on :time will behave strangely.riemann-client-php is a reasonable escape hatch.service/host, a tags/attributes accessor, and whether the log call accepts an options array at all. If any are missing, add them in your own adapter rather than patching the vendor tree.How can I help you explore Laravel packages today?