В сегодняшней заметке по написанию скриптов на 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