Por que o rsyslog pode estar registrando mensagens duplicadas do diário do systemd?
Estou ciente dos problemas conhecidos envolvendo a corrupção do diário do systemd (veja, por exemplo, o aviso na seção "Propósito" aqui: https://www.rsyslog.com/doc/configuration/modules/imjournal.html ), mas não acho que seja esse o problema que estou encontrando. Estou executando o Ubuntu 24.04, rsyslog 8.2312.0-3ubuntu9 e systemd 255.4-1ubuntu8.4.
Tenho vários hosts executando um aplicativo chamado "foobar" como um serviço systemd e registrando no diário systemd. Também executo o rsyslog como um serviço systemd e ele é configurado para encaminhar os logs foobar no formato JSON do diário systemd para um servidor de registro central. A configuração do rsyslog em cada host se parece com:
module(load="imjournal" StateFile="journalState" IgnorePreviousMessages="on")
module(load="mmjsonparse")
template(name="foobarJSON" type="string" string="%TIMESTAMP% %HOSTNAME% %syslogtag% @cee: %$!all-json%\n" )
if $syslogfacility-text == "user" and $programname == "foobar" then {
user.* action(type="omfwd" target="central-logs.server" port="514" protocol="tcp" template="foobarJSON")
}
Também estou executando o rsyslog como um serviço systemd no servidor de log central e gravando os logs foobar de cada servidor em arquivos locais dentro de um subdiretório separado para cada host. A configuração do rsyslog neste host se parece com:
module(load="imtcp")
input(type="imtcp" address="123.456.789.0" port="514")
template(name="foobarHostLogs" type="string" string="/var/logs/%PROGRAMNAME%/%HOSTNAME%/%$year%/%$month%/%$day%.log")
module(load="builtin:omfile" DirCreateMode="0755")
if $fromhost-ip != '127.0.0.1' then {
action(type="omfile" dynaFile="foobarHostLogs")
& stop
}
Executando journalctl -u foobar em qualquer um dos hosts foobar, não vejo nenhuma mensagem duplicada. No entanto, ao olhar os arquivos de log no servidor de log central, vejo que todas as mensagens estão duplicadas: há pelo menos uma mensagem contendo apenas o campo "msg" do diário systemd (embora às vezes eu veja duas linhas idênticas contendo apenas "msg"), seguidas imediatamente por uma linha com exatamente o mesmo timestamp e valor "msg" mais todos os outros campos de metadados do diário systemd.
Por exemplo (removi vários campos extras da segunda linha abaixo, mas espero que você tenha entendido a ideia):
2024-09-15T00:00:00+00:00 host-a foobar[123456]: @cee: { "msg": "Hello, world!" }
2024-09-15T00:00:00+00:00 host-a foobar[123456]: @cee: { "_TRANSPORT": "journal", "_PID": "123456", "_UID": "1000", "_GID": "1000", "_COMM": "foobar", "_EXE": "\/usr\/local\/bin\/foobar", "_CMDLINE": ".\/foobar", "_CAP_EFFECTIVE": "0", "_SELINUX_CONTEXT": "unconfined\n", "MESSAGE": "Hello, world!", "msg": "Hello, world!" }
Parece que você pode ter ambos os métodos de encaminhamento de syslog configurados nos hosts clientes – além de ler logs via imjournal (que fornece todos os metadados), ele provavelmente também recebe os mesmos logs via imuxsock em /run/systemd (o método de encaminhamento legado sem metadados). Certifique-se de que
ForwardToSyslog=
esteja desabilitado em seu journald.conf.Ok, consegui descobrir. @u1686_grawity estava certo ao dizer que a causa raiz era o rsyslog lendo mensagens do diário do systemd usando os módulos de entrada
imuxsock
eimjournal
, mas simplesmente desabilitarForwardtoSyslog
ojournald
não foi suficiente para interromper as duplicatas.Em vez disso, tive que configurar o rsyslog para encaminhar apenas a mensagem recebida para
imjournal
o servidor de registro central, adicionando a condição$inputname == "imjournal"
à cláusula if original, ou seja:Além disso, descobri por que estava recebendo essas mensagens vazias: esqueci de invocar a
mmjsonparse
ação para analisar a mensagem de log estruturada e obter todos os campos individuais da mensagem journald, então adicionei essa linha ao meu exemplo de configuração de trabalho acima também.