Syslog-ng messages to bash script
I am falling more and more in love with syslog-ng. After some trial and error I’ve finally configured to parse messages and send them to zabbix for statistics logging. Sounds cool uh? Well it is.
Of course the posibilities are endless when you think about it. For me it is just sake to get performance messages from our application into zabbix to get triggered about problems.
Read further to found out how I did it
First you have to define the destination in your syslog-ng.conf
destination d_syslog2zbx_myservice {
program(‘/opt/syslog-ng/scripts/syslog2zbx.sh zonecampaigncontrol’ template(“myservice $HOST $MSG\n”));
};
As you can see I define an application with one parameter (I don’t use it in the script but for finding the application it is handy). Secondly I define the template (how I would like the messages to be sended) as you can see I prefix it with a name (myservice) followed by the hostname and the message.
Secondly I have a script
#!/bin/bash
# Limit memory allocation
ulimit -v 50000
umask 0077ZBXSERVER=zabbix.local
PORT=10051
LOGFILE=/var/log/syslog2zbx.logfunction log
{
echo “[$$] $@” >> ${LOGFILE}
}log “Started syslog2zbx” &
log “Memory Limit: `ulimit -v`” &
log “Local time: `/bin/date`”
log “Starting read loop” &
while read type host input; dolog “Got line of type ${type}” &
case “${type}” in
myservice)
TMPFILE=`mktemp /tmp/syslog2zbx.XXXXXXXX`
while read line; do
FIELD=”`echo ${line} | cut -d: -f1`”
echo “${host}.local ${type}.`echo ${line} | sed ’s/:/ /g’`” >> ${TMPFILE}
done < <( echo $input | sed -e 's/^ *[^ ]* //' | sed 's/, /,/g' | tr ',' '\n')echo "${host}.local ${type}.logmessage $input" >> ${TMPFILE}
/usr/sbin/zabbix_sender -v -i ${TMPFILE} -z ${ZBXSERVER}
rm -f ${TMPFILE}
unset TMPFILE
;;# Write the rest to a tempfile
*)
log “Undefined type found: ${type}” &
log “Host: ${host}” &
log “Message:” &
log “${input}” &
;;
esac
doneexit 0
The trick is to use the read syntax correctly. Syslog-ng pipes all the messages to the script. Therefore you don’t have any arguments. Myservice is normally a line which is comma seperated. I do some magic to transform it to something easier to parse. It’s totally up to you how you handle it.
Third thing you have to do is add the destination to your log statement in syslog-ng.conf
log {
source(s_udp);
filter(f_myservice);
destination(d_syslog2zbx_myservice);
};
As you can see I filter every message to see if it matches with myservice. Secondly it only parses messages which come on over udp. If both criteria are matched I send it to my destination which is the script.
The rest is totally up to you how you handle it. Of course you can pipe it to a python/perl/php/c++ application. I’ll stick to bash but the possibilities are endless.