Sending Logs to Graylog

A Graylog stack is only useful once log sources are pointing at it. This guide wires three common client types into the Dockerised Graylog from the previous article: Linux via rsyslog (the universal, agentless route), Windows via the Graylog Sidecar managing Winlogbeat (the recommended way to ship Windows Event Logs), and macOS via its built-in syslog daemon. Each client targets a matching input you create once on the Graylog server.

Sources: Linux (rsyslog) · Windows (Sidecar + Winlogbeat) · macOS (syslogd)  ·  Inputs: Syslog · GELF · Beats
⚠  About iOS: Apple sandboxes iOS so tightly that there is no supported way to forward a device's system logs to an external syslog/Graylog server — it would require a jailbreak or an MDM/log-relay product, neither of which is a normal Graylog workflow. This guide covers macOS instead, which shares the same Unix syslog tooling and is almost always what's actually needed. Logs from an iOS app you write can still reach Graylog by calling a GELF HTTP input from your own code.
01 — Make the Inputs Reachable First

In the Docker article, the example Compose file binds every input port to 127.0.0.1, meaning only the Graylog host itself can connect. Before any remote client can send a single line, you must publish those ports on a routable interface and restart the container.

docker-compose.yml — remove the loopback prefix
ports: - "5044:5044/tcp" # Beats (was 127.0.0.1:5044:5044/tcp) - "5140:5140/udp" # Syslog - "5140:5140/tcp" # Syslog - "12201:12201/tcp" # GELF TCP - "12201:12201/udp" # GELF UDP - "9000:9000/tcp" # Web & API
Recreate the Graylog container
docker compose up -d
⚠  Opening these ports to a network means anything that can reach them can inject logs. Restrict access with host firewall rules (allow only your client subnets), and prefer TLS-capable transports on untrusted networks. Never expose raw syslog/GELF ports to the public internet.
02 — Understand Inputs vs. Collectors

Two halves have to agree: a collector on the client sends in a particular format and protocol, and an input on the Graylog server listens for exactly that. Mismatch either side and messages silently never appear.

Client / CollectorGraylog inputDefault port
rsyslog (Linux/macOS), plain syslogSyslog UDP / Syslog TCP5140
rsyslog with GELF templateGELF UDP / GELF TCP12201
Winlogbeat / Filebeat (via Sidecar)Beats5044
Your own app codeGELF HTTP12201 (or custom)
ℹ  Create inputs under System / Inputs: pick the type, click Launch new input, tick Global so it runs on every node, set the port to the value mapped in Compose, and save. The port you type here must match both the Compose mapping and the client config.
03 — Linux: Quick Syslog Forwarding

Nearly every Linux distribution already runs rsyslog. The fastest path is to forward all messages in RFC 5424 format to a Syslog input — no extra software, no templates. First create a Syslog UDP (or TCP) input on port 5140 in Graylog, then drop a small config file on the client.

/etc/rsyslog.d/90-graylog.conf
# Send everything to Graylog over UDP, RFC 5424 format *.* @your-graylog-ip:5140;RSYSLOG_SyslogProtocol23Format # For TCP instead, double the @ : # *.* @@your-graylog-ip:5140;RSYSLOG_SyslogProtocol23Format
Apply & verify
sudo rsyslogd -N1 # check config syntax sudo systemctl restart rsyslog logger "hello from $(hostname) to graylog" # send a test line

Open Search in Graylog and the test line should appear within a second or two, tagged with the client's hostname.

ℹ  A single @ means UDP, @@ means TCP. RFC 5424 (RSYSLOG_SyslogProtocol23Format) gives Graylog clean, parseable timestamps and structured fields — prefer it over the legacy format.
04 — Linux: Richer Forwarding with GELF

Plain syslog is fine for system messages, but GELF (Graylog Extended Log Format) carries structured fields and avoids syslog's length and escaping quirks. Define a GELF template in rsyslog and point an output action at a GELF input on port 12201.

/etc/rsyslog.d/91-graylog-gelf.conf
template(name="gelf" type="list") { constant(value="{\"version\":\"1.1\",") constant(value="\"host\":\"") property(name="hostname") constant(value="\",\"short_message\":\"") property(name="msg" format="json") constant(value="\",\"timestamp\":") property(name="timegenerated" dateformat="unixtimestamp") constant(value=",\"level\":\"") property(name="syslogseverity") constant(value="\"}") } # Forward to the Graylog GELF UDP input *.* action(type="omfwd" target="your-graylog-ip" port="12201" protocol="udp" template="gelf")
⚠  The GELF-over-rsyslog template above works cleanly over UDP. Graylog's GELF TCP input expects each message terminated by a null byte, which rsyslog's omfwd cannot emit — so for GELF use UDP here, or stick with a Syslog TCP input if you need a reliable TCP transport.
Apply
sudo rsyslogd -N1 sudo systemctl restart rsyslog
05 — Windows: Install the Graylog Sidecar

The recommended way to ship Windows Event Logs is the Graylog Sidecar — a lightweight service that manages the Winlogbeat collector and pulls its configuration centrally from Graylog. You configure once in the web UI; every tagged Windows host picks it up. Start by preparing Graylog.

On the Graylog server (one-time)
StepWhere
Launch a Beats input on port 5044, ticked GlobalSystem / Inputs
Create an API token for the graylog-sidecar userSystem / Sidecars → Administration

Download the Sidecar installer (the .exe) from Graylog's GitHub releases, matching the version to your server. Install it interactively, or silently from an elevated prompt:

Silent install (elevated PowerShell / CMD)
graylog_sidecar_installer_x.x.x-1.exe /S ^ -SERVERURL=http://your-graylog-ip:9000/api ^ -APITOKEN=your-sidecar-api-token
Register & start the service
& "C:\Program Files\Graylog\sidecar\graylog-sidecar.exe" -service install & "C:\Program Files\Graylog\sidecar\graylog-sidecar.exe" -service start
ℹ  The only values you must set are server_url (it has to end in /api) and server_api_token in C:\Program Files\Graylog\sidecar\sidecar.yml. Registration only succeeds when the host can reach the REST API on port 9000.
06 — Windows: Configure the Winlogbeat Collector

Back in Graylog the host now appears under System / Sidecars. Create (or reuse) a Winlogbeat configuration that reads the Windows event channels and ships them to your Beats input. The two fields lines at the top are required for Graylog to attribute messages to the right collector.

Winlogbeat collector configuration (in the Graylog UI)
# Needed for Graylog fields_under_root: true fields.collector_node_id: ${sidecar.nodeName} fields.gl2_source_collector: ${sidecar.nodeId} output.logstash: hosts: ["your-graylog-ip:5044"] winlogbeat.event_logs: - name: Application level: critical, error, warning ignore_older: 48h - name: System level: critical, error, warning ignore_older: 48h - name: Security level: critical, error, warning, information ignore_older: 48h

Assign the configuration to the host's Winlogbeat collector and click Start. Within a minute the Sidecar generates the local config, launches Winlogbeat, and Windows events begin landing in Graylog's Search.

ℹ  The output.logstash block is correct even though you created a "Beats" input — Beats and the Logstash output speak the same Lumberjack protocol. If you also run Sysmon, add a channel line - name: Microsoft-Windows-Sysmon/Operational to capture it.
⚠  Editing a Sidecar configuration in Graylog applies the change to every host that shares that configuration's tag. Use distinct tags (e.g. windows-servers vs workstations) if different machines need different channels or filters.
07 — macOS: Forward via syslogd

macOS keeps its modern logs in the unified logging system, but the classic BSD syslog daemon still runs and is the simplest bridge to Graylog. Point it at the same Syslog input the Linux hosts use (port 5140). Edit the syslog configuration and add a forwarding rule.

/etc/syslog.conf — add a forwarding line
# Forward everything to Graylog over UDP *.* @your-graylog-ip:5140
Reload syslogd
sudo launchctl kickstart -k system/com.apple.syslogd logger "hello from $(hostname) macOS to graylog"

For more than the basic facilities, install rsyslog via Homebrew (brew install rsyslog) and use the exact same RFC 5424 or GELF configs shown in the Linux sections — the rsyslog config syntax is identical across platforms.

ℹ  To capture the richer unified-log stream rather than just legacy syslog facilities, you can pipe log stream output into a script that posts to a GELF HTTP input. That's an application-level integration rather than a daemon config, but it's the route to Apple's structured logs.
08 — Verify & Troubleshoot
SymptomCheck
No messages at allInput running & Global? Compose port published (not bound to 127.0.0.1)? Host firewall open?
Input shows 0 receivedClient port/protocol must match the input exactly (UDP vs TCP, 5140 vs 12201)
Windows host absentSidecar can't reach server_url (must end in /api on port 9000); token valid?
Test a UDP syslog inputecho "<34>test" | nc -u -w1 your-graylog-ip 5140
Watch the input liveSystem / Inputs → the input's "Received messages" / "Show received messages"
Confirm the listener inside the container
docker compose exec graylog curl -s http://localhost:9000/api/system/inputstates \ | head -c 400
09 — Reference: Ports & Files
ItemValue
Web & REST API9000/tcp
Syslog input5140/udp + 5140/tcp
GELF input12201/udp + 12201/tcp
Beats input (Sidecar)5044/tcp
Linux rsyslog drop-in/etc/rsyslog.d/90-graylog.conf
Windows Sidecar configC:\Program Files\Graylog\sidecar\sidecar.yml
macOS syslog config/etc/syslog.conf