Registro de mejores prácticas [cerrado]


323

Me gustaría obtener historias sobre cómo las personas manejan el rastreo y el inicio de sesión en aplicaciones reales. Aquí hay algunas preguntas que pueden ayudar a explicar su respuesta.

Marcos

¿Qué marcos usas?

  • log4net
  • System.Diagnostics.Trace
  • System.Diagnostics.TraceSource
  • Bloqueo de aplicación de registro
  • ¿Otro?

Si utiliza el rastreo, ¿utiliza Trace.Correlation.StartLogicalOperation?

¿Escribe este código manualmente o utiliza alguna forma de programación orientada a aspectos para hacerlo? ¿Quieres compartir un fragmento de código?

¿Proporcionan alguna forma de granularidad sobre las fuentes de rastreo? Por ejemplo, WPF TraceSources le permite configurarlos en varios niveles:

  • System.Windows - configuración para todo WPF
  • System.Windows.Animation: anulación específica para Animación.

Oyentes

¿Qué salidas de registro utilizas?

  • Archivos de texto
  • Archivos XML
  • Registro de eventos
  • ¿Otro?

Si utiliza archivos, ¿utiliza registros continuos o solo un archivo? ¿Cómo haces que los registros estén disponibles para que la gente los consuma?

Visita

¿Qué herramientas utilizas para ver los registros?

  • Bloc
  • Cola
  • Visor de eventos
  • Systems Center Operations Manager / Microsoft Operations Manager
  • WCF Service Trace Viewer
  • ¿Otro?

Si está creando una solución ASP.NET, ¿también usa ASP.NET Health Monitoring? ¿Incluye resultados de seguimiento en los eventos del monitor de salud? ¿Qué pasa con Trace.axd?

¿Qué pasa con los contadores de rendimiento personalizados?


3
Sería útil si las personas que cierran preguntas como esta con 300 votos a favor podrían sugerir un formato wiki o publicar en programmers.stackexchange, o Quora si este tipo de pregunta no es bienvenida. Obviamente, la pregunta es realmente muy constructiva, simplemente no se ajusta al criterio que StackOverflow quiere. programmers.stackexchange.com/questions/57064/… tiene 24 votos a favor. ¿Quizás a StackOverflow le falta algo?
Niall Connaughton

Si esta pregunta viola el formato de Preguntas y Respuestas, hay ALGO MAL con el Formato de Preguntas y Respuestas y no con esta pregunta. A veces, la decisión de si una pregunta debe cerrarse debe ser una función de las respuestas proporcionadas, algunas preguntas abiertas invitan al debate, pero otras invitan a los usuarios a proporcionar contenido valioso, como este.
Matthias Wolf

1
Esta pregunta, particularmente la respuesta principal, probablemente sería una base excelente para una publicación de blog si alguien quisiera usarla como tal ... Como pregunta objetiva, realmente no encaja, está estructurada explícitamente como una encuesta de paja, pero Hay una buena información a continuación, de ahí el bloqueo.
Shog9

Respuestas:


232

Actualización: para las extensiones de System.Diagnostics, que proporcionan algunos de los oyentes que faltan, puede consultar Essential.Diagnostics en CodePlex ( http://essentialdiagnostics.codeplex.com/ )


Marcos

P: ¿Qué marcos utilizas?

R: System.Diagnostics.TraceSource, integrado en .NET 2.0.

Proporciona un registro potente, flexible y de alto rendimiento para aplicaciones, sin embargo, muchos desarrolladores no son conscientes de sus capacidades y no las utilizan por completo.

Hay algunas áreas donde la funcionalidad adicional es útil, o a veces existe la funcionalidad pero no está bien documentada, sin embargo, esto no significa que todo el marco de registro (que está diseñado para ser extensible) deba desecharse y reemplazarse por completo como algunas alternativas populares. (NLog, log4net, Common.Logging e incluso EntLib Logging).

En lugar de cambiar la forma de agregar declaraciones de registro a su aplicación y reinventar la rueda, simplemente extendió el marco System.Diagnostics en los pocos lugares donde lo necesita.

Me parece que los otros marcos, incluso EntLib, simplemente padecen el Síndrome No Inventado Aquí, y creo que han perdido el tiempo reinventando los conceptos básicos que ya funcionan perfectamente en el Sistema. en lugar de llenar los pocos vacíos que existen. En resumen, no los use, no son necesarios.

Características que quizás no conocías:

  • El uso de las sobrecargas de TraceEvent que toman una cadena de formato y argumentos pueden ayudar al rendimiento ya que los parámetros se mantienen como referencias separadas hasta que Filter.ShouldTrace () haya tenido éxito. Esto significa que no hay llamadas costosas a ToString () en los valores de los parámetros hasta que el sistema haya confirmado que el mensaje se registrará realmente.
  • Trace.CorrelationManager le permite correlacionar declaraciones de registro sobre la misma operación lógica (ver más abajo).
  • VisualBasic.Logging.FileLogTraceListener es bueno para escribir en archivos de registro y admite la rotación de archivos. Aunque en el espacio de nombres VisualBasic, se puede usar con la misma facilidad en un proyecto de C # (u otro lenguaje) simplemente al incluir la DLL.
  • Cuando utiliza EventLogTraceListener si llama a TraceEvent con múltiples argumentos y con una cadena de formato vacía o nula, los argumentos se pasan directamente a EventLog.WriteEntry () si está utilizando recursos de mensajes localizados.
  • La herramienta Service Trace Viewer (de WCF) es útil para ver gráficos de archivos de registro correlacionados con actividad (incluso si no está usando WCF). Esto realmente puede ayudar a depurar problemas complejos en los que intervienen múltiples hilos / actividades.
  • Evite los gastos generales borrando todos los oyentes (o eliminando los valores predeterminados); de lo contrario, Default pasará todo al sistema de rastreo (e incurrirá en todos esos gastos generales de ToString ()).

Áreas que tal vez quiera mirar extendiendo (si es necesario):

  • Escucha de rastreo de base de datos
  • Oyente de seguimiento de consola de color
  • MSMQ / Email / WMI oyentes de seguimiento (si es necesario)
  • Implemente un FileSystemWatcher para llamar a Trace.Refresh para cambios dinámicos de configuración

Otras recomendaciones

Use identificadores de eventos estructurados y mantenga una lista de referencia (por ejemplo, documente en una enumeración).

Tener identificadores de eventos únicos para cada evento (significativo) en su sistema es muy útil para correlacionar y encontrar problemas específicos. Es fácil rastrear el código específico que registra / usa los identificadores de eventos, y puede facilitar la orientación de errores comunes, por ejemplo, el error 5178 significa que la cadena de conexión de la base de datos es incorrecta, etc.

Los identificadores de eventos deben seguir algún tipo de estructura (similar a la Teoría de los códigos de respuesta utilizada en el correo electrónico y HTTP), que le permite tratarlos por categoría sin conocer códigos específicos.

Por ejemplo, el primer dígito puede detallar la clase general: 1xxx se puede usar para operaciones de 'Inicio', 2xxx para comportamiento normal, 3xxx para seguimiento de actividad, 4xxx para advertencias, 5xxx para errores, 8xxx para operaciones de 'Parada', 9xxx para errores fatales, etc.

El segundo dígito puede detallar el área, por ejemplo, 21xx para información de base de datos (41xx para advertencias de base de datos, 51xx para errores de base de datos), 22xx para modo de cálculo (42xx para advertencias de cálculo, etc.), 23xx para otro módulo, etc.

Los identificadores de eventos estructurados y asignados también le permiten usarlos en filtros.

P: Si utiliza el rastreo, ¿utiliza Trace.Correlation.StartLogicalOperation?

R: Trace.CorrelationManager es muy útil para correlacionar declaraciones de registro en cualquier tipo de entorno de subprocesos múltiples (que es prácticamente cualquier cosa en estos días).

Necesita al menos establecer el ActivityId una vez para cada operación lógica para correlacionar.

Start / Stop y LogicalOperationStack se pueden usar para un contexto simple basado en la pila. Para contextos más complejos (por ejemplo, operaciones asincrónicas), el uso de TraceTransfer al nuevo ActivityId (antes de cambiarlo) permite la correlación.

La herramienta Service Trace Viewer puede ser útil para ver gráficos de actividad (incluso si no está usando WCF).

P: ¿Escribe este código manualmente o utiliza alguna forma de programación orientada a aspectos para hacerlo? ¿Quieres compartir un fragmento de código?

R: Es posible que desee crear una clase de ámbito, por ejemplo, LogicalOperationScope, que (a) configura el contexto cuando se crea y (b) restablece el contexto cuando se elimina.

Esto le permite escribir código como el siguiente para ajustar automáticamente las operaciones:

  using( LogicalOperationScope operation = new LogicalOperationScope("Operation") )
  {
    // .. do work here
  }

En la creación, el alcance podría establecer primero ActivityId si fuera necesario, llamar a StartLogicalOperation y luego registrar un mensaje TraceEventType.Start. En Dispose, podría registrar un mensaje Stop y luego llamar a StopLogicalOperation.

P: ¿Proporcionan alguna forma de granularidad sobre las fuentes de rastreo? Por ejemplo, WPF TraceSources le permite configurarlos en varios niveles.

R: Sí, las Fuentes de rastreo múltiples son útiles / importantes a medida que los sistemas se hacen más grandes.

Si bien es probable que desee registrar constantemente todos los mensajes de Advertencia y superior, o toda la Información y superior, para cualquier sistema de tamaño razonable, el volumen de Rastreo de actividad (Inicio, Parada, etc.) y el registro detallado simplemente se vuelve demasiado.

En lugar de tener solo un interruptor que lo encienda o apague todo, es útil poder encender esta información para una sección de su sistema a la vez.

De esta manera, puede localizar problemas importantes desde el inicio de sesión habitual (todas las advertencias, errores, etc.) y luego "acercar" las secciones que desee y establecerlas en el Rastreo de actividad o incluso en los niveles de Depuración.

El número de fuentes de rastreo que necesita depende de su aplicación, por ejemplo, puede querer una fuente de rastreo por ensamblaje o por sección principal de su aplicación.

Si necesita un control aún más preciso, agregue interruptores booleanos individuales para activar / desactivar el seguimiento de alto volumen específico, por ejemplo, volcados de mensajes sin procesar. (O podría usarse una fuente de rastreo separada, similar a WCF / WPF).

También es posible que desee considerar fuentes de rastreo separadas para el rastreo de actividad frente al registro general (otro), ya que puede facilitar un poco la configuración de los filtros exactamente como los desea.

Tenga en cuenta que los mensajes aún pueden correlacionarse a través de ActivityId, incluso si se utilizan diferentes fuentes, por lo tanto, use tantos como necesite.


Oyentes

P: ¿Qué salidas de registro utilizas?

Esto puede depender de qué tipo de aplicación está escribiendo y qué cosas se están registrando. Por lo general, diferentes cosas van en diferentes lugares (es decir, múltiples salidas).

Generalmente clasifico los resultados en tres grupos:

(1) Eventos: registro de eventos de Windows (y archivos de seguimiento)

Por ejemplo, si escribe un servidor / servicio, la mejor práctica en Windows es usar el Registro de eventos de Windows (no tiene una IU para informar).

En este caso, todos los eventos Fatales, Error, Advertencia e Información (de nivel de servicio) deben ir al Registro de eventos de Windows. El nivel de información debe reservarse para este tipo de eventos de alto nivel, los que desea incluir en el registro de eventos, por ejemplo, "Servicio iniciado", "Servicio detenido", "Conectado a Xyz" e incluso "Programa iniciado". , "Usuario conectado", etc.

En algunos casos, es posible que desee que la escritura en el registro de eventos sea una parte integrada de su aplicación y no a través del sistema de seguimiento (es decir, escriba directamente las entradas del Registro de eventos). Esto significa que no se puede apagar accidentalmente. (Tenga en cuenta que también desea tener en cuenta el mismo evento en su sistema de rastreo para que pueda correlacionarse).

En contraste, una aplicación GUI de Windows generalmente informaría esto al usuario (aunque también puede iniciar sesión en el Registro de eventos de Windows).

Los eventos también pueden tener contadores de rendimiento relacionados (por ejemplo, número de errores / seg), y puede ser importante coordinar cualquier escritura directa en el Registro de eventos, contadores de rendimiento, escribir en el sistema de rastreo e informar al usuario para que ocurran en al mismo tiempo.

es decir, si un usuario ve un mensaje de error en un momento determinado, debería poder encontrar el mismo mensaje de error en el Registro de eventos de Windows, y luego el mismo evento con la misma marca de tiempo en el registro de seguimiento (junto con otros detalles de seguimiento).

(2) Actividades: archivos de registro de aplicaciones o tabla de base de datos (y archivos de rastreo)

Esta es la actividad regular que realiza un sistema, por ejemplo, página web servida, comercio de bolsa alojado, orden tomada, cálculo realizado, etc.

El seguimiento de actividad (inicio, detención, etc.) es útil aquí (en la granualidad correcta).

Además, es muy común usar un registro de aplicación específico (a veces llamado registro de auditoría). Por lo general, esta es una tabla de base de datos o un archivo de registro de la aplicación y contiene datos estructurados (es decir, un conjunto de campos).

Las cosas pueden ponerse un poco borrosas aquí dependiendo de su aplicación. Un buen ejemplo podría ser un servidor web que escribe cada solicitud en un registro web; ejemplos similares pueden ser un sistema de mensajería o un sistema de cálculo donde cada operación se registra junto con detalles específicos de la aplicación.

Un ejemplo no tan bueno son las operaciones bursátiles o un sistema de pedidos de ventas. En estos sistemas, probablemente ya esté registrando la actividad, ya que tienen un valor comercial importante, sin embargo, el principio de correlacionarlos con otras acciones sigue siendo importante.

Además de los registros de aplicaciones personalizados, las actividades a menudo también tienen contadores de rendimiento relacionados, por ejemplo, número de transacciones por segundo.

En general, debe coordinar el registro de actividades en diferentes sistemas, es decir, escribir en el registro de su aplicación al mismo tiempo que aumenta su contador de rendimiento e inicia sesión en su sistema de rastreo. Si lo hace todo al mismo tiempo (o directamente uno después del otro en el código), entonces los problemas de depuración son más fáciles (que si todos ocurren en diferentes momentos / ubicaciones en el código).

(3) Rastreo de depuración: archivo de texto, o tal vez XML o base de datos.

Esta es información a nivel detallado e inferior (por ejemplo, interruptores booleanos personalizados para activar / desactivar volcados de datos sin procesar). Esto proporciona las agallas o detalles de lo que está haciendo un sistema a nivel de sub-actividad.

Este es el nivel que desea poder activar / desactivar para secciones individuales de su aplicación (de ahí las múltiples fuentes). No desea que estas cosas llenen el Registro de eventos de Windows. A veces se usa una base de datos, pero lo más probable es que se acumulen archivos de registro que se purgan después de un cierto tiempo.

Una gran diferencia entre esta información y un archivo de registro de aplicación es que no está estructurado. Mientras que un registro de aplicación puede tener campos para, desde, cantidad, etc., los rastreos detallados de depuración pueden ser cualquier cosa que un programador ponga, por ejemplo, "verificar valores X = {valor}, Y = falso", o comentarios / marcadores aleatorios como " Hecho, intentando de nuevo ".

Una práctica importante es asegurarse de que las cosas que coloque en los archivos de registro de la aplicación o en el Registro de eventos de Windows también se registren en el sistema de rastreo con los mismos detalles (por ejemplo, marca de tiempo). Esto le permite correlacionar los diferentes registros al investigar.

Si está planeando usar un visor de registro particular porque tiene una correlación compleja, por ejemplo, el Visor de rastreo de servicio, entonces necesita usar un formato apropiado, es decir, XML. De lo contrario, un archivo de texto simple suele ser lo suficientemente bueno: en los niveles inferiores, la información está en gran parte desestructurada, por lo que puede encontrar volcados de matrices, volcados de pila, etc. Siempre que pueda correlacionar de nuevo a registros más estructurados en niveles superiores, las cosas deberían estar bien.

P: Si utiliza archivos, ¿utiliza registros continuos o solo un archivo? ¿Cómo haces que los registros estén disponibles para que la gente los consuma?

R: Para los archivos, generalmente desea rodar archivos de registro desde el punto de vista de la capacidad de administración (con System.Diagnostics simplemente use VisualBasic.Logging.FileLogTraceListener).

La disponibilidad nuevamente depende del sistema. Si solo está hablando de archivos, entonces para un servidor / servicio, solo se puede acceder a los archivos rodantes cuando sea necesario. (Windows Event Log o Database Application Logs tendrían sus propios mecanismos de acceso).

Si no tiene fácil acceso al sistema de archivos, entonces el rastreo de depuración a una base de datos puede ser más fácil. [es decir, implementar una base de datos TraceListener].

Una solución interesante que vi para una aplicación GUI de Windows fue que registraba información de rastreo muy detallada en un "registrador de vuelo" mientras se ejecutaba y luego, cuando la apagaba si no tenía problemas, simplemente borraba el archivo.

Sin embargo, si se bloqueó o encontró un problema, el archivo no se eliminó. Si detecta el error o la próxima vez que lo ejecuta, notará el archivo y luego podrá tomar medidas, por ejemplo, comprimirlo (por ejemplo, 7zip) y enviarlo por correo electrónico o ponerlo a disposición de otra manera.

En la actualidad, muchos sistemas incorporan informes automáticos de fallas a un servidor central (después de consultar con los usuarios, por ejemplo, por razones de privacidad).


Visita

P: ¿Qué herramientas utiliza para ver los registros?

R: Si tiene varios registros por diferentes razones, utilizará múltiples visores.

Notepad / vi / Notepad ++ o cualquier otro editor de texto es lo básico para los registros de texto sin formato.

Si tiene operaciones complejas, por ejemplo, actividades con transferencias, entonces, obviamente, utilizaría una herramienta especializada como Service Trace Viewer. (Pero si no lo necesita, entonces un editor de texto es más fácil).

Como generalmente registro información de alto nivel en el Registro de eventos de Windows, proporciona una forma rápida de obtener una descripción general, de manera estructurada (busque los bonitos iconos de error / advertencia). Solo necesita comenzar a buscar archivos de texto si no hay suficiente en el registro, aunque al menos el registro le proporciona un punto de partida. (En este punto, asegurarse de que sus registros tengan entradas coordinadas se vuelve útil).

En general, el Registro de eventos de Windows también hace que estos eventos importantes estén disponibles para herramientas de monitoreo como MOM u OpenView.

Otros --

Si inicia sesión en una base de datos, puede ser fácil filtrar y ordenar la información (por ejemplo, acercar una identificación de actividad particular. (Con los archivos de texto puede usar Grep / PowerShell o similar para filtrar en el GUID particular que desee)

MS Excel (u otro programa de hoja de cálculo). Esto puede ser útil para analizar información estructurada o semiestructurada si puede importarla con los delimitadores correctos para que los diferentes valores vayan en columnas diferentes.

Cuando ejecuto un servicio en depuración / prueba, generalmente lo alojo en una aplicación de consola por simplicidad, encuentro útil un registrador de consola de color (por ejemplo, rojo para errores, amarillo para advertencias, etc.). Debe implementar un escucha de rastreo personalizado.

Tenga en cuenta que el marco no incluye un registrador de consola de color o un registrador de base de datos, por lo que, en este momento, necesitaría escribirlos si los necesita (no es demasiado difícil).

Realmente me molesta que varios marcos (log4net, EntLib, etc.) hayan perdido el tiempo reinventando la rueda y re-implementando el registro básico, el filtrado y el registro en archivos de texto, el Registro de eventos de Windows y archivos XML, cada uno en su propio manera diferente (las declaraciones de registro son diferentes en cada una); cada uno ha implementado su propia versión de, por ejemplo, un registrador de base de datos, cuando la mayor parte de eso ya existía y todo lo que se necesitaba era un par de rastreadores más para System.Diagnostics. Hable sobre un gran desperdicio de esfuerzo duplicado.

P: Si está creando una solución ASP.NET, ¿también usa ASP.NET Health Monitoring? ¿Incluye resultados de seguimiento en los eventos del monitor de salud? ¿Qué pasa con Trace.axd?

Estas cosas se pueden activar / desactivar según sea necesario. Encuentro que Trace.axd es bastante útil para depurar la forma en que un servidor responde a ciertas cosas, pero generalmente no es útil en un entorno muy utilizado o para el seguimiento a largo plazo.

P: ¿Qué pasa con los contadores de rendimiento personalizados?

Para una aplicación profesional, especialmente un servidor / servicio, espero verla completamente equipada con los contadores del Monitor de rendimiento y el registro en el Registro de eventos de Windows. Estas son las herramientas estándar en Windows y deben usarse.

Debe asegurarse de incluir instaladores para los contadores de rendimiento y los registros de eventos que utiliza; estos deben crearse en el momento de la instalación (cuando se instala como administrador). Cuando su aplicación se ejecuta normalmente, no debería tener privilegios de administración (por lo que no podrá crear registros faltantes).

Esta es una buena razón para practicar el desarrollo como no administrador (tenga una cuenta de administrador separada para cuando necesite instalar servicios, etc.). Si escribe en el registro de eventos, .NET creará automáticamente un registro faltante la primera vez que lo escriba; si se desarrolla como no administrador, lo detectará temprano y evitará una desagradable sorpresa cuando un cliente instale su sistema y luego no pueda usarlo porque no se está ejecutando como administrador.


FYI: Encontré un problema en el que el seguimiento de Microsoft a un archivo se bloquea. Si tiene varios procesos (o subprocesos) escribiendo en el mismo archivo y colisionan, obtendrá un error de bloqueo de acceso exclusivo del sistema de archivos en el archivo de registro.
Jay

1
La infraestructura de System.Diagnostics es segura para subprocesos; el comportamiento predeterminado es que el marco se bloquee, sin embargo, puede anular TraceListener.IsThreadSafe si proporciona su propio bloqueo. Ver msdn.microsoft.com/en-us/library/… . Para procesos múltiples, normalmente escribiría en archivos separados, pero tenga en cuenta que Service Trace Viewer puede cargar múltiples archivos de rastreo (por ejemplo, desde varias máquinas) y correlacionarlos a través de ActivityId.
Sly Gryphon

1
¿Puede sugerirme cómo usar TraceEvent () para registrar excepciones?
Dmitriy Sosunov

1
¿No es uno de los principales inconvenientes de System.Diagnostics.Traceque está decorado [Conditional("TRACE")]lo que lo hace inutilizable en entornos de producción, donde rara vez se ha compilado el código con la TRACEbandera?
Asbjørn Ulsberg

2
@asbjornu La configuración de compilación de lanzamiento predeterminada en Visual Studio tiene TRACE definido (es DEBUG que está desactivado para las compilaciones de lanzamiento); sin embargo, si construye desde la línea de comando, debe activarlo.
Sly Gryphon

40

Tengo que unirme al coro que recomienda log4net, en mi caso desde un punto de vista de flexibilidad de plataforma (escritorio .Net / Compact Framework, 32/64 bits).

Sin embargo, envolverlo en una API de etiqueta privada es un antipatrón importante . log4net.ILoggeres la contraparte de .Net de la API de contenedor de Logging de Commons , por lo que el acoplamiento ya está minimizado para usted, y dado que también es una biblioteca Apache, eso generalmente no es una preocupación porque no está cediendo ningún control: bifurque si debe.

La mayoría de las bibliotecas de envoltorios domésticos que he visto también cometen una o más de una letanía de fallas:

  1. Usar un registrador global de singleton (o equivalentemente un punto de entrada estático) que pierde la resolución fina del patrón de registrador por clase recomendado para ninguna otra ganancia de selectividad.
  2. No exponer el Exceptionargumento opcional , lo que lleva a múltiples problemas:
    • Hace que una política de registro de excepciones sea aún más difícil de mantener, por lo que no se hace nada consistentemente con excepciones.
    • Incluso con una política consistente, formatear la excepción en una cadena pierde datos prematuramente. He escrito un ILayoutdecorador personalizado que realiza un desglose detallado de una excepción para determinar la cadena de eventos.
  3. No exponer las propiedadesIsLevelEnabled , lo que descarta la capacidad de omitir el código de formato cuando las áreas o niveles de registro están desactivados.

1
Me encargaron refactorizar un envoltorio interno (horrible) alrededor de log4j en algo algo menos horrible (todavía es bastante malo, pero eso es el resultado de los requisitos de horquillado que logré en log4j). Traté de eliminar el punto de entrada estático global, pero me derribaron. Realmente no entiendo el punto. En nuestra configuración, log4j está tan extendido y retorcido que realmente solo se está utilizando como despachador de eventos; solo lo estamos usando porque alguien preguntó "¿cómo podemos usar log4j para esto?" Utilice log4whatever directamente o simplemente escriba su propio marco. El camino del medio es doloroso.
Adam Jaskiewicz 03 de

25
No estoy de acuerdo con su recomendación de no ajustar log4net. Al envolverlo con una API de modelo de proveedor delgado, los usuarios de las bibliotecas de su clase pueden conectar su marco de registro favorito. YMMV, por supuesto, pero describirlo como un "antipatrón principal" es un poco dogmático. Además, el hecho de que existan bibliotecas de contenedor con "una letanía de fallas" no es un buen argumento en contra de un contenedor bien escrito.
Joe

1
Llamar a algo antipatrón no significa que siempre sea una mala idea al 100%, solo que crea una tendencia a pintarse en una esquina si no tienes cuidado. Además, ILog / LogManager es en sí mismo una mini biblioteca de envoltura bien escrita en la imagen del registro común que se incluye en el ensamblaje log4net, pero no hay razón para que no pueda extraerse y convertirse en un registro común común para CLR.
Jeffrey Hantin

18

No desarrollo a menudo en asp.net, sin embargo, cuando se trata de registradores, creo que muchas de las mejores prácticas son universales. Estos son algunos de mis pensamientos aleatorios sobre el registro que he aprendido a lo largo de los años:

Marcos

  • Use un marco de abstracción de registrador, como slf4j (o enrolle el suyo), para desacoplar la implementación del registrador de su API. He visto una serie de marcos de registro ir y venir y es mejor que puedas adoptar uno nuevo sin mucha molestia.
  • Intente encontrar un marco que admita una variedad de formatos de salida.
  • Intente encontrar un marco que admita complementos / filtros personalizados.
  • Utilice un marco que pueda configurarse mediante archivos externos, de modo que sus clientes / consumidores puedan modificar fácilmente la salida del registro para que las aplicaciones comerciales de administración de registros puedan leerlo con facilidad.
  • Asegúrese de no exagerar en los niveles de registro personalizados, de lo contrario es posible que no pueda pasar a diferentes marcos de registro.

Salida del registrador

  • Intente evitar los registros de estilo XML / RSS para el registro que podría encontrar fallas catastróficas. Esto es importante porque si el interruptor de encendido se apaga sin que su registrador escriba la </xxx>etiqueta de cierre , su registro se rompe.
  • Hilos de registro. De lo contrario, puede ser muy difícil rastrear el flujo de su programa.
  • Si tiene que internacionalizar sus registros, es posible que desee que un desarrollador solo inicie sesión en inglés (o en el idioma que elija).
  • A veces, tener la opción de insertar declaraciones de registro en consultas SQL puede ser un salvavidas en situaciones de depuración. Como:
    - Clase de invocación: com.foocorp.foopackage.FooClass: 9021
    SELECCIONE * DE foo;
  • Desea un registro a nivel de clase. Normalmente, tampoco desea instancias estáticas de registradores; no vale la pena la microoptimización.
  • Marcar y clasificar las excepciones registradas a veces es útil porque no todas las excepciones son iguales. Por lo tanto, conocer un subconjunto de excepciones importantes es muy útil si tiene un monitor de registro que necesita enviar notificaciones sobre estados críticos.
  • Los filtros de duplicación le salvarán la vista y el disco duro. ¿Realmente desea ver la misma declaración de registro repetida 10 ^ 10000000 veces? ¿No sería mejor recibir un mensaje como: This is my logging statement - Repeated 100 times

También vea esta pregunta mía .


55
los filtros de duplicación son una gran idea
Paul Stovell

Solía ​​estar de acuerdo con el problema de la etiqueta rota, pero la mayoría de los buenos escritores de XML no usan XML completo de todos modos (es decir, sin elemento raíz) para que puedan iniciar sesión sin cargar el DOM XML. en el caso poco común de que se produzca un problema por una entrada parcialmente escrita, puede solucionarlo manualmente
Paul Stovell

He estado yendo y viniendo en el registro XML durante años. Ahora, me parece excesivo. Si necesitaba una fuente RSS del estado de una aplicación, creo que se implementa mejor con una utilidad de monitoreo de registros.
Elijah

Estoy de acuerdo en RSS. Estoy pensando más en las herramientas de visualización que le permiten comprender mejor la entrada. con archivos de texto, generalmente desea mantener una entrada en una línea; pero a veces desea incluir trazas de pila u objetos serializados. ahí es donde un registro XML (como lo usa WCF) es útil
Paul Stovell

+1 por mencionar la instrumentación de consultas SQL. De hecho, esto es muy útil para la correlación de trazas de bases de datos y trazas de aplicaciones. Lo estoy haciendo manualmente en mi DAL, pero me pregunto qué tipo de soporte de herramientas hay para esta técnica.
Constantin

17

No estoy calificado para comentar sobre el registro para .Net, ya que mi pan de molde es Java, pero hemos tenido una migración en nuestro registro en los últimos 8 años, puede encontrar una analogía útil para su pregunta.

Comenzamos con un registrador Singleton que fue utilizado por cada hilo dentro de la JVM, y establecimos el nivel de registro para todo el proceso. Esto dio como resultado registros enormes si tuviéramos que depurar incluso una parte muy específica del sistema, por lo que la lección número uno es segmentar su registro.

Nuestra encarnación actual del registrador permite múltiples instancias con una definida como predeterminada. Podemos crear instancias de cualquier número de registradores secundarios que tengan diferentes niveles de registro, pero la faceta más útil de esta arquitectura es la capacidad de crear registradores para paquetes y clases individuales simplemente cambiando las propiedades de registro. La lección número dos es crear un sistema flexible que permita anular su comportamiento sin cambiar el código.

Estamos utilizando la biblioteca de registro de comunes de Apache envuelta alrededor de Log4J.

¡Espero que esto ayude!

* Editar *

Después de leer la publicación de Jeffrey Hantin a continuación, me di cuenta de que debería haber notado en qué se ha convertido realmente nuestro contenedor de registro interno. Ahora es esencialmente una fábrica y se usa estrictamente para obtener un registrador que funcione utilizando el archivo de propiedades correcto (que por razones heredadas no se ha movido a la posición predeterminada). Dado que ahora puede especificar el archivo de configuración de registro en la línea de comandos, sospecho que se volverá aún más ágil y si está iniciando una nueva aplicación, definitivamente estoy de acuerdo con su declaración de que ni siquiera debería molestarse en envolver el registrador.


gracias por la respuesta. ¿Crea los registradores secundarios manualmente en código (es decir, están codificados) o mediante algún tipo de cosa automática / implícita?
Paul Stovell

No ... si agregamos una configuración de registro a los archivos logging.properties para un paquete o clase, se registrarán según esa configuración, pero cualquier paquete o clase no configurado específicamente se registrará en los niveles predeterminados.
Steve Moyer

9

Usamos Log4Net en el trabajo como proveedor de registro, con un contenedor singleton para la instancia de registro (aunque el singleton está bajo revisión, cuestionando si son una buena idea o no).

Lo elegimos por las siguientes razones:

  • Configuración / reconfiguración simple en varios entornos.
  • Buen número de apéndices preconstruidos
  • Uno de los CMS que utilizamos ya lo tenía incorporado
  • Buena cantidad de niveles de registro y configuraciones a su alrededor

Debo mencionar que esto está hablando desde un punto de vista de desarrollo ASP.NET

Puedo ver algunos méritos en el uso de Trace que se encuentra en el marco .NET, pero no estoy completamente convencido de ello, principalmente porque los componentes con los que trabajo realmente no hacen ninguna llamada de Trace. Lo único que uso con frecuencia que hace es System.Net.Mailpor lo que puedo decir.

Entonces tenemos una biblioteca que envuelve log4net y dentro de nuestro código solo necesitamos cosas como esta:

Logger.Instance.Warn("Something to warn about");
Logger.Instance.Fatal("Something went bad!", new Exception());

try {
  var i = int.Parse("Hello World");
} catch(FormatException, ex) {
  Logger.Instance.Error(ex);
}

Dentro de los métodos, verificamos si el nivel de registro está habilitado, por lo que no tiene llamadas redundantes a la API de log4net (por lo tanto, si Debug no está habilitado, las declaraciones de depuración se ignoran), pero cuando tengo algo de tiempo Lo actualizaré para exponerlos para que pueda hacer los controles usted mismo. Esto evitará que se realicen evaluaciones cuando no deberían, por ejemplo:

Logger.Instance.Debug(string.Format("Something to debug at {0}", DateTime.Now);

Esto se convertirá en:

if(Logger.DebugEnabled) Logger.Instance.Debug(string.Format("Something to debug at {0}", DateTime.Now);

(Ahorre un poco de tiempo de ejecución)

Por defecto, iniciamos sesión en dos ubicaciones:

  1. Sistema de archivos del sitio web (en una extensión de archivo no servida)
  2. Envío de correo electrónico por error y fatal

Los archivos se realizan en forma continua de cada día o 10 MB (IIRC). No utilizamos EventLog, ya que puede requerir una mayor seguridad de la que a menudo queremos ofrecer a un sitio.

Creo que el Bloc de notas funciona bien para leer registros.


Los marcos de registro son uno de los pocos casos en los que el singleton no es un mal uso.
mmcdole

Puede ser si desea proporcionar un contexto alrededor de su registrador. Pero ayuda a lidiar con la concurrencia
Aaron Powell

77
Definitivamente arrancaría el singleton. Sin duda, puede tener una única instancia que se pasa (preferiblemente en el contenedor IOC / DI). También me gustaría tratar de mover el registro en un interceptor ....
yfeldblum

2
Tampoco soy fanático de la instancia única. Prefiero dar a cada clase un registrador con un nombre único, por lo que activar o desactivar el registro por módulo es fácil.
Jeffrey Hantin

8

¿Qué marcos usas?

Utilizamos una combinación del bloque de aplicación de registro y un asistente de registro personalizado que funciona en torno a los bits del marco .Net. El LAB está configurado para generar archivos de registro bastante extensos, incluidos archivos de seguimiento generales separados para la entrada / salida del método de servicio y archivos de error específicos para problemas inesperados. La configuración incluye fecha / hora, subproceso, pId, etc. para asistencia de depuración, así como el detalle completo de la excepción y la pila (en el caso de una excepción inesperada).

El asistente de registro personalizado utiliza Trace.Correlation y es particularmente útil en el contexto de inicio de sesión en WF. Por ejemplo, tenemos una máquina de estados que invoca una serie de flujos de trabajo secuenciales. En cada una de estas actividades de invocación registramos el inicio (usando StartLogicalOperation) y luego al final detenemos la operación lógica con un controlador de eventos de retorno gereric.

Esto ha resultado útil algunas veces al intentar depurar fallas en secuencias comerciales complejas, ya que nos permite determinar cosas como decisiones de sucursal If / Else, etc., más rápidamente en función de la secuencia de ejecución de la actividad.

¿Qué salidas de registro utilizas?

Usamos archivos de texto y archivos XML. Los archivos de texto se configuran a través del bloque de aplicaciones, pero también tenemos salidas XML de nuestro servicio WF. Esto nos permite capturar los eventos de tiempo de ejecución (persistencia, etc.), así como las excepciones genéricas de tipo de negocio. Los archivos de texto son registros sucesivos que se distribuyen por día y tamaño (creo que el tamaño total de 1 MB es un punto de sustitución).

¿Qué herramientas utilizas para ver los registros?

Estamos usando Notepad y WCF Service Trace Viewer dependiendo del grupo de salida que estemos viendo. WCF Service Trace Viewer es realmente muy útil si tiene la configuración de salida correcta y puede hacer que la lectura de la salida sea mucho más sencilla. Dicho esto, si sé aproximadamente dónde está el error de todos modos, solo leer un archivo de texto bien anotado también es bueno.

Los registros se envían a un único directorio que luego se divide en subdirectorios en función del servicio de origen. El directorio raíz se expone a través de un sitio web que tiene su acceso controlado por un grupo de usuarios de soporte. Esto nos permite echar un vistazo a los registros de producción sin tener que realizar solicitudes y pasar por largos procesos de trámites burocráticos para obtener datos de producción.


6

Como autores de la herramienta, por supuesto, utilizamos SmartInspect para registrar y rastrear aplicaciones .NET. Usualmente usamos el protocolo de canalización con nombre para el registro en vivo y los archivos de registro binarios (encriptados) para los registros del usuario final. Utilizamos la consola SmartInspect como visor y herramienta de monitoreo.

En realidad, existen bastantes marcos y herramientas de registro para .NET. Hay una descripción general y una comparación de las diferentes herramientas en DotNetLogging.com .


5

Hay muchas recomendaciones excelentes en las respuestas.

Una práctica recomendada general es considerar quién leerá el registro. En mi caso será un administrador en el sitio del cliente. Entonces registro mensajes que les dan algo sobre lo que pueden actuar. Por ejemplo, "No se puede inicializar la aplicación. Esto generalmente es causado por ......"


1

Usamos log4net en nuestras aplicaciones web.

Su capacidad de personalizar el registro en tiempo de ejecución cambiando el archivo de configuración XML es muy útil cuando una aplicación no funciona correctamente en tiempo de ejecución y necesita ver más información.

También le permite apuntar a clases o atributos específicos para iniciar sesión. Esto es muy útil cuando tienes una idea de dónde está ocurriendo el error. Un ejemplo clásico es NHibernate donde desea ver solo el SQL que va a la base de datos.

Editar:

Escribimos todos los eventos en una base de datos y en el sistema Trace. El registro de eventos que utilizamos para errores o excepciones. Registramos la mayoría de los eventos en una base de datos para poder crear informes personalizados y permitir que los usuarios vean el registro si lo desean directamente desde la aplicación.


¿Puede proporcionar más detalles sobre cómo lo usa? ¿Se registra en un archivo o en el registro de eventos? ¿Es un archivo de registro continuo? ¿Qué haces para asegurarlo o respaldarlo? Estoy interesado en el uso de la vida real.
Paul Stovell

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.