LINUX.ORG.RU

exim log parsing

 , , , ,


0

2

Hi All!

Подкиньте плз идей как ускорить выполнение этого:

#!/bin/bash

cd /var/log/exim

while read L; do

        # вот тут проблема, как это посчитать с sed/awk/... без использования while/for
        auth=$( echo "$L" | grep -oE "\ A=auth_[a-zA-Z0-9@:_.-]+" )
        foru=( $( echo "$L" | grep -oE "\ for\ .*" | sed "s/\ for\ //") )

        # пример echo
        if [ ${#foru[@]} -gt 10 ]; then
                echo -e "$auth \t ${#foru[@]}"
        fi
        # в результате
        # auth_type:email \t к-во получателей
        # спамеры сразу выделятся в таких рассылках

done < <( grep -E "\ A=auth_[a-zA-Z0-9@:_.-]+" main.log )

на log файлах 300+ Мбайт уже проблемы, ждать по 15 сек не вариант, а надо на 1-2 Гб быть готовым.

Задача скрипта считать количество отправленных писем пользователей, которые прошли авторизацию, и при этом учитывать возможность подстановки большого количества получателей в копию/темную копию(на серверах, где это можно, установлен recipients_max, но на некоторых нельзя). Это проблемная часть из-за времени работы. В итоге, просуммируются вот как-то так - http://prntscr.com/e7qk01. На графике php-mail по пользователям, и общая статистика exim-а, non-smtp тоже раздельно по юзерам, рисуется отдельно. Или будет новый граф. Суть - заметить аномальные пики спамеров.



Последнее исправление: xfiles (всего исправлений: 1)
Ответ на: комментарий от Zmicier

пример строки лога exim которая грепается и «летит» в while:

2017-02-08 16:22:23 1cbT8Z-00069T-7y <= jane@domain.com H=([192.168.0.104]) [12.123.123.150] P=esmtpsa X=TLSv1.2:DHE-RSA-AES256-GCM-SHA384:256 A=auth_cram_md5:jane@domain.com S=7264 id=6AE265CD-BA7D-4676-9825-AF7C5EB7171B@domain.com T="Email subject" from <jane@domain.com> for vincent.tomy@tourism.com

xfiles
() автор топика
Ответ на: комментарий от Zmicier

ps. если получателей несколько, то после for будут все имейлы через пробел, после этого всегда конец строки

xfiles
() автор топика

По моему скромному опыту не надо этого делать. Просто сделай warn ветку в acl с нужными условиями и добавь в неё log_message с префиксом «ПДЫЩЬ», а потом уже парси так как тебе нравится. Иначе погибнишь нах. Ещё варинат, читырить с lookup и писать сразу в mysql базу.

Ну или ещё вариант: делай полноценный парс, пихай в csv или sql базу.

К сожалению логи exim вообще никто никогда не проектировал: это ад, как он есть.

zloelamo ★★★★
()

Не уверен, что правильно понял задачу, т.к. её словесное описание расходится с приведённым кодом на шелле. Предлагаю попробовать такой вариант. (Лог этому скрипту в стандартный ввод.)

#!/usr/bin/gawk -f

/ A=auth_[a-zA-Z0-9@:_.-]+/ {
        match($0, / A=(auth_[a-zA-Z0-9@:_.-]+)/, matches)
        key = matches[1]
        senders[key] += split(gensub(/^.* for /, "", "g", $0), ignore)
}

END {
        for (key in senders) {
                print key "\t" senders[key]
        }
}
unterwulf
()
Последнее исправление: unterwulf (всего исправлений: 1)
Ответ на: комментарий от unterwulf

Можно проще и переносимее.

#!/usr/bin/awk -f

/ A=auth_[a-zA-Z0-9@:_.-]+/ {
        match($0, / A=(auth_[a-zA-Z0-9@:_.-]+)/, matches)
        key = matches[1]
        sub(/^.* for /, "")
        senders[key] += NF
}

END {
        for (key in senders) {
                print key "\t" senders[key]
        }
}

unterwulf
()
Ответ на: комментарий от unterwulf

Перфект

Мой вариант (в топике)

[root@vhost1-de ~]# time { ./get.exim-auth.sh; }
...
real    0m19.600s
user    0m0.674s
sys     0m10.858s

ваш вариант

[root@vhost1-de ~]# time { cat /var/log/exim/main.log | ./get.exim-auth2.sh; }
...
real    0m3.815s
user    0m3.056s
sys     0m0.277s

то что искал! unterwulf заслужил донат :)

unterwulf

словесное описание расходится с приведённым кодом на шелл

Увы, не понял :( «/ A=auth_[a-zA-Z0-9@:_.-]+/» не корректно будет работать ?

xfiles
() автор топика
Ответ на: комментарий от xfiles

[root@vhost1-de ~]# time { cat /var/log/exim/main.log | ./get.exim-auth2.sh; }

Вызывайте просто

time ./get.exim-auth2.sh /var/log/exim/main.log

Увы, не понял :(

В башизмах не силён, но ваш скрипт, как я понимаю, выводит только строки, в которых более 10 получателей, не суммируя значения по отправителям. Т.е. если отправитель разослал десять писем по одному за раз, он в вывод не попадёт.

Словесное описание я понял так, что нужно просуммировать количество писем отправленное каждым пользователем, считая каждого адресата как отдельное письмо. Приведённый мной код на awk так и делает.

unterwulf
()
Ответ на: комментарий от unterwulf

Понял. Да, моя ошибка описания топика и примера, делал echo только тех, кто отправил более 10 писем за раз, чтобы отсеять обычные отправки и посмотреть только «топ» рассылок, и без суммирования писем по отправителям.

xfiles
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.