Eu trabalho na distribuição linux baseada em yocto. Não sou especialista em systemd
e nem em systemd-journald
.
Meu programa C my_c_program
é iniciado na inicialização pelo script my_script.sh
. Abaixo segue o arquivo my_script.sh
:
my_c_program &
echo $! > /dev/shm/my_c_program.pid
O script anterior é iniciado por um serviço. O arquivo de unidade do serviço é chamado start_c_program.service
. Abaixo segue o atendimento da unidade:
[Unit]
Description=Start my_c_program
Requires=...
After=...
Before=...
[Service]
Type=forking
ExecStart=/usr/bin/my_script.sh
PIDFile=/dev/shm/my_c_program.pid
[Install]
WantedBy=multi-user.target
Com esta configuração, todas as instruções printf("message")
presentes em my_c_program
adicionam a string "message"
a systemd-journald
. Eu sei que se eu modificar my_script.sh
para:
my_c_program > /dev/null &
echo $! > /dev/shm/my_c_program.pid
a mensagem on journald
é suprimida, mas a questão é:
por que toda a saída do meu programa C direcionada para stdout é enviada para journald
?
Obrigado
Eu estava pensando que para enviar mensagem para journald
eu tinha que usar a instrução C syslog()
, por exemplo por um código conforme abaixo:
#include<syslog.h>
int main(int argc, char** argv) {
syslog(LOG_INFO, "Start logging");
}
O Systemd conecta a saída padrão dos processos executados ao seu diário. A saída padrão também é herdada por todos os processos filhos, e é por isso que seu programa C imprime coisas no diário. Você pode usar o parâmetro StandardOutput= para redirecionar a saída padrão do seu programa para outro lugar.
Esse é um recurso de design do systemd e, na verdade, é mais comum em softwares modernos.
O design moderno está se afastando do software que decide por si mesmo para onde enviar logs e para permitir que o executor (systemd neste caso) decida o que fazer. O próprio software apenas grava em stdout e stderr. O software em contêiner em execução no Docker ou Kubernetes tem um padrão muito semelhante.
Muitos programas não sabem como escrever em syslog e é um pouco mais complexo do que apenas escrever em stdout/stderr. Syslog nunca foi totalmente onipresente e tais programas podem ter seu stdout/stderr redirecionado para um arquivo de log em var log.
Quando o systemd inicia seu programa, redireciona stdout e stderr para journald substituindo os manipuladores de arquivo do processo antes de executar seu programa.