2
0
mirror of https://github.com/munin-monitoring/contrib.git synced 2018-11-08 00:59:34 +01:00
contrib-munin/plugins/mail/greyfix
2013-05-08 14:24:31 -07:00

186 lines
5.5 KiB
Python
Executable File

#!/usr/bin/env python
#%# family=auto
#%# capabilities=autoconf
"""
Munin plugin that monitors the greyfix triplet database.
Author: Tom Hendrikx <tom@whyscream.net> 2011-08-05
This plugin monitors the Greyfix greylisting tool for Postfix.
It creates a nice overview of the number of triplets in the greyfix database,
dividing the database population in configurable ages.
For more information about greyfix: http://trac.kim-minh.com/greyfix/
Installation
============
To install, create a symlink to the plugin in the munin plugin directory:
$ ln -s /path/to/plugin/greyfix /etc/munin/plugins/greyfix
Configuration
=============
There are some settings that can be tweaked by adding statements to the
munin-node config:
[greyfix]
# run plugin as the same user as postfix does
user nobody
# path to greyfix binary (default: /usr/sbin/greyfix)
env.greyfix /usr/local/sbin/greyfix
# the length of each graph step in days (default: 7)
env.step_size 3
# the number of steps to graph (default: 11)
env.num_steps 47
# graph the greylisted triplets separate from the whitelisted ones (default: yes)
env.greylist_step no
Please note that the last step has no end date, so it includes all triplets
older than the second last step. I.e., the defaults (as named above) create a
graph that shows 10 steps of one week each, and one last step for everything
older than 10 weeks. Also, the separate greylist step is not considered
when applying num_steps.
"""
# Settings: all of these can be redefined in the munin-node config
settings = {
'greyfix': '/usr/sbin/greyfix',
'step_size': 7,
'num_steps': 11,
'greylist_step': 'yes'
}
import os
import sys
import subprocess
import datetime
def greyfix_parse_triplets():
"""Parse output of greyfix --dump-triplets into something that we can use.
The output of the command has the following columns:
sender_ip, sender_email, recipient_email, timestamp_first_seen, timestamp_last_seen, block_count, pass_count
Also see http://groups.google.com/group/greyfix/browse_thread/thread/510687a9ed94fc2c"""
greyfix = subprocess.Popen(args=[ settings['greyfix'], '--dump-triplets'], stdout=subprocess.PIPE)
stdout = greyfix.communicate()[0]
if greyfix.returncode > 0:
print '# greyfix exited with exit code %i' % (greyfix.returncode)
sys.exit(greyfix.returncode)
triplets = []
for line in stdout.split("\n"):
triplet = line.split("\t")
if len(triplet) == 7:
triplet[3] = datetime.datetime.strptime(triplet[3], '%c')
triplet[4] = datetime.datetime.strptime(triplet[4], '%c')
triplet[5] = int(triplet[5])
triplet[6] = int(triplet[6])
triplets.append(triplet)
return triplets
def convert_step_to_days(step):
"""Compute the days that are contained in a step, according to the configuration"""
start = settings['step_size'] * step
end = (settings['step_size'] * (step + 1)) - 1
if step >= (settings['num_steps'] -1):
return (start, '')
else:
return (start, end)
def print_fetch():
"""Generates and prints the values as retrieved from greyfix."""
triplets = greyfix_parse_triplets()
now = datetime.datetime.now()
steps = [0 for i in range(0, settings['num_steps'])]
greylist_step = 0
for triplet in triplets:
if settings['greylist_step'] == 'yes' and triplet[6] == 0:
greylist_step = greylist_step +1
continue;
delta = now - triplet[3]
step = delta.days / settings['step_size']
step = min(step, settings['num_steps'] -1)
# count the number of triplets in a group
steps[ step ] = steps[ step ] +1
# print result counts for each group
if settings['greylist_step'] == 'yes':
print 'gl.value %i' % greylist_step
for step, count in enumerate(steps):
fieldname = 'd%s_%s' % convert_step_to_days(step)
print '%s.value %i' % (fieldname, count)
def print_config():
"""Generates and prints a munin config for a given chart."""
print 'graph_title Greyfix triplets by age'
print 'graph_vlabel Number of triplets'
print 'graph_info The amount of triplets in the greyfix database with a certain age'
print 'graph_category postfix'
print 'graph_total All triplets'
print 'graph_args --lower-limit 0 --base 1000'
if settings['greylist_step'] == 'yes':
print 'gl.label Greylisted'
print 'gl.info The number of greylisted triplets. These did not have a single pass (yet)'
print 'gl.draw AREASTACK'
print 'gl.colour aaaaaa'
steps = range(0, settings['num_steps'])
for step in steps:
days = convert_step_to_days(step)
fieldname = 'd%s_%s' % days
label = 'Whitelisted for %s - %s days' % (days[0], days[1] if days[1] != '' else '...')
info = 'The number of whitelisted triplets that is between %s and %s days old' % (days[0], days[1] if days[1] != '' else '...')
print '%s.label %s' % (fieldname, label)
print '%s.info %s' % (fieldname, info)
print '%s.draw AREASTACK' % fieldname
if __name__ == '__main__':
# read settings from config file / environment
for key in settings.iterkeys():
if key in os.environ:
if os.environ[ key ].isdigit():
settings[ key ] = int(os.environ[ key ])
else:
settings[ key ] = os.environ[ key ]
#print '# setting %s updated to: %s' % (key, settings[ key ])
commands = ['fetch', 'autoconf', 'config']
if len(sys.argv) > 1:
command = sys.argv[1]
else:
command = commands[0]
if command not in commands:
print '# command %s unknown, choose one of: %s' % (command, commands)
sys.exit(1)
if command == 'fetch':
print_fetch()
elif command == 'config':
print_config()
elif command == 'autoconf':
if os.path.exists( settings['greyfix'] ):
print 'yes'
else:
print 'no (binary not found at %s)' % settings['greyfix']