Ignore the little gap in the graph, I had to move my server and so it was down for a bit.
Net-SNMP has a nice little feature that allows you to execute a script and return the result back when an SNMP OID is queried. I should mention that my scripts run a bit different than those posted by africanw in that there is no requirement for Mailscanner to be logging to a database. Instead I opted to scrape through the last 5000 lines of the /var/log/maillog file for entries added in the last 5 minutes, so as a result it is more disk and CPU intensive than africanw's method but it makes it pretty easy to query from any SNMP manager. And Cacti loves SNMP (right???).
NOTE: If you're email server is a high-volume email server and your load average is running a little high the scripts may not complete in time before SNMP times out (we are scraping through syslog files after all). What will happen is that no data will be returned by Net-SNMP and you're graphs may be missing bits. Just thought I'd mention it before I get flamed for stuff that is out of my control.
Sendmail Stats
You need to create a couple of scripts, one to count the recieved mail and another to count the sent mail. For simplicity sakes I stored mine in /opt. Each script is shown below,
/opt/count_recv.sh,
Code: Select all
#!/bin/sh
echo .1.3.6.1.4.100.5
echo gauge
tail -n 5000 /var/log/maillog|awk '
BEGIN {
search_time = "^" strftime("%b %e %H:%M", systime() - 5 * 60);
search_sent = "stat=Sent";
search_domain_1 = "@domain.com";
search_domain_2 = "@domain2.com";
recv_count = 0;
}
{
if ($0 ~ search_time && $0 ~ search_sent) time_trigger = 1;
if ($0 ~ search_sent) is_sent_trigger = 1;
if ($0 ~ search_domain_1) is_domain_trigger = 1;
if ($0 ~ search_domain_2) is_domain_trigger = 1;
if (time_trigger && is_sent_trigger && is_domain_trigger) recv_count++;
is_sent_trigger = 0;
is_domain_trigger = 0;
}
END { print recv_count; }'
exit
Now for a brief explanation. Everyone likes AWK right? It's a pretty simple script, it examines the last 5000 lines of /var/log/maillog for entries added in the last 5 minutes and looks for ones that has a Sendmail status of "Sent" to your domain(s) and then increments a counter if there is one.
/opt/count_sent.sh,
Code: Select all
#!/bin/sh
echo .1.3.6.1.4.100.6
echo gauge
tail -n 5000 /var/log/maillog|awk '
BEGIN {
search_time = "^" strftime("%b %e %H:%M", systime() - 5 * 60);
search_sent = "stat=Sent";
search_domain_1 = "@domain.com";
search_domain_2 = "@domain2.com";
recv_count = 0;
}
{
if ($0 ~ search_time && $0 ~ search_sent) time_trigger = 1;
if ($0 ~ search_sent) is_sent_trigger = 1;
if ($0 ~ search_domain_1) is_domain_trigger = 1;
if ($0 ~ search_domain_2) is_domain_trigger = 1;
if (time_trigger && is_spam_trigger) spam_count++;
if (time_trigger && is_not_spam_trigger) not_spam_count++;
if (time_trigger && is_sent_trigger && !is_domain_trigger) sent_count++;
is_sent_trigger = 0;
is_domain_trigger = 0;
}
END { print sent_count; }'
exit
This script is similar to the count_recv.sh script except for one key difference. Basically this script looks for the same Sendmail status of "Sent" for any domain that isn't yours.
Now with the scripts in place there are some changes you need to make to your snmpd.conf file so that when the .1.3.6.1.4.100.5 and .1.3.6.1.4.100.6 OIDs are queried the scripts get run.
/etc/snmp/snmpd.conf additions,
Code: Select all
# Count the number of received messages in the last 5 minutes
pass .1.3.6.1.4.100.5 /bin/sh /opt/count_recv.sh
# Count the number of sent messages in the last 5 minutes
pass .1.3.6.1.4.100.6 /bin/sh /opt/count_sent.sh
Mailscanner Stats
africanw's method has an advantage over mine here in that SPAM isn't identified as HIGHSPAM or LOWSPAM, it's only SPAM. As well viruses include both blocked files and viruses. No distiction. Sorry, this is a first version. I might work on fixing that later. Now again you'll need to create a couple of scripts, one to count the number of viruses that Mailscanner has detected and another to count the number of messages detected as SPAM.
/opt/count_viruses.sh
Code: Select all
#!/bin/sh
echo .1.3.6.1.4.100.4
echo gauge
tail -n 5000 /var/log/maillog|awk '
BEGIN {
search_time = "^" strftime("%b %e %H:%M", systime() - 5 * 60);
search_virus = "Virus Scanning: Found";
virus_count = 0;
}
{
if ($0 ~ search_time && $0 ~ search_virus) time_trigger = 1;
if ($0 ~ search_virus) is_virus_trigger = 1;
if (time_trigger && is_virus_trigger) virus_count = virus_count + $9;
is_virus_trigger = 0;
}
END { print virus_count; }'
exit
/opt/count_spam.sh
Code: Select all
#!/bin/sh
echo .1.3.6.1.4.100.2
echo gauge
tail -n 5000 /var/log/maillog|awk '
BEGIN {
search_time = "^" strftime("%b %e %H:%M", systime() - 5 * 60);
search_is_spam = "is spam";
spam_count = 0;
}
{
if ($0 ~ search_time && $0 ~ search_is_spam) time_trigger = 1;
if ($0 ~ search_is_spam) is_spam_trigger = 1;
if (time_trigger && is_spam_trigger) spam_count++;
is_spam_trigger = 0;
}
END { print spam_count; }'
exit
And again you'll need to modify your snmpd.conf file so that the scripts get run when the OIDs are queried,
/etc/snmp/snmpd.conf additions,
Code: Select all
# Count the number of SPAM messages in the last 5 minutes
pass .1.3.6.1.4.100.2 /bin/sh /opt/count_spam.sh
# Count the number of viruses detected in the last 5 minutes
pass .1.3.6.1.4.100.4 /bin/sh /opt/count_viruses.sh
Cacti Templates
Below is the Cacti Graph Template that I made up too (the Data Templates are included in the XML file since they are dependents). Now all you need to do is setup Cacti to start querying the above SNMP OIDs and then graph them using the template.