The syslog daemon typically shipped with Unix systems is somewhat inflexible, only providing for logging to text files on the drive. Syslog-ng, as it's name implies, is the "next generation" of syslog daemons. Two of the concepts in syslog-ng that you’ll be using are 'templates' for your data, and extremely flexible 'destination' configuration.
First, you need to modify the syslog-ng.conf (usually in /etc/syslog-ng or /usr/local/etc/syslog-ng). Add the destination and the template for the Postgres database:
destination d_pgsql {
pipe("/tmp/.syslogd.pipe"
template("INSERT INTO syslog (ip, facility, priority, level, tag, date,time, program, msg) VALUES
( '$HOST', '$FACILITY', '$PRIORITY', '$LEVEL', '$TAG','$YEAR-$MONTH-
$DAY', '$HOUR:$MIN:$SEC', '$PROGRAM', '$MSG' );\n") template-escape(yes) owner("root") group("c-syslog") perm(0660));
};
Keep in mind that this can be used with any SQL client that is available on the system on which you've configured syslog-ng, so make sure that your SQL is valid for that particular RDBMS.
Next, configure the source/destination of the syslog to allow traffic via the network:
source net { udp(); };
Configure this to go to the previously configured destination:
log { source(net); destination(d_pgsql); };
Don't start or restart your running syslog-ng yet.
Script Configuration
On Unix systems, the fifo file type provides a way to ensure that the first amount of data sent into the file comes out first and so on. In this section, you'll create a fifo that will be writable via the syslog-ng process, running as root, and readable by a user in a group to send the syslog data to your RDBMS.
Create a user on your system (usually adduser or useradd) and call it c-syslog. It's not absolutely necessary to give the user a passwordif no password is set, nobody can log in as that user. Also create a syslog group, and put the c-syslog user into the syslog group.
To create a fifo, use the mkfifo command and run mkfifo /tmp/.syslogd.pipe. Set permissions on the fifo by using chmod 660 /tmp/.syslogd.pipe, then set chown root:syslog /tmp/.syslogd.pipe. Finally, type lsal /tmp/.syslogd.pipe to make sure it was created properly:
prw-rw---- 1 root c-syslog 0 May 4 13:20 /tmp/.syslogd.pipe
Next, you'll need a simple looping script. Cut and paste these contents and create a file in
/usr/local/bin, call it
syslog-db.sh, save it, and run
chmod 755 syslog-db.sh:
#!/bin/bash
PIPE="/tmp/.syslogd.pipe";
if [ -e ${PIPE} ]; then
while [ -e ${PIPE} ]
do
# Edit this line to work with your sql client of choice.
/usr/local/pgsql/bin/psql -q -h syslog < ${PIPE} > /dev/null 2>&1
done
else
# Since some systems clean out /tmp on bootup, you would
# probably want to include the steps to automatically re-create
# the fifo here, but since those steps vary a bit, i haven't
# included them. Assuming you followed my instructions above
# they'd look like this:
# mkfifo /tmp/.syslogd.pipe
# chmod 660 /tmp/.syslogd.pipe
# chown root:syslog /tmp/.syslogd.pipe
echo “ERROR: fifo not created in ${PIPE}. Please create.”
exit(1)
fi
Change
<dbhost> to reflect the host on your network running Postgres. It's important to not restart syslog-ng or start running the looping script mentioned aboveuntil everything is ready.