Eu tenho um feed syslog no formato csv sendo ingerido pelo syslog-ng usando o analisador csv e gravado no disco.
Pelo que entendi, o uso do analisador csv deve fornecer contexto ao syslog-ng para os dados que chegam e qual valor significa o quê. Eu gostaria de usar esse contexto para fazer o syslog-ng aplicar filtros com base nessa lógica.
Por exemplo, eu gostaria de registrar um evento no disco apenas se uma das colunas csv corresponder a um valor específico.
O analisador csvdocumentaçãoparece sugerir que isso deveria ser possível.
Minha configuração se parece um pouco com:
parser p_my_app {
csv-parser(
columns("MY_APP.COLOUR","MY_APP.SIZE","MY_APP.SERIAL_NUMBER")
delimiters(",")
flags(escape-double-char)
);
};
source s_my_app {
syslog(ip(0.0.0.0) port(6514)
transport("tcp")
);
};
filter f_my_app {
match("123456" value("MY_APP.SERIAL_NUMBER") );
};
destination d_my_app {
file("/var/log/my_app.log"
create_dirs(yes)
);
};
log {
source(s_my_app);
filter(f_my_app);
parser(p_my_app);
destination(d_my_app);
};
Porém, parece que por mais que eu tente, a partida nunca dá certo. Aqui está a saída de depuração do sylog-ng com essa configuração:
Incoming log entry; line='<14>1 2017-01-18T17:46:38+11:00 hostname - - - red,large,123456
'
Filter rule evaluation begins; rule='f_my_app', location='/etc/syslog-ng/conf.d/my-app.conf:16:18'
Filter node evaluation result; result='not-match'
Filter rule evaluation result; result='not-match', rule='f_my_app', location='/etc/syslog-ng/conf.d/my-app.conf:16:18'
Eu (espero?) Estou perdendo algo realmente óbvio, mas não consigo encontrar nenhum exemplo completo on-line depois de horas pesquisando no Google, apenas trechos que parecem nunca funcionar. Alguém é capaz de ver o que estou fazendo de errado e/ou fornecer um exemplo completo de trabalho?
Responder1
Bem, como sempre acontece, passo uma semana resolvendo um problema, desisto, decido procurar ajuda - e então descubro a solução sozinho uma hora depois.
Meu problema era a ordem dos itens na log()
declaração. Especificamente, a parser()
linhaDEVEestar antes da filter()
declaração.
Na verdade, odocumentação(que devo ter lido umas 10 vezes e perdido) afirma que:
Observação A ordem dos filtros, regras de reescrita e analisadores na instrução de log é importante, pois eles são processados sequencialmente.
Então, o código de trabalho é usar:
log {
source(s_my_app);
parser(p_my_app);
filter(f_my_app);
destination(d_my_app);
};
Além disso, outra coisa a observar é que, match()
na verdade, deveria ser um regex; portanto, para maior clareza, também atualizei o filtro para:
filter f_my_app {
match("123456" value("MY_APP.SERIAL_NUMBER") type("string"));
};
Com o syslog-ng agora reportando:
Incoming log entry; line='<14>1 2017-01-18T17:46:38+11:00 hostname - - - red,large,123456
'
Message parsing complete; result='1', rule='p_my_app', location='/etc/syslog-ng/conf.d/my-app.conf:14:2'
Filter rule evaluation begins; rule='f_my_app', location='/etc/syslog-ng/conf.d/my-app.conf:16:18'
Filter node evaluation result; result='match'
Filter rule evaluation result; result='match', rule='f_my_app', location='/etc/syslog-ng/conf.d/my-app.conf:16:18'