Estamos creando una nueva aplicación y me gustaría incluir el registro estructurado. Mi configuración ideal sería algo así como Serilog
nuestro código C # y Bunyan
nuestro JS. Estos alimentarían fluentd
y luego podrían salir a cualquier cantidad de cosas, estaba pensando inicialmente elasticsearch + kibana
. Ya tenemos una base de datos MySQL, por lo que a corto plazo estoy más interesado en obtener la configuración de Serilog + Bunyan y los desarrolladores para usarla, y podemos iniciar sesión en MySQL mientras tomamos un poco más de tiempo para incorporar fluidez y el resto.
Sin embargo, uno de nuestros codificadores más experimentados preferiría hacer algo como: log.debug("Disk quota {0} exceeded by user {1}", quota, user);
usar log4net
y luego ejecutar sentencias select contra MySQL como:SELECT text FROM logs WHERE text LIKE "Disk quota";
Dicho esto, ¿qué enfoque es mejor y / o qué cosas debemos tener en cuenta al elegir el tipo de sistema de registro?
fuente
Respuestas:
Hay dos avances fundamentales con el enfoque estructurado que no se pueden emular usando registros de texto sin (a veces niveles extremos) de esfuerzo adicional.
Tipos de eventos
Cuando escribe dos eventos con log4net como:
Estos producirán un texto similar:
Pero, en lo que respecta al procesamiento automático, son solo dos líneas de texto diferente.
Es posible que desee encontrar todos los eventos de "cuota de disco excedida", pero el caso simplista de buscar eventos
like 'Disk quota%'
se reducirá tan pronto como ocurra otro evento con el siguiente aspecto:El registro de texto desecha la información que inicialmente tenemos sobre el origen del evento, y esto debe reconstruirse al leer los registros, generalmente con expresiones de coincidencia cada vez más elaboradas.
Por el contrario, cuando escribe los siguientes dos eventos Serilog :
Estos producen una salida de texto similar a la versión de log4net, pero detrás de escena, ambos eventos llevan la
"Disk quota {Quota} exceeded by user {Username}"
plantilla de mensaje .Con un receptor apropiado, más tarde puede escribir consultas
where MessageTemplate = 'Disk quota {Quota} exceeded by user {Username}'
y obtener exactamente los eventos donde se superó la cuota de disco.No siempre es conveniente almacenar la plantilla de mensaje completa con cada evento de registro, por lo que algunos hunden la plantilla de mensaje en un
EventType
valor numérico (por ejemplo0x1234abcd
), o puede agregar un enriquecedor a la canalización de registro para hacerlo usted mismo .Es más sutil que la siguiente diferencia a continuación, pero es enormemente poderosa cuando se trata de grandes volúmenes de registro.
Datos estructurados
Una vez más, considerando los dos eventos sobre el uso del espacio en disco, puede ser bastante fácil usar registros de texto para consultar a un usuario en particular
like 'Disk quota' and like 'DTI-Matt'
.Pero, el diagnóstico de producción no siempre es tan sencillo. ¿Imagina que es necesario encontrar eventos donde la cuota de disco excedida fuera inferior a 125 MB?
Con Serilog, esto es posible en la mayoría de los sumideros utilizando una variante de:
La construcción de este tipo de consulta a partir de una expresión regular es posible, pero se cansa rápido y por lo general termina siendo una medida de último recurso.
Ahora agregue a esto un tipo de evento:
Aquí comienza a ver cómo estas capacidades se combinan de manera directa para hacer que la depuración de producción con registros se sienta como una actividad de desarrollo de primera clase.
Un beneficio adicional, quizás no tan fácil de prevenir por adelantado, pero una vez que la depuración de producción se ha eliminado de la tierra de la piratería de expresiones regulares, los desarrolladores comienzan a valorar mucho más los registros y a tener más cuidado y consideración al escribirlos. Mejores registros -> aplicaciones de mejor calidad -> más felicidad por todas partes.
fuente
Cuando recopila registros para procesar, ya sea para analizar en alguna base de datos y / o buscar en los registros procesados más adelante, el uso del registro estructurado hace que parte del procesamiento sea más fácil / más eficiente. El analizador puede aprovechar la estructura conocida ( por ejemplo , JSON, XML, ASN.1, lo que sea) y usar máquinas de estado para el análisis, a diferencia de las expresiones regulares (que pueden ser computacionalmente caras (relativamente) compilar y ejecutar). El análisis de texto de forma libre, como el sugerido por su compañero de trabajo, tiende a depender de expresiones regulares y a que el texto no cambie . Esto puede hacer que el análisis de texto de forma libre sea bastante frágil ( es decir, el análisis está estrechamente acoplado al texto exacto en el código).
Considere también el caso de búsqueda / búsqueda, por ejemplo :
LIKE
las condiciones requieren comparaciones con cadatext
valor de fila; De nuevo, esto es relativamente costoso desde el punto de vista computacional, particularmente cuando se usan comodines:Con el registro estructurado, su mensaje de registro relacionado con errores de disco podría verse así en JSON:
Los campos de este tipo de estructura pueden mapearse con bastante facilidad, por ejemplo , a los nombres de columna de la tabla SQL, lo que significa que la búsqueda puede ser más específica / granular:
Puede colocar índices en las columnas cuyos valores espera buscar / buscar con frecuencia, siempre que no utilice
LIKE
cláusulas para esos valores de columna . Cuanto más pueda dividir su mensaje de registro en categorías específicas, más específico podrá hacer su búsqueda. Por ejemplo, además delerror_type
campo / columna en el ejemplo anterior, podría hacer incluso be"error_category": "disk", "error_type": "quota"
o somesuch.La mayor estructura que tiene en sus mensajes de registro, los sistemas más su análisis sintáctico / búsqueda (como
fluentd
,elasticsearch
,kibana
) puede tomar ventaja de esta estructura, y llevar a cabo sus tareas con mayor rapidez y menos CPU / memoria.¡Espero que esto ayude!
fuente
No encontrará muchos beneficios del registro estructurado cuando su aplicación cree unos cientos de mensajes de registro por día. Definitivamente lo hará cuando tenga unos cientos de mensajes de registro por segundo provenientes de muchas aplicaciones diferentes implementadas.
Relacionado, la configuración donde los mensajes de registro terminan en ELK Stack también es apropiada para la escala en la que el registro en SQL se convierte en un cuello de botella.
He visto la configuración de "inicio de sesión y búsqueda básicos" con SQL
select .. like
y expresiones regulares llevadas a sus límites donde se desmorona: hay falsos positivos, omisiones, código de filtro horrible con errores conocidos que es difícil de mantener y nadie quiere tocar, nuevos mensajes de registro que no siguen los supuestos del filtro, renuencia a tocar las declaraciones de registro en el código para que no rompan los informes, etc.Por lo tanto, están surgiendo varios paquetes de software para abordar este problema de una mejor manera. Está Serilog, escuché que el equipo de NLog lo está mirando y escribimos
StructuredLogging.Json
para Nlog , también veo que las nuevas abstracciones de registro de ASP.Net "hacen posible que los proveedores de registro implementen ... registro estructurado".Un ejemplo con StructuredLogging. Inicia sesión en un registrador NLog como este:
Estos datos estructurados van a kibana. El valor
1234
se almacena en elOrderId
campo de la entrada del registro. Luego puede buscar usando la sintaxis de consulta kibana para, por ejemplo, todas las entradas de registro donde@LogType:nlog AND Level:Error AND OrderId:1234
.Message
yOrderId
ahora son solo campos en los que se pueden buscar coincidencias exactas o inexactas según lo necesite, o agregados para conteos. Esto es poderoso y flexible.De las mejores prácticas de StructuredLogging :
fuente