Eu tenho um aplicativo que deve registrar cada transação. Toda mensagem de log é liberada porque precisamos ter um registro do que ocorreu antes da falha. Meus colegas e eu estávamos curiosos sobre como obter os efeitos de desempenho do buffer, garantindo que a mensagem de log havia saído do processo.
O que criamos é:
- faça um FIFO no qual o aplicativo possa gravar e
- redirecionar o conteúdo desse FIFO para um arquivo regular via
cat
.
Ou seja, o que era normalmente:
app --logfile logfile.txt
é agora:
mkfifo logfifo
cat logfifo &> logfile.txt &
app --logfile logfifo
Existem algumas dicas para essa abordagem? Funcionou quando o testamos, mas queremos ter certeza absoluta de que as mensagens encontrarão o caminho para o arquivo de redirecionamento, mesmo se o aplicativo original travar.
(Não temos o código-fonte para o aplicativo, portanto, as soluções de programação estão fora de questão. Além disso, o aplicativo não grava stdout
, portanto, a canalização direta para um comando diferente está fora de questão. Portanto, syslog
não é uma possibilidade .)
Atualização: eu adicionei uma recompensa. A resposta aceita não envolverá logger
pela simples razão de que nãologger
é isso que perguntei. Como afirma a pergunta original, estou apenas procurando dicas no uso de um FIFO.
Respostas:
Observe que um fifo é normalmente necessário na programação em que a quantidade escrita pode exceder a quantidade lida.
Como tal, um fifo não funcionará perfeitamente como você esperava, mas resolveria o seu principal problema ao introduzir outro.
Existem três advertências possíveis.
Isso significa que o seu problema (emular E / S com buffer em uma gravação sem buffer) será resolvido. Isso ocorre porque o novo 'limite' no seu FIFO se tornará, com efeito, a velocidade de qualquer utilitário que estiver gravando o que está no canal no disco (que provavelmente será E / S em buffer).
No entanto, o gravador fica dependente do seu leitor de log para funcionar. Se o leitor parar de ler de repente, o escritor bloqueará. Se o leitor sair repentinamente (digamos que você fique sem espaço em disco no seu destino), o gravador SIGPIPE e provavelmente sairá.
Outro ponto a ser mencionado é que, se o servidor entrar em pânico e o kernel parar de responder, você poderá perder até 64k de dados que estavam nesse buffer.
Outra maneira de corrigir isso será gravar logs no tmpfs (/ dev / shm no linux) e ajustar a saída para um local de disco fixo. Existem limites menos restritivos à alocação de memória fazendo isso (não 64K, normalmente 2G!), Mas podem não funcionar se o gravador não tiver uma maneira dinâmica de reabrir arquivos de log (você precisaria limpar os logs do tmpfs periodicamente). Se o servidor entrar em pânico nesse método, você poderá perder muito mais dados.
fonte
/dev/shm
. Também tínhamos considerado isso, embora tivesse me esquecido de usartail -f
.O que acontece quando seu
cat logfifo
processo morre, alguém o mata acidentalmente ou alguém acidentalmente o aponta para o local errado?Minha experiência é que o
app
bloqueio e a trava rapidamente. Eu tentei isso com o Tomcat, Apache e alguns aplicativos caseiros pequenos, e tive o mesmo problema. Eu nunca investiguei muito longe, porque ologger
simples redirecionamento de E / S fez o que eu queria. Normalmente, não preciso da integridade do registro, que é o que você está tentando buscar. E como você diz, você não quer logger.Há alguma discussão sobre esse problema no Linux non-blocking fifo (registro sob demanda) .
fonte
Suas opções são bastante limitadas pelo aplicativo, mas o que você testou funcionará.
Fazemos algo semelhante com verniz e varnishncsa aos logs get em algum lugar útil para nós. Temos um fifo e apenas lemos com syslog-ng e enviamos para onde precisamos. Lidamos com cerca de 50 GB e não encontramos nenhum problema com essa abordagem até o momento
fonte
O ambiente é o CentOS e o aplicativo grava em um arquivo ...
Em vez de enviar para um arquivo regular, eu enviaria a saída para o syslog e garantiria que as mensagens do syslog sejam enviadas para um servidor central e também localmente.
Você deve poder usar um script de shell como este:
Você também pode receber entrada (para
logger
) decat
outail -f
para um canal:O único problema é que ele não se diferencia com base na importância da mensagem de log (tudo é AVISO ), mas pelo menos é registrada e também enviada fora do host para um servidor central.
A configuração do syslog depende do servidor que você está usando. Existe
rsyslog
esyslog-ng
(ambos muito capazes).EDIT : Revisado após obter mais informações do pôster.
fonte
stdout
. O sistema operacional é o CentOS (eu havia marcado a questão como linux , mas acho que é fácil perder isso). Todas as mensagens são de igual importância, portanto, não há diferença entre um aviso e um erro neste aplicativo.Slow query detected
eDatabase halted
?Você escreve:
Você tentou fazer logon no "arquivo"
/dev/stdout
? Isso pode permitir que você faça algo como:fonte
Não há nenhum ponto em escrever para um fifo e depois ter outro processo gravá-lo em um arquivo. Basta escrever diretamente no arquivo normalmente e, uma vez que o
write()
retorno, ele esteja nas mãos do kernel; ainda o gravará no disco se o aplicativo falhar.fonte
fsync()
espera que cada gravação atinja o disco, e você NÃO deseja que isso aconteça (risco de perda no caso de uma falha no sistema)?write()
aplicativo retorne, o aplicativo poderá travar como quiser - os dados chegarão ao disco enquanto o kernel não travar.