sammybaby
15-02-2005, 21:17
(thanks to Spaceelk on the #zabbix IRC channel for the help. :) )
I run mail services on a Debian server running Exim 4, exiscan, SpamAssassin, and ClamAV. My boss is always asking for statistics on our mail server, and while I've had good luck generating reports with existats, I thought that a better graphical representation might be more useful to him. As you've probably guessed, I thought of Zabbix.
The key to getting custom data into Zabbix is to generate a shell command which will return a simple number. I couldn't think of one which would pull the data I needed directly from Exim's mainlog, so I decided to go with an intermediate step: a daemon to follow the mainlog and insert relevant data into a MySQL database.
First: I use a "check_data" acl with exiscan to scan for viruses, spam, and relaying rules. For the purposes of analysis, there are only five categories of messages I'm interested in:
messages rejected for spam content ("spamrejected")
messages delivered, but marked as spam ("spamdelivered")
messages rejected for virus/malware content ("virus")
messages rejected because of relaying rules ("relayrejected")
all messages delivered, period ("delivered")
Each type of message generates a unique log entry: I use a perl script to tail the exim log, then insert a row into the table with the relevant data. Here's a snippet:
...
elsif( $entrydata =~ m/.*This message contains a virus.*/ ) {
$messageType = "virus";
}
...
$sql = "INSERT INTO log_entry SET timestamp='$date $time', messageID='$messageID', message_type='$message_type'";
...
Next, I needed a utility that could find and count up the entries I wanted. Again, a little perl script was called for.
...
# Usage: exim_sqlscan -t<entrytype> -i<interval_in_minutes>
...
$sql = "SELECT count(*) as count FROM log_entry where timestamp >= DATE_SUB(NOW(
), INTERVAL $opt_i minute) AND message_type = '$opt_t' GROUP BY message_type";
...
And, lastly, a few entries in zabbix_agentd.conf:
...
UserParameter=exim[deliveredminute],/usr/local/bin/exim_sqlscan -t delivered -i 1
...
UserParameter=exim[relayrejectedhourly],/usr/local/bin/exim_sqlscan -t relayrejected -i 60
...
Seems to be working pretty well so far, although I know it's not an ideal solution. Suggestions are welcome and appreciated.
I run mail services on a Debian server running Exim 4, exiscan, SpamAssassin, and ClamAV. My boss is always asking for statistics on our mail server, and while I've had good luck generating reports with existats, I thought that a better graphical representation might be more useful to him. As you've probably guessed, I thought of Zabbix.
The key to getting custom data into Zabbix is to generate a shell command which will return a simple number. I couldn't think of one which would pull the data I needed directly from Exim's mainlog, so I decided to go with an intermediate step: a daemon to follow the mainlog and insert relevant data into a MySQL database.
First: I use a "check_data" acl with exiscan to scan for viruses, spam, and relaying rules. For the purposes of analysis, there are only five categories of messages I'm interested in:
messages rejected for spam content ("spamrejected")
messages delivered, but marked as spam ("spamdelivered")
messages rejected for virus/malware content ("virus")
messages rejected because of relaying rules ("relayrejected")
all messages delivered, period ("delivered")
Each type of message generates a unique log entry: I use a perl script to tail the exim log, then insert a row into the table with the relevant data. Here's a snippet:
...
elsif( $entrydata =~ m/.*This message contains a virus.*/ ) {
$messageType = "virus";
}
...
$sql = "INSERT INTO log_entry SET timestamp='$date $time', messageID='$messageID', message_type='$message_type'";
...
Next, I needed a utility that could find and count up the entries I wanted. Again, a little perl script was called for.
...
# Usage: exim_sqlscan -t<entrytype> -i<interval_in_minutes>
...
$sql = "SELECT count(*) as count FROM log_entry where timestamp >= DATE_SUB(NOW(
), INTERVAL $opt_i minute) AND message_type = '$opt_t' GROUP BY message_type";
...
And, lastly, a few entries in zabbix_agentd.conf:
...
UserParameter=exim[deliveredminute],/usr/local/bin/exim_sqlscan -t delivered -i 1
...
UserParameter=exim[relayrejectedhourly],/usr/local/bin/exim_sqlscan -t relayrejected -i 60
...
Seems to be working pretty well so far, although I know it's not an ideal solution. Suggestions are welcome and appreciated.