syslog-ng

syslog-ng is a syslog implementation which can take log messages from sources and forward them to destinations, based on powerful filter directives.

Note: With systemd's journal, syslog-ng is not needed by most users.

Overview

syslog-ng takes incoming log messages from defined 'sources' and forwards them to the appropriate destinations, based on powerful filter directives. In a typical simple set-up, syslog-ng will read messages from three sources:

  1. the default /dev/log device, where most logs are sent
  2. syslog-ng "internal" log messages
  3. /proc/kmsg kernel messages

Sources are defined using the "source" directive. These incoming messages are then filtered according to defined filters ("filter" keyword), i.e. according to originating program or log level, and sent to the appropriate "destination". Destinations include log files (e.g. /var/log/messages.log), printing messages on a console and remote servers. The pivotal function is log. This function defines which filters should be applied to a certain source, and where the resulting messages should be sent to.

Installation

Install the syslog-ng package.

To use syslog-ng, start/enable syslog-ng@default.service.

systemd/journald integration

syslog-ng pulls in the messages from the systemd journal by default. Keeping ForwardToSyslog=no in is recommended in order to avoid the overhead associated with the socket and to avoid needless error messages in the log. If on the other hand you do not want to store your logs twice and turn journald's , you will need , as syslog-ng tries to follow the 'journald' journal file.

See #syslog-ng and systemd journal for more details.

Sources

syslog-ng receives log messages from a source. To define a source you should follow the following syntax:

source <identifier> { source-driver(params); source-driver(params); ... };

You can look at the identifiers and source-drivers in the official manuals. This will follow the manual to explain the configuration file above. The unix-stream() source-driver opens the given AF_UNIX socket and starts listening on it for messages. The internal() source-driver gets messages generated by syslog-ng.

Therefore, the following means: gets messages from the /dev/log socket and syslog-ng.

source src { unix-stream("/dev/log"); internal(); };

The kernel sends log messages to /proc/kmsg and the file() driver reads log messages from files. Therefore, the following means: kernsrc gets messages from file /proc/kmsg

source kernsrc { file("/proc/kmsg"); };

In the default configuration file after emerging syslog-ng, the source is defined as:

source src { unix-stream("/dev/log"); internal(); pipe("/proc/kmsg"); };

Reading messages by pipe("/proc/kmsg") gives a better performance but because it opens its argument in read-write mode can be a security hazard as the syslog-ng admin guide states:

"Pipe is very similar to the file() driver, but there are a few differences, for example pipe() opens its argument in read-write mode, therefore it is not recommended to be used on special files like /proc/kmsg." (You can follow this discussion in this post.)

To open a port to read data from a remote server a source must be defined with this syntax:

source s_net { udp(); };

for UDP or

source s_net { tcp(); };

to receive log messages via TCP. Both listen on port 514.

syslog-ng and systemd journal

Starting with syslog-ng version 3.6.1 the default source on Linux systems using systemd uses journald as its standard source.

If you wish to use both the journald and syslog-ng, ensure the following settings are in effect. For systemd-journald, in the file, either set to or unset (which defaults to auto) and set to . For /etc/syslog-ng/syslog-ng.conf, you need the following stanza:

If, on the other hand, you wish not to retain the journald logs, but only syslog-ng's text logs, set in . This will store journald in ram. As of syslog-ng 3.6.3, syslog-ng is using journald as the system(); source so if you set , the systemd journal will drop all messages and not forward them to syslog-ng.

After the change restart the and syslog-ng@default.service daemons.

Destinations

In syslog-ng, log messages are sent to files. The syntax is very similar to sources:

destination <identifier> {destination-driver(params); destination-driver(params); ... };

You will be normally logging to a file, but you could log to a different destination-driver: pipe, Unix socket, TCP-UDP ports, terminals or to specific programs. Therefore, this means sending authlog messages to /var/log/auth.log:

destination authlog { file("/var/log/auth.log"); };

If the user is logged in, sends messages to the terminal of the specified user. If you want to send console messages to root's terminal if it is logged in:

destination console { usertty("root"); };

Messages can be sent to a pipe with . The following sends xconsole messages to the pipe . This needs some more configuration, so you could look at the sub-section xconsole below.

destination xconsole { pipe("/dev/xconsole"); };

To send messages on the network, use . The following will send your log data out to another server.

destination remote_server { udp("10.0.0.2" port(514)); };

Creating Filters for Messages

The syntax for the filter statement is:

filter <identifier> { expression; };

Functions can be used in the expression, such as the function which selects messages based on the facility codes. The Linux kernel has a few facilities you can use for logging. Each facility has a log-level; where debug is the most verbose, and panic only shows serious errors. You can find the facilities, log levels and priority names in . To filter those messages coming from authorization, like May 11 23:42:31 mimosinnet su(pam_unix)[18569]: session opened for user root by (uid=1000), use the following:

filter f_auth { facility(auth); };

The facility expression can use the boolean operators , , and not, so the following filter selects those messages not coming from authorization, network news or mail:

filter f_debug { not facility(auth, authpriv, news, mail); };

The function level() selects messages based on its priority level, so if you want to select informational levels:

filter f_info { level(info); };

Functions and boolean operators can be combined in more complex expressions. The following line filters messages with a priority level from informational to warning not coming from auth, authpriv, mail and news facilities:

filter f_messages { level(info..warn) and not facility(auth, authpriv, mail, news); };

Messages can also be selected by matching a regular expression in the message with the function . For example:

filter f_failed { match("failed" value("MESSAGE")); };

here is a list of templates :

 "AMPM", "BSDTAG", "DATE, C_DATE, R_DATE, S_DATE", "DAY, C_DAY, R_DAY, S_DAY", "FACILITY", "FACILITY_NUM", "FULLDATE, C_FULLDATE, R_FULLDATE, S_FULLDATE", "FULLHOST", "FULLHOST_FROM", "HOUR, C_HOUR, R_HOUR, S_HOUR", "HOUR12, C_HOUR12, R_HOUR12, S_HOUR12", "HOST", "HOST_FROM", "ISODATE, C_ISODATE, R_ISODATE, S_ISODATE", "LEVEL_NUM", "LOGHOST", "MIN, C_MIN, R_MIN, S_MIN", "MONTH, C_MONTH, R_MONTH, S_MONTH", "MONTH_ABBREV, C_MONTH_ABBREV, R_MONTH_ABBREV, S_MONTH_ABBREV", "MONTH_NAME, C_MONTH_NAME, R_MONTH_NAME, S_MONTH_NAME", "MONTH_WEEK, C_MONTH_WEEK, R_MONTH_WEEK, S_MONTH_WEEK", "MSEC, C_MSEC, R_MSEC, S_MSEC", "MSG or MESSAGE", "MSGHDR", "MSGID", "MSGONLY", "PID", "PRI", "PRIORITY or LEVEL", "PROGRAM", "SDATA, .SDATA.SDID.SDNAME", "SEC, C_SEC, R_SEC, S_SEC", "SOURCEIP", "SEQNUM", "STAMP, R_STAMP, S_STAMP", "SYSUPTIME", "TAG", "TAGS", "TZ, C_TZ, R_TZ, S_TZ", "TZOFFSET, C_TZOFFSET, R_TZOFFSET, S_TZOFFSET", "UNIXTIME, C_UNIXTIME, R_UNIXTIME, S_UNIXTIME", "USEC, C_USEC, R_USEC, S_USEC", "YEAR, C_YEAR, R_YEAR, S_YEAR", "WEEK, C_WEEK, R_WEEK, S_WEEK", "WEEK_ABBREV, C_WEEK_ABBREV, R_WEEK_ABBREV, S_WEEK_ABBREV", "WEEK_DAY, C_WEEK_DAY, R_WEEK_DAY, S_WEEK_DAY", "WEEKDAY, C_WEEKDAY, R_WEEKDAY, S_WEEKDAY", "WEEK_DAY_NAME, C_WEEK_DAY_NAME, R_WEEK_DAY_NAME, S_WEEK_DAY_NAME".

To filter messages received from a particular remote host, the function must be used:

filter f_host { host( "192.168.1.1" ); };

Log Paths

syslog-ng connects sources, filters and destinations with log statements. The syntax is:

log {source(s1); source(s2); ...
filter(f1); filter(f2); ...
destination(d1); destination(d2); ...
flags(flag1[, flag2...]); };

The following for example sends messages from source to destination filtered by filter.

log { source(src); filter(f_mail); filter(f_info); destination(mailinfo); };

Tips and Tricks

After understanding the logic behind syslog-ng, many possible and complex configuration are possible. Here there are some examples.

Have syslog-ng reload the configuration file

You can make syslog-ng re-evaluate the configuration file. You can do so manually by sending a to the process, or reload syslog-ng@default.service.

Failover Logging to Remote Host

This setup shows how to send the default unencrypted syslog packets across both TCP and UDP protocols, using the standard port (514) and an alternate port. This is sending the same output to the same machine 4 different ways to try and make sure packets make it. Mostly useful if you are debugging a remote server that fails to reboot. The different ports and protocols are to make it past any firewall filters or other network problems. Also useful for port-forwarding and using tunnels. Something like this setup is ideal to tunnel across an ssh connection that the prone-to-failover host initiates through a reverse connection.

And then on the loghost receiving these logs:

Move log to another file

In order to move some log from to another file:

Configuring as a loghost

Configuring your system to be a loghost is quite simple. Drop the following into your configuration, and create the needed directory. With this simple configuration, log filenames will be based on the FQDN of the remote host, and located in /var/log/remote/. After creating the remote directory, reload your syslog-ng configuration.

source net { udp(); };
destination remote { file("/var/log/remote/${FULLHOST}-log"); };
log { source(net); destination(remote); };

Improve Performance

syslog-ng's performance can be improved in different ways:

Write every so often

It seems that the old option is called now, where the writing to the file is buffered for lines. Default is 0 (no buffering).

Avoid redundant processing and disk space

A single log message can be sent to different log files several times. For example, in the initial configuration file, we have the following definitions:

The same message from the facility will end up in both the and files. To change this behavior we can use the flag, ending up further processing with the message. Therefore, in this example, if we want messages from the facility not ending up in the messages file, we should change the cron's log sentence by:

 log { source(src); filter(f_cron); destination(cron); flags(final); };

another way is to exclude the facility from filter:

 filter f_messages { level(info..warn) and not facility(cron, auth, authpriv, mail, news); };

PostgreSQL Destination

This section will use two roles: syslog and . syslog will be the administrator of the database syslog and will only be able to add records to the logs table.

No longer needed to create table for logs. syslog-ng will create automatically.

psql -U postgres
postgres=# CREATE ROLE syslog WITH LOGIN;
postgres=# \password syslog    # Using the \password function is secure because
postgres=# CREATE ROLE logwriter WITH LOGIN;
postgres=# \password logwriter # the password is not saved in history.
postgres=# CREATE DATABASE syslog OWNER syslog;
postgres=# \q # You are done here for the moment

Edit to allow syslog and to establish a connection to PostgreSQL.

Then reload .

Edit /etc/syslog-ng/syslog-ng.conf so that it knows where and how to write to PostgreSQL. syslog-ng will utilize the role.

Finally, restart .

And check to see if things are being logged.

psql -U logwriter -d syslog
syslog=> SELECT * FROM <your table name> ORDER BY datetime DESC LIMIT 10;

ISO 8601 timestamps

Before :

#logger These timestamps are not optimal.
#tail -n 1 /var/log/messages.log
Feb 18 14:25:01 hostname logger: These timestamps are not optimal.
#

Add to /etc/syslog-ng/syslog-ng.conf in the options section. Example:

options {
  stats_freq (0);
  flush_lines (0);
  time_reopen (10);
  log_fifo_size (1000);
  long_hostnames(off); 
  use_dns (no);
  use_fqdn (no);
  create_dirs (no);
  keep_hostname (yes);
  perm(0640);
  group("log");
  ts_format(iso);      #make ISO-8601 timestamps
  #frac-digits(3);     #optional time to nearest millisecond 
};

Then reload .

After :

#logger Now THAT is a timestamp!
#tail -n 2 /var/log/messages.log
Feb 18 14:25:01 hostname logger: These timestamps are not optimal.
2010-02-18T20:23:58-05:00 electron logger: Now THAT is a timestamp!
#

RFC 3339 timestamps

Same as above, except use instead of iso for

Log Levels

Log levels are defined separately for each logged facility in syslog-ng config. Available log levels are listed in /usr/include/sys/syslog.h :

define LOG_EMERG       0       /* system is unusable */
define LOG_ALERT       1       /* action must be taken immediately */
define LOG_CRIT        2       /* critical conditions */
define LOG_ERR         3       /* error conditions */
define LOG_WARNING     4       /* warning conditions */
define LOG_NOTICE      5       /* normal but significant condition */
define LOG_INFO        6       /* informational */
define LOG_DEBUG       7       /* debug-level messages */

Macros and Variables

Macros can be used in both templates, and in destination file names. Macros of syslog-ng OSE.

The following code will write the log lines to in the format of .

You can create your own value list as below once syslog-ng is restarted with: tail /var/log/test.log|tr "@" "\n"

Receive and parse common syslog messages

Starting from version 3.16 syslog-ng is capable to receive and parse messages on the most common ports with the most common parsers using the default-network-drivers() source driver.

  • Default listening ports:
    • 514, both TCP and UDP, for RFC3164 (BSD-syslog) formatted traffic
    • 601 TCP, for RFC5424 (IETF-syslog) formatted traffic
    • 6514 TCP, for TLS-encrypted traffic
  • Automatic parsers:
    • RFC3164 message parser
    • RFC5424 message parser
    • Cisco parser
    • Structured EWMM parser
    • Other application adapters (Splunk Common Information Model (CIM), iptables, or sudo)

See Also

  • Netconsole A kernel module that sends all kernel log messages (i.e. dmesg) over the network to another computer, without involving user space (e.g. syslogd).
gollark: I know of at least two ways to do this.
gollark: Ah, of course, you memetically encoded your entry into an image.
gollark: 1. do thing2. verify thing is done3. ???4. profit
gollark: > exercise
gollark: Gibson (monoid).
This article is issued from Archlinux. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.