1

Тема: Bash/Perl: logmerge - программа слияния лог-файлов

Казалось бы простая задача - слить несколько лог-файлов в один и отсортировать. Однако задача несколько усложняется тем, что одна запись лог-файла не равна одной строке, то есть запись может занимать несколько строк. Это хорошо известно тем, кто работал с java приложениями. Там стектрейсы могу занимать по два десятка строк, а это одна запись.

В интернете попадались аналоги, но либо они были несвободными, либо ориентированы на специфический формат записей лог-файлов (например только веб-серверов), либо возможность работать с многострочными записями была не очевидна. Подгонка под наши нужды возможно заняла бы больше времени чем разработка с нуля.

Объединение и хронологическая сортировка файлов требуется для анализа событий двух и более взаимодействующих процессов. При простой сортировке двух файлов соседние строки одной записи могут потеряться.
Другая проблема заключается в том, что время двух записей может совпадать (например две записи от нескольких нитей, threads, или две последовательных записи одной нити). В данном случае важно сохранить последовательность записей в пределах одного файла.

Скрипт был написан. Для его работы требуются Bash+Perl. Требуется gzip для чтения сжатых файлов. То есть, скрипт, в первую очередь ориентирован для работы в Unix. Также он может работать и в Windows при наличии установленного Cygwin. Никаких специфических требований к библиотекам Perl нет. Разрабатывалось и тестировалось в следующих конфигурациях:

Windows Vista+Cygwin
Bash 3.2.49
Perl 5.10.0

Red Hat Linux
Bash 2.05
Perl 5.8.9

Хотя скрипт писался для собственных нужд, я обнаружил, что его можно расширить для большинства текстовых лог-файлов. В качестве бонуса я добавил пару опций, которые позволяют работать с логами Apache (access.log и error.log). Далее несколько примеров.

1.

./logmerge --apache-error ./error.log* > all.log

Объединить все error.log* файлы, включая упакованные командой gzip и сохранить в один результирующий файл. Опция --apache-error рассматривает, что строки содержат временную метку в следующем фоормате

[Fri Apr 23 22:14:21 2010] <...>

2.

find /export/home/ -name 'access.log' | xargs ./logmerge -f -n --apache-access > all.log

найти все последние access.log файлы и объединить их в один отсортировав записи хронологически. В начале каждой строки добавляется имя исходного файла и номер строки (!) в нем. Временная метка определяется так:

<...> [15/Feb/2008:14:18:49 +0300] <...>

3.

./logmerge -f -n log/*.log | gzip -c > all.gz

Последний пример - образец того ради чего все это затевалось. Скрипт аналогично предыдущему примеру "сливает" несколько файлов в один добавляя в начало строки имя файла и номер строки. Далее результат передается команде gzip, которая создает сжатый файл. Лог-файл может содержать строки подобные этой:

05/21/2012 21:54:41.070 <the rest of the entry>
java.lang.Throwable
        at boo.hoo.StackTrace.bar(StackTrace.java:223)
        at boo.hoo.StackTrace.foo(StackTrace.java:218)
        at boo.hoo.StackTrace.main(StackTrace.java:54)
...

Здесь описана лишь часть опций скрипта. Архив скрипта доступен на странице http://code.google.com/p/logmerge/. Критика и пожелания приветствуются.

( 2 * b ) || ! ( 2 * b )

2

Re: Bash/Perl: logmerge - программа слияния лог-файлов

Немного поправил код и обновил архив на скачивание. Изменения:
-- изменил обработчик скрипта на Bash, вместо старого, но еще существующего на многих системах shell
-- добавлена возможность чтения архивных файлов .gz/.bz2
-- корректная обработка входных аргументы - имен файлов

( 2 * b ) || ! ( 2 * b )

3

Re: Bash/Perl: logmerge - программа слияния лог-файлов

Спасибо... хорошая реализация

4

Re: Bash/Perl: logmerge - программа слияния лог-файлов

можно пример двух файлов ?

Я конечно далек от мысли... (с)

5

Re: Bash/Perl: logmerge - программа слияния лог-файлов

smaharbA пишет:

можно пример двух файлов ?

Уточните вопрос. Каких файлов?

( 2 * b ) || ! ( 2 * b )

6

Re: Bash/Perl: logmerge - программа слияния лог-файлов

выложите два файла лога для примера

Я конечно далек от мысли... (с)

7

Re: Bash/Perl: logmerge - программа слияния лог-файлов

smaharbA
Коллега, прошу прощения за задержку. Вот пример в архиве http://rghost.ru/39881325:

исходные файлы
localhost/error.log
my/error.log

конечный файл
merged.log

команда
./logmerge -f -n --apache-error localhost/error.log my/error.log > merged.log

( 2 * b ) || ! ( 2 * b )