Various documentation and example apps for sending logs to Graylog via syslog.
Note that in most situations it would be preferable to send logs to Graylog as Graylog Extended Log Format (GELF) messages; this repository is only for when the logs must be sent as syslog messsages.
If you want to see the log messages that are being sent, a quick way is to use netcat to listen on a local port and dump the logs to the console; this is also helpful for troubleshooting if, for example, the timestamp in the log is improperly formatted (which may make it difficult to find the log in Graylog):
nc -klu 5140
Or for TCP:
nc -kl 5140
Alternatively, see below for setting up a test Graylog server.
-
Clone this repo: https://github.com/Graylog2/docker-compose/
-
Create .env file
cd open-core cp .env.example .env
-
Set
GRAYLOG_PASSWORD_SECRET
andGRAYLOG_ROOT_PASSWORD_SHA2
in the .env file according to the instructions in the file -
Set the time zone for the admin user
This will allow you to do searches in Graylog in your local timezone as the admin user
-
Add this line to the
.env
file you created:GRAYLOG_ROOT_TIMEZONE: '...'
Replace
...
with a valid timezone from http://joda-time.sourceforge.net/timezones.html; copy the value from Canonical ID, e.g.America/New_York
-
-
Start the server
docker-compose up
-
Login using a user name of
admin
and whatever value you used when you setGRAYLOG_ROOT_PASSWORD_SHA2
-
Add a new syslog input
-
System / Inputs (click the hamburger menu if you don't see it) > Inputs
-
Select input > Syslog UDP > Launch new input
-
Set the Port to
5140
(this port is already pre-configured in the docker-compose file) -
Check Store full message (this will help troubleshooting)
-
Save
-
-
Send some syslog logs to localhost on port 5140/udp (see one of the provided test apps)
-
Go to Search to see any logs you send to the server
- You can see the full message under
full_message
as needed
- You can see the full message under
TCP offers a lot of advantages over UDP, however there's a catch when sending syslog messages to Graylog over TCP: by default, the Graylog TCP input will split logs on the newline ('\n') character, splitting any multi-line messages into separate logs.
This is controlled by the use_null_delimiter
setting in the Syslog TCP input. When set to false
(the default), Graylog will split messages on the newline character. When set to true
, Graylog will split messages on the null character (\0
). However, in my testing, setting use_null_delimiter: true
caused logs that weren't terminated with a null character to not show in Graylog at all (regardless of the number of lines in the log).
Here are a few possible options to deal with this:
-
Send logs to the Syslog UDP input
-
Or set
use_null_delimiter: true
in the Syslog TCP input and make sure they're null-terminated-
e.g. Winston can do this by using this setting in the syslog transport:
eol: '\0',
-
-
Alternatively, set
use_null_delimiter: false
in the Syslog TCP input and use a different separator between lines. Unfortunately, I haven't found a separator that shows up as proper newlines in the Graylog UI as it does when sending over UDP. Separators such as\r
and\u2028
get converted to spaces.
Some syslog clients may give the option of sending logs formatted as BSD (RFC 3164) or RFC 5424 messages. Always prefer RFC 5424 when possible, because it has the following advantages:
- More accurate timestamps, including milliseconds and timezone
- More fields, including application name, process ID, message ID, structured data (custom fields)
The biggest painpoint when sending BSD-formatted messages to Graylog is the timestamp:
- Because there's no time zone, Graylog will always assume logs are sent with a UTC time zone
- Because there are no milliseconds, logs will likely be out of order
Here is an example of a BSD-formatted syslog message (generated using log4j2 without format
):
<131>Sep 27 11:33:14 localhost Test error message, without stack trace
Here is an example of the same message formatted according to RFC 5424 (generated using log4j2 with format="RFC5424"
):
<131>1 2021-09-27T11:33:14.564-04:00 localhost testlog4j2 56903 - [mdc@18060 category="App" exception="" priority="ERROR" thread="main"] Test error message, without stack trace
Given the sample RFC 5424 above, here is how Graylog will parse it:
- The first part (in angle brackets) is the syslog facility, which gets set to these fields in Graylog:
facility
,facility_num
, andlevel
- After that should be a
1
, which tells Graylog that the message adheres to syslog protocol version 1 (RFC 5424) - The next field is the timestamp, which Graylog parses providing that it's properly formatted
- Next field is the hostname, set to the
source
field in Graylog - Next field is the application name, set to the
application_name
field in Graylog - Next field is the process ID, set to the
process_id
field in Graylog - Next field is the message ID, which above is empty (
-
is an empty value in syslog; see NILVALUE) - If structured data is present, each item will each get parsed as fields in Graylog
- Everything else gets set to the
message
field in Graylog