База знаний

www. IT-Mehanika .ru --  журнал доброго админа

Примитивный анализатор почтовых логов для тех кто в танке ( таких как я :) )


Респект и Уважуха Вершинину Егору <Этот адрес электронной почты защищен от спам-ботов. У вас должен быть включен JavaScript для просмотра. .> с его статьей

Обработка log-файла почтового сервера Postfix

Собственно основные проблемы возникшие у меня были хорошо описаны в статье Егора. Приведу цитату :
"... У многих системных администраторов, работающих с почтовыми серверами,
рано или поздно возникают различные задачи, связанные с обработкой
журнальных файлов.

Например:

1) Нужно узнать было ли когда-то в прошлом письмо с определенного почтового адреса?
2) Или нужно посмотреть статистику работы с почтой уволившегося сотрудника?
3) Получить точный размер почтовых сообщений, прошедших через SMTP-сервер.
4) Да мало ли что еще

Основные проблемы при таких задачах следующие:

1) При больших объемах почтового трафика журналы растут достаточно быстро;
2) Журналы подвергаются ежедневной ротации;
3) В журналах масса ненужной информации.

... "

То что я нашел на просторах инета было либо тяжеленное как пушка "Берта" или выдавало что очень общее... )))) Почитав написанное Егором , я решил что это просто здоровско запихивать логи в MySql и дальше их рассматривать в спокойной обстановке. Взяв его  скрипт на perl , я лишь не много переточил его под Ubuntu. Здесь привожу переделанный

#!/usr/bin/perl

use DBI;

$dbh = DBI->connect("DBI:mysql:host=localhost;database=maillogs","mailuser","password")
or die "Нет доступа к СУБД!";
$insert = "INSERT INTO mails (month,day,time,ip,mailfrom,rcptto,size) VALUES(?,?,?,?,?,?,?)";
$sth = $dbh->prepare("$insert");

my %rec;

open(MAIL, "/var/log/mail.log");
while ($line = <MAIL>)
{
my ($month, $day, $time, $hostname, $servicename, $id, $message) = split /\s+/, $line, 7;
if ($id =~ /([a-z0-9]+)\:/i)
{
$id = $1;
$rec{$id} = {}
unless ($rec{$id});

if ($message =~ 'removed')
{
$rec{$id}->{'removed'}++;
}
else
{
while ($message =~ /(client|size|from|to)=(\S+?)(\s|,)/g)
{
if ($1 eq 'client') {
$rec{$id}->{'month'} = sprintf "%s", $month;
$rec{$id}->{'day'} = sprintf "%d", $day;
$rec{$id}->{'time'} = sprintf "%s", $time;
}
$rec{$id}->{$1} = $2;
}
}
}
}
close(MAIL);

foreach my $id (sort { $rec{$a}->{'time'} cmp $rec{$b}->{'time'} } keys %rec)
{
$rec{$id}->{'client'} =~ s/(.+)\[(\d+\.\d+\.\d+\.\d+)\]/$2/;
$rec{$id}->{'from'} =~ s/<(.+)>/$1/;
$rec{$id}->{'to'} =~ s/<(.+)>/$1/;
if (
$rec{$id}->{'removed'} 
&&
$rec{$id}->{'client'} ne '127.0.0.1'      
)
{
if ($rec{$id}->{'from'} ne 'Этот адрес электронной почты защищен от спам-ботов. У вас должен быть включен JavaScript для просмотра. ')
{
$sth->execute($rec{$id}->{'month'},$rec{$id}->{'day'},$rec{$id}->{'time'},$rec{$id}->{'client'},$rec{$id}->{'from'},$rec{$id}->{'to'},$rec{$id}->{'size'});
}
}
}

$sth->finish;
$dbh->disconnect;

далее все делается по тексту :
Mysql> create database maillogs;

Mysql> create table mails( month varchar(10), day char(2), time time,
ip varchar(255) not null default '', mailfrom varchar(255) not null default '',
rcptto varchar(255) not null default '', size int,  primary key(month,day,time));
Mysql> grant select,insert,update on maillogs.* to mailuser@localhost identified by 'password';

 

Ну и конечно данный скриптик заставим раз в сутки заглатывать лог. Выполняем crontab -e, вносим следующую строчку:

58 23 * * * /root/Scripts/maillog.pl

казалось все , но хочется видеть результат на экране , причем выборочно. Пришлось впомнить молодость и написать два php скриптика для счастья. Ногами не пинать , я уже 10 лет не писал ничего ))))))))

скриптик 1 он же index.php
<?php
header( "Content-Type: text/html; charset=UTF-8" );
echo "<font face='arial' size='6' ";
echo "<p align=center> Почтовые логи и прочие радости  </p>\n";
echo "<font face='arial' size='4'>";
echo "<p align=left> Введите нужный адрес или часть его добавив к нему % . Пример : pupkin@% выбор из всех доменов пользователей pupkin </p><br><hr>\n";

?>
<form action="tinc.php" method="GET">
Пользователь: <input name="mail_int" type="text" value="%">
Адресат: <input name="mail_ext" type="text" value="%">
<input type="submit" value="Выбор сделан !">
</form>

скриптик 2 он же tinc.php
<?php
header( "Content-Type: text/html; charset=UTF-8" );
$mail_int=$_GET['mail_int'];
$mail_ext=$_GET['mail_ext'];
echo "<font face='arial' size='6' ";
echo "<p align=center> Результаты поиска по почтовым логам </p>";
echo "<font face='arial' size='4'>";
echo "<p align=left> выбран пользователь> " ;
echo($mail_int);
echo "  выбран внешний адрес> " ;
echo($mail_ext);
echo ("</p><br><hr>\n");

echo "<table border=1>";
echo "<tr><td>Месяц</td><td>Число</td><td>Время </td><td>IP          </td><td>ОТ </td><td>Кому </td><td>Размер </td></tr>";

$host='localhost'; // имя хоста
$database='maillogs'; // имя базы данных, которую вы должны создать
$user='mailuser'; // заданное вами имя пользователя, либо определенное провайдером
$pswd='password'; // заданный вами пароль
$dbh = mysql_connect($host, $user, $pswd) or die("Не могу соединиться с MySQL.");
mysql_select_db($database) or die("Не могу подключиться к базе.");

$query = "SELECT * FROM maillogs.mails where mails.mailfrom LIKE '".$mail_ext."' and mails.rcptto LIKE '".$mail_int."'";
///

$res = mysql_query($query);

while($row = mysql_fetch_array($res))
{
echo "<tr><td>".$row['month']."</td><td>".$row['day']."</td><td>".$row['time']."</td><td>".$row['ip']."          </td><td>".$row['mailfrom']."</td><td>".$row['rcptto']."</td><td>".$row['size']." </td></tr>";

}
echo "</table>";

?>

если пригодится буду рад. меня очень напрягли монстры-анализаторы )))))


Бублик (это то же я)





You have no rights to post comments