Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / postfix / postfix_mailstats_ @ 1fe97cbf

Historique | Voir | Annoter | Télécharger (4,19 ko)

1 a64e85b2 Clemens Schwaighofer
#!/usr/bin/perl -w
2
# -*- perl -*-
3
4
=head1 NAME
5
6
postfix_mailstats_ - Plugin to monitor the number of mails delivered and
7
rejected by postfix
8
9
=head1 CONFIGURATION
10
11
Uses the last part of the symlink name for grepping the correct data from the
12
postfix log file. The name must be syslog_name from the postfix config.
13
The environment settings still applay to this plugin.
14
15
Configuration parameters for /etc/munin/postfix_mailstats_,
16
if you need to override the defaults below:
17
18
 [postfix_mailstats]
19
  env.logdir  - Which logfile to use
20
  env.logfile - What file to read in logdir
21
22
=head2 DEFAULT CONFIGURATION
23
24
 [postfix_mailstats]
25
  env.logdir  /var/log
26
  env.logfile mail.log
27
28
=head1 AUTHOR
29
30
Records show that the plugin was contributed by Nicolai Langfeldt in
31
2003.  Nicolai can't find anything in his email about this and expects
32
the plugin is based on the corresponding exim plugin - to which it now
33 fba800ae Veres Lajos
bears no resemblance.
34 a64e85b2 Clemens Schwaighofer
35
Extended for multiple queue use by Clemens Schwaighofer (gullevek@gullevek.org) in 2010.
36
37
=head1 LICENSE
38
39
GPLv2
40
41
=head1 MAGIC MARKERS
42
43
=begin comment
44
45
These magic markers are used by munin-node-configure when installing
46
munin-node.
47
48
=end comment
49
50
 #%# family=manual
51
 #%# capabilities=autoconf
52
53
=head1 RANDOM COMMENTS
54
55
Would be cool if someone ported this to Munin::Plugin for both state
56
file and log tailing.
57
58
=cut
59
60
# get the postfix queue number to look for
61
$0 =~ /postfix_mailstats_([\w\d\-]+)$/;
62
my $postfix = $1;
63
my $statefile = "$ENV{MUNIN_PLUGSTATE}/munin-plugin-".$postfix."_mailstats.state";
64
my $pos;
65
my $delivered = 0;
66
my $rejects = {};
67
my $LOGDIR  = $ENV{'logdir'}  || '/var/log';
68
my $LOGFILE = $ENV{'logfile'} || 'mail.log';
69
70
my $logfile = "$LOGDIR/$LOGFILE";
71
72
if ($ARGV[0] and $ARGV[0] eq "autoconf")
73
{
74
	my $logfile;
75
	if (-d $LOGDIR)
76
	{
77
		if (-f $logfile)
78
		{
79
				if (-r $logfile)
80
				{
81
					print "yes\n";
82
					exit 0;
83
				}
84
				else
85
				{
86
					print "no (logfile '$logfile' not readable)\n";
87
				}
88
		}
89
		else
90
		{
91
			print "no (logfile '$logfile' not found)\n";
92
		}
93
	}
94
	else
95
	{
96
		print "no (could not find logdir '$LOGDIR')\n";
97
	}
98
99
	exit 0;
100
}
101
102
103
if (-f $statefile)
104
{
105
	open (IN, '<', $statefile) or die "Unable to open state-file: $!\n";
106
	if (<IN> =~ /^(\d+):(\d+)/)
107
	{
108
		($pos, $delivered) = ($1, $2);
109
	}
110
	while (<IN>)
111
	{
112
		if (/^([0-9a-z.\-]+):(\d+)$/)
113
		{
114
			$rejects->{$1} = $2;
115
		}
116
	}
117
	close IN;
118
}
119
120
if (! -f $logfile)
121
{
122
	print "delivered.value U\n";
123
	foreach my $i (sort keys %{$rejects})
124
	{
125
		print "r$i.value U\n";
126
	}
127
	exit 0;
128
}
129
130
$startsize = (stat $logfile)[7];
131
132
if (!defined $pos)
133
{
134
    # Initial run.
135
    $pos = $startsize;
136
}
137
138
parseLogfile($logfile, $pos, $startsize);
139
$pos = $startsize;
140
141
if ( $ARGV[0] and $ARGV[0] eq "config" )
142
{
143
	print "graph_title Postfix message throughput for $postfix\n";
144
	print "graph_args --base 1000 -l 0\n";
145
	print "graph_vlabel mails / \${graph_period}\n";
146
	print "graph_scale  no\n";
147
	print "graph_total  Total\n";
148 cc3622d9 dipohl
	print "graph_category mail\n";
149 a64e85b2 Clemens Schwaighofer
	print "delivered.label delivered\n";
150
	print "delivered.type DERIVE\n";
151
	print "delivered.draw AREA\n";
152
	print "delivered.min 0\n";
153
	foreach my $i (sort keys %{$rejects})
154
	{
155
		print "r$i.label reject $i\n";
156
		print "r$i.type DERIVE\n";
157
		print "r$i.draw STACK\n";
158
		print "r$i.min 0\n";
159
	}
160
	exit 0;
161
}
162
163
print "delivered.value $delivered\n";
164
foreach my $i (sort keys %{$rejects})
165
{
166
	print "r$i.value ", $rejects->{$i}, "\n";
167
}
168
169
if (-l $statefile)
170
{
171
	die ("$statefile is a symbolic link, refusing to touch it.");
172
}				
173
open (OUT, '>', $statefile) or die "Unable to open statefile: $!\n";
174
print OUT "$pos:$delivered\n";
175
foreach my $i (sort keys %{$rejects})
176
{
177
	print OUT "$i:", $rejects->{$i}, "\n";
178
}
179
close OUT;
180
181
sub parseLogfile 
182
{    
183
	my ($fname, $start, $stop) = @_;
184
	open (LOGFILE, $fname)
185
		or die "Unable to open logfile $fname for reading: $!\n";
186
	seek (LOGFILE, $start, 0)
187
		or die "Unable to seek to $start in $fname: $!\n";
188
189
	while (tell (LOGFILE) < $stop) 
190
	{
191
		my $line = <LOGFILE>;
192
		chomp ($line);
193
194
		if ($line =~ /$postfix\/qmgr.*from=.*size=[0-9]*/ ||
195
			$line =~ /$postfix\/smtp.* status=sent /) 
196
		{
197
			$delivered++;
198
		} 
199
		elsif ($line =~ /$postfix\/smtpd.*reject: \S+ \S+ \S+ (\S+)/ ||
200
			   $line =~ /$postfix\/cleanup.* reject: (\S+)/)
201
		{
202
			$rejects->{$1}++;
203
		}
204
	}
205
	close(LOGFILE) or warn "Error closing $fname: $!\n";    
206
}
207
208
# vim:syntax=perl