[Postfixbuch-users] Bild von Mailgraph als Mail senden

Joern Falatik jofanews at gmx.de
Mo Sep 5 14:19:23 CEST 2005


Hallo Sven,

ich stand vor demselben Problem und habe es über zwei Perl-Scripte
gesteuert:

1. create_rrd_pics.pl

--- snip ---
#!/usr/bin/perl -w

# mailgraph -- a postfix statistics rrdtool frontend
# copyright (c) 2000-2005 David Schweikert <dws at ee.ethz.ch>
# released under the GNU General Public License

use RRDs;
use POSIX qw(uname);

my $VERSION = "1.11";

my $host = (POSIX::uname())[1];
my $scriptname = 'mailgraph.cgi';
my $xpoints = 900;
my $points_per_sample = 3;
my $ypoints = 250;
my $ypoints_err = 160;
my $rrd = '/var/log/mailgraph.rrd'; # path to where the RRD database is
my $rrd_virus = '/var/log/mailgraph_virus.rrd'; # path to where the
Virus RRD database is
my $tmp_dir = '/tmp/mailgraph'; # temporary directory where to store the
images
my $rrdtool_1_0 = ($RRDs::VERSION < 1.199908);
my $in = ".gif";
my $out = ".jpg";

my @graphs = (
	{ title => 'Day Graphs',   seconds => 3600*24,        },
	{ title => 'Week Graphs',  seconds => 3600*24*7,      },
	{ title => 'Month Graphs', seconds => 3600*24*31,     },
	{ title => 'Year Graphs',  seconds => 3600*24*365, },
);

my %color = (
	sent     => '000099', # rrggbb in hex
	received => '009900',
	rejected => 'AA0000',
	bounced  => '000000',
	virus    => 'FF0000',
	spam     => '999999',
);

sub graph($$$)
{
	my $range = shift;
	my $file = shift;
	my $title = shift;
	my $step = $range*$points_per_sample/$xpoints;
	my $date = localtime(time);
	$date =~ s|:|\\:|g unless $rrdtool_1_0;

	my ($graphret,$xs,$ys) = RRDs::graph($file,
		'--imgformat', 'GIF',
		'--width', $xpoints,
		'--height', $ypoints,
		'--start', "-$range",
		'--vertical-label', 'msgs/min',
		'--lower-limit', 0,
		'--units-exponent', 0, # don't show milli-messages/s
		'--lazy',
		'--color', 'SHADEA#ffffff',
		'--color', 'SHADEB#ffffff',
		'--color', 'BACK#ffffff',

		$rrdtool_1_0 ? () : (
			'--slope-mode'
		),

		"DEF:sent=$rrd:sent:AVERAGE",
		"DEF:msent=$rrd:sent:MAX",
		"CDEF:rsent=sent,60,*",
		"CDEF:rmsent=msent,60,*",
		"CDEF:dsent=sent,UN,0,sent,IF,$step,*",
		"CDEF:ssent=PREV,UN,dsent,PREV,IF,dsent,+",
		"AREA:rsent#$color{sent}:Sent    ",
		'GPRINT:ssent:MAX:total\: %8.0lf msgs',
		'GPRINT:rsent:AVERAGE:avg\: %5.2lf msgs/min',
		'GPRINT:rmsent:MAX:max\: %4.0lf msgs/min\l',

		"DEF:recv=$rrd:recv:AVERAGE",
		"DEF:mrecv=$rrd:recv:MAX",
		"CDEF:rrecv=recv,60,*",
		"CDEF:rmrecv=mrecv,60,*",
		"CDEF:drecv=recv,UN,0,recv,IF,$step,*",
		"CDEF:srecv=PREV,UN,drecv,PREV,IF,drecv,+",
		"LINE2:rrecv#$color{received}:Received",
		'GPRINT:srecv:MAX:total\: %8.0lf msgs',
		'GPRINT:rrecv:AVERAGE:avg\: %5.2lf msgs/min',
		'GPRINT:rmrecv:MAX:max\: %4.0lf msgs/min\l',

                 "DEF:virus=$rrd_virus:virus:AVERAGE",
                 "DEF:mvirus=$rrd_virus:virus:MAX",
                 "CDEF:rvirus=virus,60,*",
                 "CDEF:dvirus=virus,UN,0,virus,IF,$step,*",
                 "CDEF:svirus=PREV,UN,dvirus,PREV,IF,dvirus,+",
                 "CDEF:rmvirus=mvirus,60,*",
                 "LINE2:rvirus#$color{virus}:Viruses ",
                 'GPRINT:svirus:MAX:total\: %8.0lf msgs',
                 'GPRINT:rvirus:AVERAGE:avg\: %5.2lf msgs/min',
                 'GPRINT:rmvirus:MAX:max\: %4.0lf msgs/min\l',

		'COMMENT:['.$date.']\r',
	);
	my $ERR=RRDs::error;
	die "ERROR: $ERR\n" if $ERR;
}

sub graph_err($$$)
{
         my $range = shift;
         my $file = shift;
         my $title = shift;
         my $step = $range*$points_per_sample/$xpoints;
         my $date = localtime(time);
         $date =~ s|:|\\:|g unless $rrdtool_1_0;

         my ($graphret,$xs,$ys) = RRDs::graph($file,
                 '--imgformat', 'GIF',
                 '--width', $xpoints,
                 '--height', $ypoints_err,
                 '--start', "-$range",
                 '--vertical-label', 'msgs/min',
                 '--lower-limit', 0,
                 '--units-exponent', 0, # don't show milli-messages/s
                 '--lazy',
                 '--color', 'SHADEA#ffffff',
                 '--color', 'SHADEB#ffffff',
                 '--color', 'BACK#ffffff',

                 $rrdtool_1_0 ? () : (
                         '--slope-mode',
                 ),

                 "DEF:rejected=$rrd:rejected:AVERAGE",
                 "DEF:mrejected=$rrd:rejected:MAX",
                 "CDEF:rrejected=rejected,60,*",
                 "CDEF:drejected=rejected,UN,0,rejected,IF,$step,*",
                 "CDEF:srejected=PREV,UN,drejected,PREV,IF,drejected,+",
                 "CDEF:rmrejected=mrejected,60,*",
                 "LINE2:rrejected#$color{rejected}:Rejected",
                 'GPRINT:srejected:MAX:total\: %8.0lf msgs',
                 'GPRINT:rrejected:AVERAGE:avg\: %5.2lf msgs/min',
                 'GPRINT:rmrejected:MAX:max\: %4.0lf msgs/min\l',

                 "DEF:bounced=$rrd:bounced:AVERAGE",
                 "DEF:mbounced=$rrd:bounced:MAX",
                 "CDEF:rbounced=bounced,60,*",
                 "CDEF:dbounced=bounced,UN,0,bounced,IF,$step,*",
                 "CDEF:sbounced=PREV,UN,dbounced,PREV,IF,dbounced,+",
                 "CDEF:rmbounced=mbounced,60,*",
                 "AREA:rbounced#$color{bounced}:Bounced ",
                 'GPRINT:sbounced:MAX:total\: %8.0lf msgs',
                 'GPRINT:rbounced:AVERAGE:avg\: %5.2lf msgs/min',
                 'GPRINT:rmbounced:MAX:max\: %4.0lf msgs/min\l',

                 "DEF:spam=$rrd_virus:spam:AVERAGE",
                 "DEF:mspam=$rrd_virus:spam:MAX",
                 "CDEF:rspam=spam,60,*",
                 "CDEF:dspam=spam,UN,0,spam,IF,$step,*",
                 "CDEF:sspam=PREV,UN,dspam,PREV,IF,dspam,+",
                 "CDEF:rmspam=mspam,60,*",
                 "STACK:rspam#$color{spam}:Spam    ",
                 'GPRINT:sspam:MAX:total\: %8.0lf msgs',
                 'GPRINT:rspam:AVERAGE:avg\: %5.2lf msgs/min',
                 'GPRINT:rmspam:MAX:max\: %4.0lf msgs/min\l',

                 'COMMENT:['.$date.']\r',
         );
         my $ERR=RRDs::error;
         die "ERROR: $ERR\n" if $ERR;
}

sub main()
{
	my $file = "";
	
	$file = "$tmp_dir/mailgraph_0n";
	graph($graphs[0]{seconds}, $file.$in, $graphs[0]{title});
	#system("/usr/bin/convert $file$in $file$out");

	$file = "$tmp_dir/mailgraph_1n";
	graph($graphs[1]{seconds}, $file.$in, $graphs[1]{title});
	#system("/usr/bin/convert $file$in $file$out");

	$file = "$tmp_dir/mailgraph_2n";
	graph($graphs[2]{seconds}, $file.$in, $graphs[2]{title});
	#system("/usr/bin/convert $file$in $file$out");

	$file = "$tmp_dir/mailgraph_3n";
	graph($graphs[3]{seconds}, $file.$in, $graphs[3]{title});
	#system("/usr/bin/convert $file$in $file$out");

	$file = "$tmp_dir/mailgraph_0e";
	graph_err($graphs[0]{seconds}, $file.$in, $graphs[0]{title});
	#system("/usr/bin/convert $file$in $file$out");

	$file = "$tmp_dir/mailgraph_1e";
	graph_err($graphs[1]{seconds}, $file.$in, $graphs[1]{title});
	#system("/usr/bin/convert $file$in $file$out");

	$file = "$tmp_dir/mailgraph_2e";
	graph_err($graphs[2]{seconds}, $file.$in, $graphs[2]{title});
	#system("/usr/bin/convert $file$in $file$out");

	$file = "$tmp_dir/mailgraph_3e";
	graph_err($graphs[3]{seconds}, $file.$in, $graphs[3]{title});
	#system("/usr/bin/convert $file$in $file$out");

}

main;

--- snap ---

2. send_rrd.pl

--- snip ---
#!/usr/bin/perl -w
############################################################################
#
# ChangeLog:
#
############################################################################
#
# Date and author
# --
# changes and descriptions
# ==
#
############################################################################
#
# 28.08.2005	Falatik, Joern
# --
# first release
# ==
# --
# ==
# --
# ==
#
############################################################################

############################################################################
#
# Description:
#
############################################################################
#
# coming soon ;-)
#
# Usage:
#
#############################################################################
use warnings;
use strict;

use MIME::Lite;
use Net::SMTP;
use HTML::FromText;

############################################################################
#
###
### Global settings
###
#
############################################################################

### Adjust systemprograms
my $plot_prg         = '/usr/local/bin/create_rrd_pics.pl';
my $date_prg         = '/bin/date +"Datum: %d.%m.%Y - Uhrzeit: %H:%M"';
my $hostname_prg     = '/bin/hostname -f';

my $date;
chomp($date          = `$date_prg`);

my $hostname         = `$hostname_prg`;
chomp $hostname;

### other globals
my $line             =
"\n========================================================================\n\n";
my $msg;
my $html;
my $text;

### Adjust sender, recipient and your SMTP mailhost
my $from_address     = '"ECODOR Maildienste" <maildienste at ecofis.de>';
my $to_address       = '"ECODOR Maildienste" <maildienste at ecofis.de>';
#my $to_address       = '"ECODOR Mail" <j.falatik at ecofis.de>';
my $mail_host        = 'localhost';
my $tmpfilename      = '/tmp/mailgraph/mailgraph_';
my $ext              = '.gif';

### Adjust subject and body message
my $subject          = '[' . $hostname . '] - RRD-Postfix-Statistik von
' . $date;

### Adjust the filenames
my $an_cid   = $tmpfilename . "0n";
my $an_file  = $tmpfilename . "0n" . $ext;
my $ae_cid   = $tmpfilename . "0e";
my $ae_file  = $tmpfilename . "0e" . $ext;

my $bn_cid   = $tmpfilename . "1n";
my $bn_file  = $tmpfilename . "1n" . $ext;
my $be_cid   = $tmpfilename . "1e";
my $be_file  = $tmpfilename . "1e" . $ext;

my $cn_cid   = $tmpfilename . "2n";
my $cn_file  = $tmpfilename . "2n" . $ext;
my $ce_cid   = $tmpfilename . "2e";
my $ce_file  = $tmpfilename . "2e" . $ext;

my $dn_cid   = $tmpfilename . "3n";
my $dn_file  = $tmpfilename . "3n" . $ext;
my $de_cid   = $tmpfilename . "3e";
my $de_file  = $tmpfilename . "3e" . $ext;

### Create Pictures
system($plot_prg);

############################################################################
#
### Convert a string into HTML
###
### Parameter:	Type String
### Return:	Type String with HTML Code
#
############################################################################

sub mk_html($)
{
	my($str) = @_;

	my $return = text2html(
		$str,
		metachars  => 0,
		paras      => 0,
  		blockcode  => 0,
  		tables     => 0,
  		lines      => 1,
  		bullets    => 0,
  		numbers    => 0,
  		urls       => 0,
  		email      => 0,
  		bold       => 0,
  		underline  => 0,
		numbers    => 0,
		title      => 0,
		spaces     => 1
	);


	return $return;
}


############################################################################
#
### Create MIME Multipart container
###
### Parameter:	none
### Return:	none
#
############################################################################

sub mk_multipart_container()
{
	### Create the multipart container
	$msg = MIME::Lite->new (
		From => $from_address,
		To => $to_address,
		Subject => $subject,
		Type =>'multipart/related'
#		Type =>'multipart/mixed'
	) or die "Error creating multipart container: $!\n";

	return;
}


############################################################################
#
### Create MIME Message Part text/html
###
### Parameter:	Type String	Content and Header
### Return:	none
#
############################################################################

sub mk_msg_part($)
{
	my($str) = @_;

	### Add the text message part Mailstats
	$msg->attach (
		Type => 'text/html',
		Data => $str
	) or die "Error adding the text message part: $!\n";


	return;
}


############################################################################
#
### Create HTML block from ASCII
###
### Parameter:	Type String	Content and Header
### Return:	none
#
############################################################################

sub mk_html_block($$)
{
	my($str, $header) = @_;

	$header = '<hr noshade size="4"><b><font size="3" face="monospace">' .
mk_html($header) . '</font></b><hr noshade size="4">';
	$str    = '<font size="2" face="monospace">' . mk_html($str) . '</font>';

	return $header . $str;
}


############################################################################
#
### Create HTML block from HTML
###
### Parameter:	Type String	Content and Header
### Return:	none
#
############################################################################

sub mk_html_block_scr($$)
{
	my($str, $header) = @_;

	$header = '<hr noshade size="4"><b><font size="3" face="monospace">' .
mk_html($header) . '</font></b><hr noshade size="4">';
	$str    = '<font size="2" face="monospace">' . $str . '</font>';

	return $header . $str;
}


############################################################################
#
### Create Image block
###
### Parameter:	Type String	Path and Id
### Return:	none
#
############################################################################

sub mk_image_block($$)
{
	my($path, $id) = @_;

	### Add the CPUSARPLOT Image
	$msg->attach (
		Type        => 'image/gif',
		Path        => $path,
		Id          => $id,
#		Encoding    => 'base64',
		Disposition => 'inline'
	) or die "Error adding $path: $!\n";

	return;
}


############################################################################
#
### MAIN
#
############################################################################


mk_multipart_container();

my $header = '<b><font size="5" face="monospace">' . $subject .
'</font></b>';

$html = $header;


$text = "<p><img src=\"cid:$an_cid\"></p>";
$text = $text . "<p><img src=\"cid:$ae_cid\"></p>";
$html = $html . mk_html_block_scr($text, "Day Graphs:");


$text = "<p><img src=\"cid:$bn_cid\"></p>";
$text = $text . "<p><img src=\"cid:$be_cid\"></p>";
$html = $html . mk_html_block_scr($text, "Week Graphs:");


$text = "<p><img src=\"cid:$cn_cid\"></p>";
$text = $text . "<p><img src=\"cid:$ce_cid\"></p>";
$html = $html . mk_html_block_scr($text, "Month Graphs:");


$text = "<p><img src=\"cid:$dn_cid\"></p>";
$text = $text . "<p><img src=\"cid:$de_cid\"></p>";
$html = $html . mk_html_block_scr($text, "Year Graphs:");

#print $html;

mk_msg_part("<body>" . $html . "</body>");

mk_image_block($an_file, $an_cid);
mk_image_block($ae_file, $ae_cid);

mk_image_block($bn_file, $bn_cid);
mk_image_block($be_file, $be_cid);

mk_image_block($cn_file, $cn_cid);
mk_image_block($ce_file, $ce_cid);

mk_image_block($dn_file, $dn_cid);
mk_image_block($de_file, $de_cid);

### Send the Message
MIME::Lite->send('smtp', $mail_host, Timeout=>60);
$msg->send;

system("/bin/rm /tmp/mailgraph/*");

0;
### END OF PROGRAM ####################################################jofa#


--- snap ---


Das zweite Script ruft das erste auf und wird über die crontab bei mir
gesteuert:

--- snip ---
5 0 * * * /usr/local/bin/send_rrd.pl >/dev/null
--- snap ---

Ich erstelle allerdings keine PNGs sondern GIFs, das hat aber lediglich
mit dem Client (Lotus Notes) zu tun, der erst ab R7 PNGs darstellen kann.

MfG Jörn Falatik




Mehr Informationen über die Mailingliste Postfixbuch-users