Разбор записи системного журнала - PullRequest
1 голос
/ 08 августа 2011

Вот как выглядит запись:

Jan 26 20:53:31 hostname logger: System rebooted for hard disk upgrade

Я пишу небольшое приложение для разбора таких записей и отправки по электронной почте красиво отформатированного сообщения администратору. Я пишу на Perl и нашел функцию split (), которая именно то, что я ищу:

my @tmp = split(/ /, $string, 4);
@tmp = {$date, $hostname, $facility, $message)

Это то, что я надеюсь получить. Split () может обрабатывать пробелы в части $ message, потому что я ограничиваю количество «слов» для разделения. Однако пробелы в части $ date отбрасывают его. Есть ли способ, которым я могу заставить эти переменные представлять то, что они должны?

Я знаю, что мог бы использовать substr (), чтобы получить первые 15 символов (дату), затем использовать split () и ограничить его 3 словами вместо 4, а затем взять все мои строки оттуда. Но есть ли более элегантный способ сделать это?

Ответы [ 4 ]

4 голосов
/ 08 августа 2011

Если однострочность важна для элегантности, разделите ее на пробелы, за которыми не следует цифра:

my ( $time, $hostname, $facility, $message ) = split /\s+(?=\D)/, $string, 4;

Но имеет смысл использовать комбинацию split и unpack для удовлетворения потребностей:

my ( $timeStamp, $log ) = unpack 'A15 A*', $string;

my ( $host, $facility, $msg ) = split /\s+/, $log;
2 голосов
/ 03 декабря 2012

делает Parse :: Syslog делает то, что вам нужно, без i-try-this-regexp-oh-it-not-work-ok-i-hcanged-and-it-works- о-не-всегда-хм-дай-мне-попробовать-то-намного-лучше-уа-ой-не-сломал-дай-мне-попробовать-это-один-никто-не-сделал-это-пока-чувствую

1 голос
/ 24 июля 2017

Старый вопрос, но у меня возникла похожая проблема, и она была исправлена ​​путем форматирования сообщений системного журнала (следовательно, изменен rsyslog.conf)

Я создал шаблон rsyslog следующим образом

template(name="CustomisedTemplate" type="list") {
    property(name="timestamp")
    constant(value=" ")
    property(name="$year")
    constant(value=";")
    property(name="hostname")
    constant(value=";")
    property(name="programname")
    constant(value=";")
    property(name="msg" spifno1stsp="on")
    property(name="msg" droplastlf="on")
    constant(value="\n")
}

тогда

Я настроил свой шаблон по умолчанию, добавив

    $ActionFileDefaultTemplate CustomisedTemplate.

to (r) syslog.conf

Я также мог бы создать фильтр для моей программы (регистратор), который будет использовать шаблон и перенаправить сообщение, созданное программой (регистратор), в отдельный файл. Для этого я добавил

    if $programname contains "logger" then /var/logs/logger.err;CustomisedTemplate

to (r) syslog.conf

Так что в конце моя запись в системном журнале выглядит как

Jan 26 20:53:31 2016;hostname;logger:;System rebooted for hard disk upgrade

который довольно легко разобрать.

1 голос
/ 08 августа 2011

Используйте регулярное выражение. Вот простой пример:

$mystring = "Jan 26 20:53:31 hostname logger: System rebooted for hard disk upgrade";
if($mystring =~ m/(\w{3}\s+\d{1,2}\s\d{2}:\d{2}:\d{2})\s([^\s]*)\s([^\s:]*):\s(.*$)/) {
    $date=$1;
    $host=$2;
    $facility=$3;
    $mesg=$4;
    print "Date: $date\nHost: $host\nFacility: $facility\nMesg: $mesg";
}
...