Управление очередью exim, получение подробного лога

На серверах с крупными проектами, где происходит рассылка большого количества сообщений, очередь доставки exim временами разрастается до неприличных размеров из-за недоставленных писем. Анализ логов по каждому конкретному случаю представляет собой непростую задачу.

В целях упрощения анализа причин недоставленности сообщений, находящихся в очереди и её очистки был написан этот скрипт на bash. По-хорошему скрипт надо переписать через нормальное пренаправление вывода, сделать отлов ошибок, чистку логов – если реализуете – поделитесь :)

#!/bin/bash
# ----------------------------------------------------------------------------
# "THE BEER-WARE LICENSE" (Revision 42):
# farmal.in wrote this file. As long as you retain this notice you
# can do whatever you want with this stuff. If we meet some day, and you think
# this stuff is worth it, you can buy me a beer in return
# ----------------------------------------------------------------------------
# farmal.in script for controlling exim queue and for getting verbose reports via email
 
# current date
day=`date "+%Y-%m-%d"`
# report's path and filename
text="/tmp/$day.exim.txt"
# path
p="/usr/sbin"
# report recipients
emails="my@email.com"
# time in seconds after which message in queue will be deleted by this script 1 day (86400 seconds by default)
# warning! you should adjust this parameter to your system for not losing anything important from exim queue!
sec=86400
cd /tmp
 
#echo -e "There are `exim -bpc` messages in the queue:\n\n" > "/tmp/$day.exim.txt"
echo -e "There are OLD `$p/exiqgrep -o $sec -bc` in the queue:\n\n" > "/tmp/$day.exim.txt"
# show all messages in the queue
#echo -e "`$p/exiqgrep -o $sec -b`\n\n" >> "/tmp/$day.exim.txt"
 
#echo -e "LOGS for each unldelivered message:\n" >> "/tmp/$day.exim.txt"
#echo -e "`$p/exiqgrep -o $sec -i | xargs exim -Mvl`\n" >> "/tmp/$day.exim.txt"
 
# changing separator (space to newline)
OLD_IFS="$IFS"
IFS=$'\n'
# declare array
declare -a ARR
# finding messages' IDs: grepping only line with <email@host.com> and getting the third value
# for all messages in queue you may use
# ARR=(`exim -bp|grep '<'|awk '{print $3}'`)
# for only old mesaggges
ARR=(`$p/exiqgrep -o $sec -i`)
 
# iterating through each array element
for ((i=0; i<${#ARR[@]}; i++))
do
   echo -e "******* Message ${ARR[$i]}\n">> "/tmp/$day.exim.txt"
   # message headers
   # echo -e "`$p/exim -Mvh ${ARR[$i]}`\n">> "/tmp/$day.exim.txt"
 
   # if we don't want to have to mush garbage in our report we can only show the most
   # important part (after the word "Received" (there goes subject,date,to etc.)
   echo -e "`$p/exim -Mvh ${ARR[$i]}|awk '/Received/ {f=1}f'`\n">> "/tmp/$day.exim.txt"
 
   # message body
   # echo -e "`$p/exim -Mvb ${ARR[$i]}`\n">> "/tmp/$day.exim.txt"
 
   # getting log for each message
   #echo -e "`$p/exim -Mvl ${ARR[$i]}`\n">> "/tmp/$day.exim.txt"
done
 
# restoring separator
IFS="$OLD_IFS"
 
echo -e "\nDeleting old messages:\n" >> "/tmp/$day.exim.txt"
# delete all undelivered messages in exim's queue which are older than $sec
echo -e "`$p/exiqgrep -o $sec -i | xargs $p/exim -Mrm`" >> "/tmp/$day.exim.txt"
 
# let's see if we have something useful in our log
if  [ $(stat -c %s "$text") -gt 120 ]
then
   # sending report
   mail -s 'following messages were deleted from exim queue on SERVER' $emails<$text
   echo
fi

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

There are OLD 2 matches out of 12 messages in the queue:
 
 
******* Message 1RdjNI-0005pc-4Y
 
209P Received: from user1 by mail.myserver.com with local (Exim 4.69)
       (envelope-from <info@myserver.com>)
       id 1RdjNI-0005pc-4Y
       for myclient@hishost.com; Thu, 22 Dec 2011 15:12:00 +0100
048T To: Myclient1 <myclient@hishost.com>
053  Subject: Happy Holidays Wishes
049F From: MyCompany <info@myserver.com>
018  MIME-Version: 1.0
085  Content-Type: multipart/mixed;
       boundary="PMW------e6311b22194c02eacf5a8e301c4b3f16"
032  Content-Transfer-Encoding: 7bit
059I Message-Id: <E1RdjNI-0005pc-4Y@mail.myserver.com>
038  Date: Thu, 22 Dec 2011 15:12:00 +0100
 
******* Message 1RdjtW-0007kC-Lp
 
216P Received: from user1 by mail.myserver.com with local (Exim 4.69)
       (envelope-from <info@myserver.com>)
       id 1RdjtW-0007kC-Lp
       for myclient2@hishost.com; Thu, 22 Dec 2011 15:45:18 +0100
048T To: Myclient2 <myclient2@hishost.com>
053  Subject: Happy Holidays Wishes
049F From: MyCompany <info@myserver.com>
018  MIME-Version: 1.0
085  Content-Type: multipart/mixed;
       boundary="PMW------8307188c354eaa46873230e8d14eeb61"
032  Content-Transfer-Encoding: 7bit
059I Message-Id: <E1RdjtW-0007kC-Lp@mail.myserver.com>
038  Date: Thu, 22 Dec 2011 15:45:18 +0100
 
Deleting old messages:
Message 1RdjNI-0005pc-4Y has been removed
Message 1RdjtW-0007kC-Lp has been removed

А если их раскоммениторовать строку

   # getting log for each message
   echo -e "`$p/exim -Mvl ${ARR[$i]}`\n">> "/tmp/$day.exim.txt"

то можно включить в логи подробные отчёты о том, почему не получилось доставить конкретное сообщение. Выглядеть это будет так:

2011-12-18 10:03:13 Received from root@mail.myserver.com U=root P=local S=509
2011-12-18 10:03:19 theresa@bsf-s.com R=lookuphost defer (-1): host lookup did not complete
2011-12-18 10:03:20 immortal@fsbkgb.com R=lookuphost T=remote_smtp defer (-53): retry time not reached for any host
2011-12-18 10:03:20 zed@alghurair.com R=lookuphost T=remote_smtp defer (-53): retry time not reached for any host
2011-12-18 10:03:24 SMTP error from remote mail server after DATA: host mailx.hoster.ru [195.128.50.36]: 451 Greylisting is in progress. Please, delay the message for at least 15 minutes before retry.
2011-12-18 10:03:24 lena@conpr.ru R=lookuphost T=remote_smtp defer (-46): SMTP error from remote mail server after DATA: host mailx.hoster.ru [195.128.50.36]: 451 Greylisting is in progress. Please, delay the message for at least 15 minutes before retry.
2011-12-18 10:06:29 nic.mv.ru [89.239.136.58]:25 Connection timed out
2011-12-18 10:06:29 mike@nic.mv.ru R=lookuphost T=remote_smtp defer (110): Connection timed out
2011-12-18 10:23:30 SMTP error from remote mail server after DATA: host mailx.hoster.ru [195.128.50.36]: 451 Greylisting is in progress. Please, delay the message for at least 15 minutes before retry.
2011-12-18 10:23:30 lena@conpr.ru R=lookuphost T=remote_smtp defer (-46): SMTP error from remote mail server after DATA: host mailx.hoster.ru [195.128.50.36]: 451 Greylisting is in progress. Please, delay the message for at least 15 minutes before retry.
2011-12-18 10:41:42 SMTP error from remote mail server after DATA: host mailx.hoster.ru [195.128.50.36]: 451 Greylisting is in progress. Please, delay the message for at least 15 minutes before retry.

Кстати, в коде скрипта получилось интересно реализовать работу с массивами в bash, а также разбор вывода команд с вомощью awk (хотя это и не необходимо, ибо существует краткий формат вывода, но в целях обучения..)

Leave a Reply

Your email address will not be published. Required fields are marked *