syslog-ng
Practical syslog-ng guide for Gentoo Linux covering installation, filtering, templates, network logging (UDP/TCP), testing with logger and netcat, and integrating Apache logs for centralized log management
Send UDP Test Message
nc -w0 -u 192.168.1.102 514 <<< "testing again from my home machine"
echo hi |nc -w0 -u 78.69.211.116 1337
Install syslog-ng
echo "app-admin/syslog-ng http geoip2 ipv6 json python smtp spoof-source -systemd test" \
> /etc/portage/package.use/syslog-ng
emerge app-admin/syslog-ng
Here is my personal syslog-ng.conf 2026-02-11 and it will store sshd stuff to sshd.log and openwrt to openwrt.log
@version: 4.10
@include "scl.conf"
###########################################################################
# Templates
###########################################################################
template template_date_format {
template("[${YEAR}-${MONTH}-${DAY} | ${HOUR}:${MIN}:${SEC} | ${HOST}]: ${MSG}\n");
template_escape(no);
};
###########################################################################
# Global options
###########################################################################
options {
threaded(yes);
chain_hostnames(no);
keep_hostname(yes);
create_dirs(yes);
owner("wuseman");
group("wuseman");
perm(0644);
dir_owner("wuseman");
dir_group("wuseman");
dir_perm(0755);
stats(freq(43200));
};
###########################################################################
# Sources
###########################################################################
source s_local {
system();
internal();
};
source s_openwrt_udp {
network(
transport("udp")
port(514)
);
};
###########################################################################
# Destinations
###########################################################################
destination d_messages {
file("/var/log/messages"
template(template_date_format)
persist-name("messages_main"));
};
destination d_openwrt_log {
file("/var/log/openwrt.log"
template(template_date_format)
persist-name("openwrt_combined"));
};
destination d_sshdlog {
file("/var/log/sshd.log"
template(template_date_format)
owner("root") group("root") perm(0640)
persist-name("sshd_all"));
};
destination console_all { file("/dev/tty12"); };
destination console { usertty("root"); };
###########################################################################
# Filters
###########################################################################
filter f_sshd_all {
program("^sshd$") or program("^sshd-session$");
};
filter f_emergency { level(emerg); };
###########################################################################
# Log paths
###########################################################################
# 1) SSH logs → sshd.log
log {
source(s_local);
filter(f_sshd_all);
destination(d_sshdlog);
};
# 2) OpenWrt UDP logs → openwrt.log
log {
source(s_openwrt_udp);
destination(d_openwrt_log);
};
# 3) Everything else local → messages
log {
source(s_local);
destination(d_messages);
};
# 4) Console
log { source(s_local); destination(console_all); };
log { source(s_local); filter(f_emergency); destination(console); };
And then trigger the new dates for a specifik log as example by add template(template_date_format)); after the log name
destination d_auth { file("/var/log/auth.log" template(template_date_format)); };
Selecting messages using the in-list filter
Create a text file that contains the programs (as in the ${PROGRAM} field of their log messages) you want to select. For example, you want to forward only the logs of a few applications from a host: kernel, sshd, and sudo.
cat << "EOF" > /etc/syslog-ng/programlist.list
kernel
sshd
sudo
EOF
The following filter selects only the messages of the listed applications
filter f_whitelist { in-list("/etc/syslog-ng/programlist.list", value("PROGRAM")); };
Create the appropriate sources and destinations for your environment, then create a log path that uses the previous filter to select only the log messages of the applications you need
log {
source(s_all);
filter(f_whitelist);
destination(d_logserver); };
To create a blacklist filter, simply negate the in-list filter:
filter f_blacklist { not in-list("/etc/syslog-ng/programlist.list", value("PROGRAM")); };
Using the hook-commands() with a network source
In the following example, the hook-commands() is used with the network() driver and it opens an iptables port automatically as syslog-ng OSE is started/ stopped.
The assumption in this example is that the LOGCHAIN chain is part of a larger ruleset that routes traffic to it. Whenever the syslog-ng OSE created rule is there, packets can flow, otherwise the port is closed.
source {
network(transport(udp)
hook-commands(
startup("iptables -I LOGCHAIN 1 -p udp --dport 514 -j ACCEPT")
shutdown("iptables -D LOGCHAIN 1")
)
);
};
Simple configuration file for syslog-ng
@version: 3.19
source s_local {
unix-dgram("/dev/log"); internal();
};
destination d_file {
file("/var/log/messages_syslog-ng.log");
};
log {
source(s_local); destination(d_file);
};
Default syslog-ng.conf (Gentoo)
@version: 4.1
#
# Syslog-ng default configuration file for Gentoo Linux
# https://bugs.gentoo.org/426814
@include "scl.conf"
options {
threaded(yes);
chain_hostnames(no);
# The default action of syslog-ng is to log a STATS line
# to the file every 10 minutes. That's pretty ugly after a while.
# Change it to every 12 hours so you get a nice daily update of
# how many messages syslog-ng missed (0).
stats(freq(43200));
# The default action of syslog-ng is to log a MARK line
# to the file every 20 minutes. That's seems high for most
# people so turn it down to once an hour. Set it to zero
# if you don't want the functionality at all.
mark_freq(3600);
};
source src { system(); internal(); };
destination messages { file("/var/log/messages"); };
# By default messages are logged to tty12...
destination console_all { file("/dev/tty12"); };
# ...if you intend to use /dev/console for programs like xconsole
# you can comment out the destination line above that references /dev/tty12
# and uncomment the line below.
#destination console_all { file("/dev/console"); };
log { source(src); destination(messages); };
log { source(src); destination(console_all); };
Simple config for network server
@version:4.1
source s_tcp { tcp(port(514)); };
destination d_file { file("/var/log/fromnet"); };
log { source(s_tcp); destination(d_file); };
Stop the running syslog implementation and start syslog-ng with this configuration in the foreground with debug information enabled
/etc/init.d/syslog-ng stop
syslog-ng -F -f /etc/syslog-ng/syslog-ng.conf
Using logger with a network source for test our configuration
| OPTIND | Description |
|---|---|
| -T | TCP |
| -n | Hostname/IP |
| -P | Port |
Send Log Message
logger -T -n 127.0.0.1 -P 514 this is a test message
Start syslog-ng
/etc/init.d/syslog-ng
Get syslog-ng version
syslog-ng -V | grep "Config version:" | cut -d ':' -f 2 | sed -e 's/^[ \t]*//'
Display version and settings
syslog-ng -V
Run as user
syslog-ng --user <user> --group <group>
Use hostname instead of ipaddresses
use_dns=yes
Log message to stderr
syslog-ng --stderr
Set log level
syslog-ng --log-level <verbose|debug|trace>
Display module information
syslog-ng --module-registry
Network
How the network sources should be configured depends also on the capabilities of your client hosts: many older networking devices support only the legacy BSD-syslog protocol (RFC3164) using UDP transport
source s_network {
syslog(ip(10.1.2.3) transport("udp"));
};
However, if possible, use the much more reliable TCP transport:
source s_network {
syslog(ip(10.1.2.3) transport("tcp"));
};
If you want to create separate logfiles for every client host, use the ${HOST} macro when specifying the filename, for example:
Create a log statement connecting the sources to the local destinations
log {
source(s_local); source(s_network); destination(d_local);
};
Minimal server config with remote support
@version: 4.1
#
# Syslog-ng default configuration file for Gentoo Linux
@include "scl.conf"
options {
threaded(yes);
chain_hostnames(no);
stats(freq(43200));
mark_freq(3600);
keep-hostname(yes);
time-reap(30);
};
source s_local { system(); internal();}; # syslog-ng | local
source s_network { syslog(ip(192.168.1.64) transport("tcp"));}; # syslog-ng | network
destination messages { file("/var/log/messages"); }; # destination local
destination d_local { file("/var/log/messages_${HOST}");}; # destination remote
destination console_all { file("/dev/tty12");};
destination d_logs {
file(
"/var/log/messages"
owner("root")
group("root")
perm(0777)
);
};
log { source(s_local); source(s_network); destination(d_local); destination(d_logs); destination(console_all);}
Apache HTTP Server with syslog-ng
Here is a very quick and easy way to get your Apache2 logs into syslog-ng so you can send them to a central log server or a remote logging server for security in case of a breach.
Generate source for all apache2 logs in commandline
ls -1 /var/log/apache2/ | \
sed 's/^/ file("\/var\/log\/apache2\//;s/$/" follow_freq(1) flags(no-parse));/g'
for i in `find /var/log/apache2/ -type d`; do
echo "file(\"$i/access.log\" flags(no-parse) program-override(\"apache2\"));";
done;
Define a new source that essentially 'tails' the apache logs
source s_apache2 {
file("/var/log/apache2/access_log" flags(no-parse));
file("/var/log/apache2/error_log" flags(no-parse));
file("/var/log/apache2/referer_log" flags(no-parse));
file("/var/log/apache2/ssl_access_log" flags(no-parse));
file("/var/log/apache2/ssl_error_log" flags(no-parse));
file("/var/log/apache2/ssl_request_log" flags(no-parse));
file("/var/log/apache2/userAgent_log" flags(no-parse));
};
log { source(s_src); destination(loghost); };
log { source(s_apache2); destination(loghost); };
Resource(s)