Estamos criando um novo aplicativo e eu gostaria de incluir o log estruturado. Minha configuração ideal seria algo como Serilog
para o nosso código C # e Bunyan
para o nosso JS. Eles se alimentariam fluentd
e poderiam sair para várias coisas, pensei inicialmente elasticsearch + kibana
. Já temos um banco de dados MySQL, então, a curto prazo, estou mais interessado em obter a configuração do Serilog + Bunyan e os desenvolvedores para usá-lo, e podemos fazer logon no MySQL enquanto levamos um pouco mais de tempo trazendo o fluente e o resto.
No entanto, um dos nossos codificadores mais experientes prefere fazer algo como: log.debug("Disk quota {0} exceeded by user {1}", quota, user);
using log4net
e, em seguida, apenas executar instruções select no MySQL como:SELECT text FROM logs WHERE text LIKE "Disk quota";
Dito isto, qual abordagem é melhor e / ou que coisas precisamos considerar ao escolher o tipo de sistema de registro?
fonte
Respostas:
Existem dois avanços fundamentais na abordagem estruturada que não podem ser emulados usando logs de texto sem (às vezes níveis extremos de) esforço adicional.
Tipos de Eventos
Quando você escreve dois eventos com o log4net, como:
Isso produzirá texto semelhante:
Mas, no que diz respeito ao processamento da máquina, são apenas duas linhas de texto diferente.
Você pode encontrar todos os eventos de "cota de disco excedida", mas o caso simplista de procurar eventos
like 'Disk quota%'
cairá assim que outro evento ocorrer:O registro de texto descarta as informações que temos inicialmente sobre a origem do evento, e isso deve ser reconstruído ao ler os registros geralmente com expressões de correspondência cada vez mais elaboradas.
Por outro lado, quando você escreve os dois eventos Serilog a seguir :
Eles produzem saída de texto semelhante à versão log4net, mas nos bastidores, o
"Disk quota {Quota} exceeded by user {Username}"
modelo de mensagem é carregado pelos dois eventos.Com um coletor apropriado, você pode escrever consultas posteriormente
where MessageTemplate = 'Disk quota {Quota} exceeded by user {Username}'
e obter exatamente os eventos em que a cota de disco foi excedida.Nem sempre é conveniente armazenar o modelo de mensagem inteiro com cada evento de log; portanto, alguns afundamentos colocam o modelo de mensagem em hash em um
EventType
valor numérico (por exemplo0x1234abcd
), ou você pode adicionar um enricher ao pipeline de log para fazer isso sozinho .É mais sutil que a próxima diferença abaixo, mas extremamente poderosa ao lidar com grandes volumes de log.
Dados Estruturados
Novamente, considerando os dois eventos sobre o uso do espaço em disco, pode ser fácil usar logs de texto para consultar um usuário específico
like 'Disk quota' and like 'DTI-Matt'
.Porém, os diagnósticos de produção nem sempre são tão diretos. Imagine que seja necessário encontrar eventos em que a cota de disco excedida esteja abaixo de 125 MB?
Com o Serilog, isso é possível na maioria dos sumidouros usando uma variante de:
Construir esse tipo de consulta a partir de uma expressão regular é possível, mas torna-se cansativo rápido e normalmente acaba por ser uma medida de último recurso.
Agora adicione a isso um tipo de evento:
Você começa a ver aqui como esses recursos se combinam de maneira direta para fazer com que a depuração da produção com logs pareça uma atividade de desenvolvimento de primeira classe.
Um benefício adicional, talvez não tão fácil de prevenir antecipadamente, mas depois que a depuração da produção foi removida da área de hackers regex, os desenvolvedores começam a valorizar os logs muito mais e a ter mais cuidado e consideração ao escrevê-los. Melhores registros -> aplicativos de melhor qualidade -> mais felicidade ao redor.
fonte
Quando você está coletando logs para processamento, seja para analisar em algum banco de dados e / ou pesquisar os logs processados posteriormente, o uso do log estruturado torna alguns dos processos mais fáceis / eficientes. O analisador pode tirar proveito da estrutura conhecida ( por exemplo , JSON, XML, ASN.1, qualquer que seja) e usar máquinas de estado para analisar, em oposição a expressões regulares (que podem ser computacionalmente caras (relativamente) para compilar e executar). A análise de texto de forma livre, como a sugerida pelo seu colega de trabalho, tende a depender de expressões regulares e a não mudar o texto . Isso pode tornar a análise de texto de forma livre bastante frágil ( ou seja, a análise está fortemente acoplada ao texto exato no código).
Considere também o caso de pesquisa / pesquisa, por exemplo :
LIKE
condições requerem comparações com cadatext
valor de linha; novamente, isso é relativamente computacionalmente caro, principalmente quando os curingas são usados:Com o log estruturado, sua mensagem de log relacionada ao erro de disco pode se parecer com isso no JSON:
Os campos desse tipo de estrutura podem ser mapeados facilmente, por exemplo , nomes de colunas da tabela SQL, o que significa que a pesquisa pode ser mais específica / granular:
Você pode colocar índices nas colunas cujos valores você espera pesquisar / procurar com freqüência, desde que não use
LIKE
cláusulas para esses valores de coluna . Quanto mais você puder dividir sua mensagem de log em categorias específicas, mais direcionado poderá fazer sua pesquisa. Por exemplo, além doerror_type
campo / coluna no exemplo acima, você pode criar um par"error_category": "disk", "error_type": "quota"
ou algo assim.Quanto mais estrutura que você tem em suas mensagens de log, os sistemas mais a sua análise / busca (como
fluentd
,elasticsearch
,kibana
) pode tirar vantagem dessa estrutura, e executar suas tarefas com maior velocidade e menos CPU / memória.Espero que isto ajude!
fonte
Você não encontrará muitos benefícios com o log estruturado quando o aplicativo criar algumas centenas de mensagens de log por dia. Definitivamente, você terá quando tiver centenas de mensagens de log por segundo provenientes de vários aplicativos implantados.
Relacionado, a configuração em que as mensagens de log terminam na pilha ELK também é apropriada para a escala em que o log no SQL se torna um gargalo.
Vi a configuração do "registro e pesquisa básicos" com SQL
select .. like
e regexps chegar ao limite onde desmorona - há falsos positivos, omissões, código de filtro horrível com bugs conhecidos difíceis de manter e ninguém quer tocar, novas mensagens de log que não seguem as premissas do filtro, relutância em tocar as instruções de log no código, para que não quebrem relatórios etc.Portanto, vários pacotes de software estão surgindo para lidar com esse problema de uma maneira melhor. Existe o Serilog, ouvi dizer que a equipe do NLog está olhando para ele , e escrevemos
StructuredLogging.Json
para o Nlog , também vejo que as novas abstrações de log de núcleo do ASP.Net "possibilitam que os provedores de log implementem ... o log estruturado".Um exemplo com StructuredLogging. Você faz logon em um logger NLog como este:
Esses dados estruturados vão para kibana. O valor
1234
é armazenado noOrderId
campo da entrada do log. Você pode pesquisar usando a sintaxe de consulta do kibana, por exemplo, todas as entradas de log em que@LogType:nlog AND Level:Error AND OrderId:1234
.Message
eOrderId
agora são apenas campos que podem ser pesquisados por correspondências exatas ou inexatas, conforme necessário, ou agregados por contagens. Isso é poderoso e flexível.Das práticas recomendadas do StructuredLogging :
fonte