В сегодняшней заметке по написанию скриптов на Perl мы будем извлекать данные за вчерашнее число из лога Exim и отправлять эти данные по почте. Буду рад любым замечаниям и конструктивной критике специалистов по Perl. Вот так обычно выглядит лог Exim:
2022-08-30 08:15:41 [31309] 1T6wAO-00088v-W6 => user1 <[email protected]> F=<[email protected]> P=<[email protected]> R=mysql_localuser T=local_delivery S=1152 QT=1s DT=0s
2022-08-30 08:15:41 [31310] 1T6wAP-000890-1c <= [email protected] H=(domain) [ip1]:39258 I=[ip2]:25 P=esmtp S=1034 [email protected] T="Shutdown" from <[email protected]> for [email protected] [email protected]
2022-08-30 08:15:41 [2287] SMTP connection from [ip1]:39259 I=[ip2]:25 (TCP/IP connection count = 5)
2022-08-30 08:15:41 [31310] SMTP connection from (domain) [ip1]:39258 I=[ip2]:25 closed by QUIT
2022-08-30 08:15:41 [31309] 1T6wAO-00088v-W6 => user2 <[email protected]> F=<[email protected]> P=<[email protected]> R=mysql_localuser T=local_delivery S=1147 QT=1s DT=0s
2022-08-30 08:15:41 [31309] 1T6wAO-00088v-W6 Completed QT=1s
Из лога мы будем выбирать все записи, которые были сделаны вчера, а затем отправлять их по электронной почты с вложением лога. Далее сам скрипт с комментариями.
#!/usr/bin/perl -w
# Подключаем необходимые модули DateTime, MIME::Lite
use strict;
use warnings;
use DateTime;
use MIME::Lite;
# Объявляем переменные
my $today = DateTime->now; # Определяем текущую дату
my $yesterday_format = $today->subtract(days => 1); # Получаем вчерашнюю дату
my $yesterday = $yesterday_format->ymd; # Форматируем дату в формат даты лога Exim
open INPUTFILE, "/path/to/input/log/mainlog" or die "Cannot open input file\n"; # Открываем на чтение исходный (анализируемый) файл лога Exim
open OUTPUTFILE, ">/path/to/output/log/log.txt" or die "Cannot open output file\n"; # Открываем на запись файл, который впоследствии будем отправлять по почте
# Проходим по исходному файлу построчно в цикле
while (<INPUTFILE>) {
chomp; # Убираем символы перевода строки в конце каждой строки
if (/^$yesterday */) { # Регулярным выражением проверяем соответствие даты вчерашней
print OUTPUTFILE "$_\n"; # Пишем в файл все записи лога, сделанные вчера
} # end block of if
} # end block of while
close OUTPUTFILE; # Закрываем конечный файл
close INPUTFILE; # Закрываем исходный файл
# Используя модуль MIME::Lite создаем тело сообщения, заполняя необходимые поля своими данными: От Кого, Кому, Тема, Текст письма, Вложение etc.
my $msg = MIME::Lite->new(
From =>'monitoring_script',
To =>'[email protected]',
Subject =>'Logfile of exim',
Type =>'multipart/mixed'
);
# Создаем текст письма
$msg->attach(Type =>'TEXT',
Data =>"Logfile of exim for ".$yesterday
);
# Создаем вложение
$msg->attach(Type =>'application/zip',
Path =>'/path/to/scripts/log.txt',
Filename =>'log.txt',
Disposition => 'attachment'
);
# Отправляем письмо
$msg->send();
Теперь все это ставим в cron и ждем писем. Также при желании можно доработать скрипт: задать другой интервал, можно также приспособить данный скрипт для выборки из логов Nginx. Все это просто реализуется и очень хорошо все описано на страницах модулей MIME::Lite и DateTime.
Более подробно про модуль MIME::Lite
Более подробно про модуль DateTime