A processar um item do syslog

Este é o aspecto de uma entrada:

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

estou a escrever uma pequena aplicação para processar itens como este e enviar uma mensagem formatada para a administração. Estou escrevendo em Perl e encontrei a função split() que é exatamente o que eu estou procurando:

my @tmp = split(/ /, $string, 4);
@tmp = {$date, $hostname, $facility, $message)
É o que espero conseguir. Split () pode lidar com os espaços na parte da mensagem $porque eu limite a quantidade de "palavras" para dividir. No entanto,os espaços na parte da data de $afastam-no. Há alguma maneira limpa que eu possa fazer com que estas variáveis representem o que é suposto representarem?

Eu sei que eu poderia usar substr () para pegar os primeiros 15 caracteres (a data), em seguida, usar split () e limitá-lo a 3 palavras em vez de 4, em seguida, pegar todas as minhas cordas de lá. Mas há uma maneira mais elegante de fazer isto?

Author: n0pe, 2011-08-08

4 answers

Se a unicidade for importante para a elegância, divide-se em espaços que não são seguidos por um dígito:

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

Mas faz mais sentido usar uma combinação de split e unpack para responder à necessidade:
my ( $timeStamp, $log ) = unpack 'A15 A*', $string;

my ( $host, $facility, $msg ) = split /\s+/, $log;
 4
Author: Zaid, 2011-08-08 14:15:11

É Analisar::Syslog fazer o que você precisa sem o i-try-this-regexp-oh-it-does-not-work-ok-i-hcanged-and-it-works-oh-not-always-hmm-let-me-try-that-much-better-yay-oh-no-it-broke-let-me-try-this-one-has-nobody-done-this-ainda sentindo?

 2
Author: , 2012-12-03 12:53:22

Utilize uma expressão regular. Aqui está um exemplo simples:

$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";
}
 1
Author: dogbane, 2011-08-08 13:34:49

Pergunta antiga, mas eu experimentei um problema semelhante e rectificado pela formatação das minhas mensagens syslog (daí o rsyslog modificado.conf)

Criei o modelo do rsyslog da seguinte forma

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")
}

Depois

Configurei o meu modelo personalizado por omissão, adicionando

    $ActionFileDefaultTemplate CustomisedTemplate.

A (r)syslog.conf

Eu também poderia criar o filtro para o meu programa (logger), que irá usar o modelo e redirecionar a mensagem criada pelo programa ( logger) para separar o arquivo. Para conseguir isso, eu Adicionado

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

A (r)syslog.conf

Por isso, no final, a minha entrada no syslog parece-se com o
Jan 26 20:53:31 2016;hostname;logger:;System rebooted for hard disk upgrade
O que é fácil de processar.
 1
Author: taiko, 2017-07-24 11:36:51