elcweb/graylog-bundle
Symfony bundle that provides a Monolog GELF handler for sending log messages to a Graylog server over UDP. Install via Composer, register the bundle in your kernel, then configure hostname, port, and the gelf handler in config.yml.
This bundle is a thin Symfony 2/3 wrapper around a Monolog GELF (UDP) handler. It exists to answer one question: "how do I get my app's Monolog records into a Graylog UDP input?" If that is not your question, stop here and use Monolog's built-in gelf handler type instead — this package is archived, has no dependents, and is pinned to the old AppKernel bundle-registration model.
Minimal path if you are on a legacy Symfony app:
composer require elcweb/graylog-bundle (expect it to resolve graylog2/gelf-php transitively — verify with composer show graylog2/gelf-php).app/AppKernel.php: new Elcweb\GraylogBundle\ElcwebGraylogBundle().parameters:
elcweb_graylog.hostname: 127.0.0.1
elcweb_graylog.port: 12201
monolog:
handlers:
gelf:
type: service
id: elcweb.graylog.monolog.gelf_handler
level: debug
Look first at: Resources/config/services.yml inside the bundle. That is the whole package — a single service definition constructing a GELF handler from the two parameters. There is no configuration tree, no compiler pass, no extension class worth reading. Knowing that up front saves you from hunting for options that don't exist.
First use case: point a Graylog GELF UDP input at your app host/port, keep your existing stream/fingers_crossed handler alongside it, and confirm messages land in Graylog. Do not replace file logging on day one — UDP is fire-and-forget, and you want a local copy while you validate.
Dual-handler (recommended baseline). Keep local files authoritative, ship a copy to Graylog:
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: file
channels: ["!gelf"]
file:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
gelf:
type: service
id: elcweb.graylog.monolog.gelf_handler
level: notice
Note the channels: ["!gelf"] exclusion on main — without it you will double-log through fingers_crossed and get confusing duplicates in Graylog.
Environment gating. Because the handler is just a service, gate it on the environment so dev machines don't flood the Graylog input:
# config_prod.yml
monolog:
handlers:
gelf:
type: service
id: elcweb.graylog.monolog.gelf_handler
level: notice
Leave it out of config_dev.yml entirely, and in config_test.yml point Monolog at a test handler.
Channel routing for signal separation. Route only the channels you actually want centralized, and let noisy ones stay on disk:
gelf:
type: service
id: elcweb.graylog.monolog.gelf_handler
level: warning
channels: ["app", "security", "request"]
Attaching context. The bundle gives you no help here; add Monolog processors yourself and they will flow through to GELF:
services:
monolog.processor.request_id:
class: AppBundle\Monolog\RequestIdProcessor
tags:
- { name: monolog.processor, method: processRecord }
Remember GELF only preserves additional fields when they are prefixed with _. Custom processor keys like request_id will be sent as _request_id; if they are not prefixed they will be dropped by Graylog. Either prefix in the processor or accept whatever graylog2/gelf-php does with the extra array.
Swapping the transport later. Because Monolog references a service id rather than a handler type, you can replace the definition in your own services.yml without touching Monolog config. That is the one genuinely useful extension point: override elcweb.graylog.monolog.gelf_handler with your own handler class (e.g. one wrapping Gelf\Publisher with a TcpTransport, or one that buffers to batch). Do this if you ever need TLS or batching.
Migration path for new code. On Symfony 4+ use the built-in handler instead of the bundle:
monolog:
handlers:
gelf:
type: gelf
publisher:
hostname: "%env(GRAYLOG_HOST)%"
port: 12201
level: notice
This is the same graylog2/gelf-php underneath with no archived bundle in the supply chain.
graylog2/gelf-php chunks messages, but chunking is frequently disabled or mis-sized on the Graylog UDP input side. Symptom: truncated or missing stack traces for exactly the errors you care most about. Verify chunking is enabled on the input before you trust it.elcweb_graylog.hostname / elcweb_graylog.port as plain parameters. Typo the name and you get a ParameterNotFoundException at container compile — or worse, a hostname of the literal string. There is no Configuration class to catch this.bin/console cache:clear after editing config. On prod deploys, a stale container is the usual reason "logs aren't showing up."type: service limits handler options. You cannot set formatter or processors directly on a service-type handler in the same way as built-in types. Attach processors via the monolog.processor tag instead, or override the service definition.nc -ul 12201 or sudo tcpdump -i any -n udp port 12201. If packets leave and Graylog shows nothing, the problem is the input configuration, not the bundle.graylog2/gelf-php itself is still receiving releases before you depend on the stack at all.AppKernel.php in the README is a signal. If your project doesn't have an AppKernel, this bundle is not for you — skip to the type: gelf Monolog config above and move on.level: debug handler pointed at prod will generate a surprising volume of network traffic. Start at notice or warning and tune down once you see volume in Graylog.How can I help you explore Laravel packages today?