Um programa de primeiro plano chamado por um daemon deve dividir o log entre stderr e stdout com base nos níveis de severidade?

6

Geralmente, as mensagens de log são gravadas no stderr. Eu estou querendo saber se é uma boa idéia / prática para dividir as mensagens de log para que erros e avisos vão para stderr enquanto mensagens de debug / informational / notice vão para stdout em vez disso? Ou isso é irrelevante, dado que muitos processos de registro dedicados apenas lêem o stdin de qualquer maneira, o que requer que as mensagens de log de origem em stderr e stdout sejam combinadas e redirecionadas para o stdin do logger.

[Atualização]

As duas respostas abaixo mencionadas syslog, eu acho que preciso esclarecer a configuração em detalhes.

Os processos daemon que eu perguntei estão sendo executados em primeiro plano por si mesmos. A daemonização é gerenciada por processos de supervisão, como runit ou supervisord . Em ambos os casos, stderr e stdout dos processos daemon serão capturados pelos processos de supervisão, e é o trabalho dos processos de supervisão decidir como e onde armazenar os logs (pode ser syslog ou em algum outro lugar na rede sobre UDP) . Os processos daemon não precisam se preocupar com o que e onde escrever logs, pois eles apenas escrevem para stdout / stderr.

No caso de runit , seu recurso de criação de log svlogd lerá de seu stdin para as mensagens de log redirecionadas, que são stderr / stdout combinadas do processo do daemon gerenciado. Quanto ao supervisord , ele pode gravar stderr e stdout para separar os arquivos de log.

Então, nessas configurações específicas, é uma boa prática dividir logs entre stderr e stdout ou apenas escrever para um deles?

    
por Rio 10.03.2013 / 07:18

4 respostas

3

Eu não sugeriria misturar o stdout e stderr dentro do seu programa, mas como você lida com ele fora é com você. stdout foi destinado a dados processados destinados a um pipeline, enquanto stderr é especificamente para mensagens que não são de dados. Isso torna certos comportamentos possíveis, como o processamento em lote, sem alterar o comportamento interativo existente. Seu caso é diferente - há uma boa chance de que stdout signifique pouco ou nada.

Como runit tem uma abordagem ligeiramente diferente do log por svlog , e o serviço que você está escrevendo provavelmente não será desassossificado (o que neste caso significa "desconectar de um tty"), então depende de você se você quiser capturar tudo em um único log, ou não, através do script /etc/sv/<servicename>/run . Na maior parte, a maioria dos scripts de execução usa

exec 2>&1 

para fundir os dois fluxos juntos, pois a maioria dos serviços não repassa dados via stdout. Se você quiser usar svlog , precisará criar um script em /etc/sv/<servicename>/log/run com o comando apropriado para iniciá-lo. Provavelmente parece semelhante (mas não exatamente):

#!/bin/sh
exec 2>&1
exec svlog -tt main

onde main é um link simbólico para um diretório de registro.

    
por 20.08.2014 / 21:30
4

Primeiro, algo importante a esclarecer: STDOUT e STDERR raramente são relevantes no contexto de um processo daemon depois de iniciado com sucesso, a menos que você esteja invocando um com uma opção de depuração.

O ponto principal de um daemon é que ele precisa se desassociar de ter um terminal de controle, para que ele possa persistir após o logout. Uma vez que não há terminal, todas as mensagens precisam ser enviadas para um daemon syslog ou um arquivo de log gerenciado diretamente pelo processo.

Se você não está realmente se referindo a daemons, e realmente se refere a qualquer shell script ou similar que você esteja escrevendo, então a lógica deve ser geralmente esta:

  • STDOUT : Tudo o que você quer que seja preso por canos ou redirecionamento de saída básico.
  • STDERR : mensagens "fora da banda". Coisas que você quer atingir o terminal de alguém, mesmo que estejam fazendo algum tipo de redirecionamento. (por isso, por que estão associados a erros) Deixe o usuário decidir se também deseja redirecionar essas mensagens, ou seja, redirecionando STDERR para STDIN como você mencionou.
por 10.03.2013 / 07:44
3

Se for um daemon, recomendo usar a interface syslog para registrar suas mensagens diretamente nos logs. Execute "man 3 syslog" para informações. Se necessário, seu programa também pode ter uma opção de depuração (com um parâmetro que especifica a prioridade) que instrui o programa daemon a não executar em segundo plano e também a efetuar login no stderr.

Eu escreveria uma função de registro que recebe uma prioridade e uma string como argumento. Ele deve chamar syslog () para registrar a mensagem corretamente e, se a prioridade for maior ou igual ao valor de prioridade de depuração global, enviar a mensagem para stderr e também syslog (). Chame syslog(..., "%s", msg) para evitar que os caracteres percentuais da mensagem sejam corrompidos. (Ou faça sua função pegar um número variável de argumentos e passar o arglist para vsyslog ().)

Certifique-se de chamar openlog(..., LOG_PID, LOG_DAEMON) na inicialização do seu programa. Você poderia adicionar | LOG_PERROR após LOG_DAEMON se você estivesse no modo de depuração, o que evitaria ter que gravar a função de registro mencionada acima. Mas você perderá a capacidade de filtrar com base na prioridade.

Você pode (se estiver usando o Ubuntu) precisar configurar o /etc/rsyslog.conf para garantir que as mensagens do daemon estejam sendo registradas.

PS - Use o comando logger se o seu daemon for um script de shell

    
por 10.03.2013 / 07:45
2

Eu não acho que você deveria usar stdout e stderr para logar. Se você tiver mensagens de log com gravidades diferentes, elas devem ser marcadas com um prefixo para facilitar a filtragem / classificação delas usando svlogd .

Eu diria que usar stdout e stderr para logar violaria o princípio da menor surpresa.

    
por 03.09.2014 / 00:20