Поиск в логах Exim

Поиск в логах Exim

Часто бывает, что кто-то просит найти письмо такого-то пользователя, которое было отправлено позавчера, например. Можно перерывать логи руками, а можно воспользоваться скриптом, который любезно прислал один из читателей:

#!/bin/sh

to_grep="$*"

if [ ${#to_grep} = 0 ]
then
echo "
STOP: Where is search string?
" > /dev/stderr
exit 1
fi

tmp_major_filename="/tmp/searchmajortmp$$"
rm -f "${tmp_major_filename}"

# Мониторим Ctrl+C чтобы не оставлять хвостов из временных файлов.
trap 'rm -f ${tmp_major_filename} ;echo ; exit 13' TERM INT

exlog_log="/var/log/exim/mainlog"

if [ ! -r "${exlog_log}" ]
then
echo "
STOP: Where is exim log?
" > /dev/stderr
exit 1
fi

today_is=`date +%Y-%m-%d`

echo "1" | awk -v today_is="${today_is}" -v rex_log="${exlog_log}" '{
dl_cn = 0 # устанавливаем счетчик дней в 0
# Получаем список файлов лога exim-a, считаем их количество.
cmd_get_file_list=("ls "rex_log"*")
while ((cmd_get_file_list |getline)> 0) {
++fl_cn
}
close (cmd_get_file_list)

# Узнаем что у нас за ОС
cmd_what_os=("uname -s")
cmd_what_os |getline os_is
close(cmd_what_os)

while (dl_cn < fl_cn) { # Получаем три значения в массиве (год, месяц, день) - текущая дата. if (dl_cn == 0) { split(today_is,TEMPTODAY,"-") today_is_month = TEMPTODAY[2] month_arg = TEMPTODAY[2] } else { cmd_month_arg = (today_is_month - month_arg) # Получаем три значения в массиве (год, месяц, день) - последнее число нужного нам предыдущего месяца. if (os_is == "FreeBSD" || os_is == "Darwin") { cmd_date_last_month=("date -v-"cmd_day_arg"d -v-"cmd_month_arg"m +%Y-%m-%d") } else { cmd_date_last_month=("date -d \""cmd_day_arg" days ago "cmd_month_arg" months ago\" +%Y-%m-%d") } cmd_date_last_month |getline split($0,TEMPTODAY,"-") close (cmd_date_last_month) } # Выясняем до какого числа месяца будем делать декремент. days_until = (fl_cn - dl_cn) if (days_until > 0) {
day_until = 1
} else {
day_until = days_until
}

cmd_day_arg = TEMPTODAY[3]

# Получаем список дат в нисходящем порядке, забиваем в массив.
for (tmp_td=TEMPTODAY[3];tmp_td>=day_until;tmp_td--) {
# Заодно пририсовываем нули для красоты.
if (length(tmp_td) == 1) {
day_number = ("0"tmp_td)
} else {
day_number = tmp_td
}
FILESLIST[++dl_cn] = (TEMPTODAY[1]"-"TEMPTODAY[2]"-"day_number)
}

# Проверяем первая ли у нас итерация цикла.
if (month_arg != today_is_month) {
month_arg--
}
split("",TEMPTODAY)
}

# Печать массива.
printf "\n"
for (xs=1;xs<=fl_cn;xs++) { printf "\t%s%s%s\t%s\n" , "(", xs, ")", FILESLIST[xs] } split("",FILESLIST) printf "\n\t" exit }' read -p "Enter Digit: " num_to_grep if [ ${#num_to_grep} = 0 ] then echo " STOP: Where is digit? " > /dev/stderr
exit 1
fi

awk -v tmfname="${tmp_major_filename}" -v today_is="${today_is}" -v num_to_grep="${num_to_grep}" -v rex_log="${exlog_log}" -v to_grep="${to_grep}" '{
# Проверяем пользовательский ввод. Устанавливаем переменную w_show.
if ($0 ~ /^[1-3]$/) {
w_show=$0
exit
} else {
printf "\n\t%s\n\n", msg_wrong_number > err_log
split("",QUEUEARR)
split("",REJARRAY)
was_error = 1
exit 1
}
} BEGIN {
q_cn = 0
r_cn = 0
err_log = "/dev/stderr"

# Сообщения
msg_nothing_to_show = "STOP: Nothing to show."
msg_no_records = "STOP: No Records."
msg_wrong_number = "STOP: Wrong number."
msg_header_major = "SUCCESS"
msg_header_minor = "FAILURE"
msg_header_summ = "SUMMARY"

# Паттерн очереди
patt_QUEbe = "^[A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9]-[A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9]-[A-Za-z0-9][A-Za-z0-9]$"

# Получаем список файлов лога exim-a, добавляем их в массив, считаем их количество.
cmd_get_file_list=("ls "rex_log"*")
while ((cmd_get_file_list |getline)> 0) {
FILESLIST[++fl_cn] = $0
}
close (cmd_get_file_list)

# Проверяем пользовательский ввод. Получаем имя файла, проверяем заархивирован ли он, устанавливаем необходимые переменные.
if (num_to_grep ~ /^[0-9]+$/ && (num_to_grep <= fl_cn && num_to_grep != 0)) { ex_log = FILESLIST[num_to_grep] tmpfilename_parts = split(FILESLIST[num_to_grep],TMPFILENAME,".") if (TMPFILENAME[tmpfilename_parts] == "gz") { first_grep = ("zgrep -ni \""to_grep"\" "ex_log) second_grep = ("zgrep -f "tmfname" "ex_log) pr_ex_log = ("zcat "ex_log) } else { first_grep = ("grep -ni \""to_grep"\" "ex_log) second_grep = ("grep -f "tmfname" "ex_log) pr_ex_log = ("cat "ex_log) } split("",TMPFILENAME) split("",FILESLIST) } else { printf "\n\t%s\n\n", msg_wrong_number > err_log
was_error = 1
exit 1
}

# Запускаем греп лога екзима. Если в строке в нужном месте есть совпадение с паттерном очереди, и это не реджект,
# добавляем очередь в массив очередей. Иначе номер строки лога в массив номеров строк лога.
while ((first_grep |getline)> 0) {
if (split($0,TMPLINE,":")>0) {
testqueue = substr(TMPLINE[4],4,16)
if (testqueue ~ patt_QUEbe) {
if (substr(TMPLINE[4],21,8) == "rejected") {
REJARRAY[++r_cn] = TMPLINE[1]
} else if ((testqueue in QUEUEARR) == 0) {
QUEUEARR[testqueue]
++q_cn
}
} else {
REJARRAY[++r_cn] = TMPLINE[1]
}

}
split("",TMPLINE)
}
printf "\n"
close (first_grep)

# Считаем и печатаем сколько мы всего нашли. Заодно приглашение ввода номера того что хочется увидеть если чего-то нашли.
printf "\t%s\t%s\t%s\n", "(1)", msg_header_major, q_cn
printf "\t%s\t%s\t%s\n", "(2)", msg_header_minor, r_cn
printf "\t%s\t%s\t%s\n", "(3)", msg_header_summ, (q_cn+r_cn)
if ((q_cn+r_cn) == 0) {
printf "\n\t%s\n\n", msg_nothing_to_show > err_log
split("",QUEUEARR)
split("",REJARRAY)
was_error = 1
exit 1
} else {
printf "\n\t%s\t" , "Enter Digit:"
}
} END {
if (was_error == 1) {
exit 1
}

# Получаем значение год-месяц-день из лога который будем показывать.
pr_ex_log | getline
close (pr_ex_log)
actdte = substr($0,1,10)

# Устанавливаем переменные - элементы декора.
header_major = sprintf("%s%s%s%s%s", "-------------------------------- ",msg_header_major," ---------------------------------------- ",actdte," ----------------------")
header_minor = sprintf("%s%s%s%s%s", "-------------------------------- ",msg_header_minor," ---------------------------------------- ",actdte," ----------------------")
footer = sprintf("%s%s%s\n", "------------------------------------------------------------------------------- ",actdte," ----------------------")
splitter_completed = sprintf("%s", "+ ------------ c -- o -- m -- p -- l -- e -- t -- e -- d ---------------------- +")

cmd_more = "more"

# Пользователь возжелал увидеть очереди.
if (w_show == 1) {
if (q_cn == 0) {
split("",QUEUEARR)
split("",REJARRAY)
printf "\n\t%s\n\n", msg_no_records > err_log
exit 1
} else {
y = 1
z = 0
# Сбрасываем содержимое массива очередей во временный файл
for (tq in QUEUEARR) {
print (tq) >> tmfname
}
print(header_major)
# Грепаем лог екзима используя временный файл в качестве файла паттернов.
while ((second_grep |getline)> 0) {
if (length($0) == 46) {
if (substr($0,38,9) == "Completed") {
print (splitter_completed) | cmd_more
} else {
print(substr($0,12)) | cmd_more
}
} else {
print(substr($0,12)) | cmd_more
}
}
close (second_grep)
close (cmd_more)
print(footer)
}

# Пользователь возжелал увидеть отлупы.
} else if (w_show == 2) {
if (r_cn == 0) {
split("",QUEUEARR)
split("",REJARRAY)
printf "\n\t%s\n\n", msg_no_records > err_log
exit 1
} else {
y = 1
z = 0
print(header_minor)
while ((pr_ex_log |getline)> 0) {
z++
if(z == REJARRAY[y]){
print(substr($0,12)) | cmd_more
y++
}
}
close (pr_ex_log)
close (cmd_more)
print(footer)
}

# Пользователь возжелал увидеть все.
} else if (w_show == 3) {
if (r_cn != 0) {
y = 1
z = 0
print(header_minor)
while ((pr_ex_log |getline)> 0) {
z++
if(z == REJARRAY[y]){
print(substr($0,12)) | cmd_more
y++
}
}
close (pr_ex_log)
close (cmd_more)
print(footer)
}
if (q_cn != 0) {
y = 1
z = 0
# Сбрасываем содержимое массива очередей во временный файл
for (tq in QUEUEARR) {
print (tq) >> tmfname
}
print(header_major)
# Грепаем лог екзима используя временный файл в качестве файла паттернов.
while ((second_grep |getline)> 0) {
if (length($0) == 46) {
if (substr($0,38,9) == "Completed") {
print (splitter_completed) | cmd_more
} else {
print(substr($0,12)) | cmd_more
}
} else {
print(substr($0,12)) | cmd_more
}
}
close (second_grep)
close (cmd_more)
print(footer)
}
}
split("",QUEUEARR)
split("",REJARRAY)
}' -

rm -f "${tmp_major_filename}"

# Настройки логгирования в конфиге exim:
# --
# log_file_path = /var/log/exim/exim_%s.log
# write_rejectlog = no
#
# log_selector = \
# +all_parents \
# +connection_reject \
# -host_lookup_failed \
# -incoming_interface \
# -lost_incoming_connection \
# +received_sender \
# +received_recipients \
# +smtp_confirmation \
# +smtp_syntax_error \
# +smtp_protocol_error \
# -queue_run
#
# syslog_timestamp = yes
#
# --
#
# Ver 1.1
#

Рейтинг 3.00/5

Добавить комментарий

Ваш адрес email не будет опубликован.