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?
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;
É 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?
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";
}
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 oJan 26 20:53:31 2016;hostname;logger:;System rebooted for hard disk upgrade
O que é fácil de processar.