На серверах с крупными проектами, где происходит рассылка большого количества сообщений, очередь доставки 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 (хотя это и не необходимо, ибо существует краткий формат вывода, но в целях обучения..)