¿Cuáles son algunos patrones y antipatrones del registro de aplicaciones? [cerrado]

64

Hace poco tuve que investigar un problema de campo para nuestra aplicación de gran empresa. Me horrorizaron los registros que tuve que peinar en un intento de encontrar el problema y al final del día, los registros no ayudaron en absoluto a identificar / aislar el error.

Nota: entiendo que no todos los errores son detectables a través de los registros. Esto no cambia el hecho de que los registros son horribles.

Hay algunos problemas obvios con nuestro registro que ya podemos intentar solucionar. No quiero enumerarlos aquí y simplemente no puedo mostrarle nuestros archivos de registro para que pueda dar consejos sobre qué hacer.

En cambio, para evaluar qué tan mal estamos haciendo en el frente de registro, me gustaría saber:

  1. Cuáles son algunas pautas , si las hay, cuando se trata de registrar para una aplicación, especialmente para aplicaciones grandes.
  2. ¿Hay algún patrón que debamos seguir o anti-patrones que debemos conocer?
  3. ¿Es esto algo importante para corregir o puede incluso solucionarse o todos los archivos de registro son simplemente enormes y necesita scripts complementarios para analizarlos?

Nota al margen: usamos log4j.

    
pregunta c_maker 04.10.2011 - 22:24

9 respuestas

53

Algunos puntos en los que mi práctica resultó útil:

  • Mantenga todo el código de registro en su código de producción. Tiene la capacidad de habilitar un registro más / menos detallado en la producción, preferiblemente por subsistema y sin reiniciar su programa.

  • Haga que los registros sean fáciles de analizar por grep y por ojo. Se adhieren a varios campos comunes al principio de cada línea. Identifique el tiempo, la severidad y el subsistema en cada línea. Formule claramente el mensaje. Haga que cada mensaje de registro sea fácil de asignar a su línea de código fuente.

  • Si ocurre un error, intente recopilar y registrar la mayor cantidad de información posible. Puede llevar mucho tiempo pero está bien porque el procesamiento normal ha fallado de todos modos. No tener que esperar cuando ocurre la misma condición en producción con un depurador adjunto no tiene precio.

La mayoría de los registros son necesarios para el monitoreo y la solución de problemas. Póngase en el lugar de un solucionador de problemas y piense qué tipo de registros le gustaría tener cuando algo malo está sucediendo o ha ocurrido en la oscuridad de la noche.

    
respondido por el 9000 05.10.2011 - 01:20
27

Mi recurso público favorito para las pautas de registro es Apache JCL Best Practices .

  

Las mejores prácticas para JCL se presentan en dos categorías: General y Enterprise. Los principios generales son bastante claros. Las prácticas empresariales son un poco más complicadas y no siempre es tan claro por qué son importantes.

     

Los principios de mejores prácticas empresariales se aplican a los componentes y herramientas de middleware que se espera que se ejecuten en un entorno de nivel "Enterprise". Estos problemas se relacionan con el registro como internacionalización y la detección de fallas. La empresa requiere más esfuerzo y planificación, pero se recomienda encarecidamente (si no se requiere) en los sistemas de nivel de producción. Diferentes empresas / entornos corporativos tienen diferentes requisitos, por lo que ser flexible siempre ayuda ...

A pesar de la orientación de JCL, estos parecen ser lo suficientemente genéricos como para ser adoptados para el registro en general.

  • Mis "pautas" personales para el registro son que a nivel de depuración, trato de hacer que mis registros se lean como una historia, con lógica comprensible y suficientes detalles (pero no sobrecargados).

El anti-patrón más famoso es, probablemente, "tragar excepciones", simplemente búsquelo en la web.

En cuanto a los archivos de registro de gran tamaño, en mi práctica este fue principalmente el caso normal. Y sí, scripts suplementarios a medida que los llama y / o herramientas como Chainsaw también se ven normal para mi.

  • Por encima de esto no significa que siempre debes colocar ciegamente todos los registros en un archivo enorme. A veces puede ser útil escribir / copiar algunos de los registros en archivos separados. Por ejemplo, en mi reciente proyecto, los chicos de control de calidad pidieron archivos dedicados para métricas y datos de tiempo y para informes breves sobre las operaciones del sistema. Dijeron que se beneficiarían de eso y el desarrollador lo hizo (el beneficio de un breve informe de archivos resultó realmente significativo).

PS. Con respecto a los antipatrones, otros que vienen a la mente son "inundaciones" y mensajes sin sentido.

  • Lo llamo flooding cuando veo varios mensajes similares provenientes de un bucle con muchas iteraciones. Para mí, la inundación es lo suficientemente molesta como para intentar deshacerme de ella cuando la detecto en el código fuente. Por lo general, mejorarlo requiere algo de arte, porque, bueno, las cosas que ocurren dentro del bucle pueden ser interesantes. Cuando no tengo tiempo de mejorarlo más profundamente, trato de al menos cambiar el nivel de registro de tales mensajes al más bajo para facilitar el filtrado.

  • Mensajes sin sentido parecen ser basura bastante popular. Parecen inofensivos cuando se leen en el código fuente: supongo que uno tiene que pasar por el dolor de analizar el resultado de la depuración con el aspecto ...

    step #1
    step #2
    step #3
    

    ... para apreciar profundamente su inherente fealdad. Mi heurística favorita para detectar este tipo de problemas a nivel de código fuente (propuesto por un colega en uno de mis proyectos anteriores) es calcular el número de apariciones de símbolos de espacio en los literales de cadena utilizados en el registro. En mi experiencia, cero espacios básicamente garantiza que la declaración de registro no tiene sentido, un espacio también es un buen indicador del problema potencial.

respondido por el gnat 04.10.2011 - 22:41
27

Trabajo con sistemas críticos de seguridad en tiempo real y el registro es a menudo la única forma de detectar errores raros que aparecen una vez en la luna azul cada 53. ° martes, cuando es luna llena, si capta mi deriva. Esto te hace obsesivo con el tema, así que me disculparé ahora si empiezo a echar espuma por la boca. Lo siguiente se escribió para los registros de depuración de código nativo, pero la mayoría de ellos se aplica también al mundo administrado ...

Usa archivos de registro de texto. Parece obvio, pero algunas personas intentan generar archivos de registro binarios: eso es estúpido porque no necesito buscar una herramienta de lectura cuando estoy en el campo. Además, si se trata de texto y la depuración es detallada, existe la posibilidad de que el ingeniero de campo pueda leer el archivo y diagnosticar el problema sin volver a consultarme. Todo el mundo gana.

Diseño sistemas que son capaces de registrar casi todo, pero no enciendo todo de forma predeterminada. La información de depuración se envía a un cuadro de diálogo de depuración oculto que lo marca y lo envía a un cuadro de lista (limitado a unas 500 líneas antes de la eliminación), y el cuadro de diálogo me permite detenerlo, guardarlo en un archivo de registro automáticamente o desviarlo a un depurador adjunto. Esa desviación me permite ver la salida de depuración de múltiples aplicaciones, todas perfectamente serializadas, lo que a veces puede ser un salvavidas. Usé para usar niveles de registro numérico (cuanto más alto establezca el nivel, más capturará):

off
errors only
basic
detailed
everything

pero esto es demasiado inflexible: a medida que te abres camino hacia un error, es mucho más eficiente poder enfocarte en iniciar sesión exactamente en lo que necesitas sin tener que atravesar toneladas de detritus, y puede ser un tipo particular de Transacción u operación que provoca el error. Si eso requiere que enciendas todo, solo estás haciendo tu propio trabajo más difícil. Necesitas algo más fino.

Así que ahora estoy en el proceso de cambiarme al registro basado en un sistema de bandera. Todo lo que se registra tiene una marca que detalla qué tipo de operación es, y hay un conjunto de casillas de verificación que me permiten definir qué se registra. Normalmente esa lista se ve así:

#define DEBUG_ERROR          1
#define DEBUG_BASIC          2
#define DEBUG_DETAIL         4
#define DEBUG_MSG_BASIC      8
#define DEBUG_MSG_POLL       16
#define DEBUG_MSG_STATUS     32
#define DEBUG_METRICS        64
#define DEBUG_EXCEPTION      128
#define DEBUG_STATE_CHANGE   256
#define DEBUG_DB_READ        512
#define DEBUG_DB_WRITE       1024
#define DEBUG_SQL_TEXT       2048
#define DEBUG_MSG_CONTENTS   4096

Este sistema de registro se envía con la versión versión , está activado y se guarda en el archivo de forma predeterminada. Es demasiado tarde para descubrir que debería haber estado registrando DESPUÉS de que se haya producido el error, si ese error solo ocurre una vez cada seis meses en promedio y no tiene forma de reproducirlo. El registro que solo funciona con las versiones de depuración es justo. llanura. tonto.

El software normalmente se envía con ERROR, BASIC, STATE_CHANGE y EXCEPTION activados, pero esto se puede cambiar en el campo a través del cuadro de diálogo de depuración (o una configuración de registro / ini / cfg, donde se guardan estas cosas).

Ah y una cosa: mi sistema de depuración genera un archivo por día. Sus requisitos pueden ser diferentes. Pero asegúrese de que su código de depuración inicie todos los archivos con la fecha, la versión del código que está ejecutando y, si es posible, algún marcador para la ID del cliente, la ubicación del sistema o lo que sea. Puede obtener una mezcla de archivos de registro desde el campo, y necesita algún registro de lo que vino de dónde y qué versión del sistema que estaban ejecutando, que está realmente en los datos en sí, y no puede confiar en el cliente / Ingeniero de campo para decirle qué versión tienen, es posible que solo le digan qué versión piensan que tienen. Peor aún, pueden informar la versión exe que está en el disco, pero la versión anterior todavía se está ejecutando porque se olvidó de reiniciar después de reemplazarla. Haga que su código se lo diga a usted mismo.

Por último, no desea que su código genere sus propios problemas, así que ponga una función de temporizador para purgar los archivos de registro después de tantos días o semanas (solo verifique la diferencia entre la hora actual y la hora de creación del archivo). Esto está bien para una aplicación de servidor que se ejecuta todo el tiempo, en una aplicación del lado del cliente que puede obtener con la purga de datos antiguos cuando se inicia. Por lo general, hacemos purga después de 30 días aproximadamente, en un sistema sin frecuentes visitas de ingenieros, es posible que desee dejarlo por más tiempo. Obviamente, esto también depende del tamaño de sus archivos de registro.

    
respondido por el Bob Moore 06.10.2011 - 00:42
11

¡Registra la excepción solo una vez!

Uno de los puntos de dolor comunes que he notado es el registro y el reenvío de una excepción. Como resultado, los archivos de registro contienen las mismas excepciones varias veces en varios niveles de pila.

    
respondido por el Nayaki 05.10.2011 - 19:44
5

Aquí hay un antipatrón: crear dos docenas de campos "genéricos" en una tabla de base de datos para rastrear cualquier cosa concebible y luego tener 88 (y contar) diferentes valores de enumeración para diferentes tipos de registros.

    
respondido por el Wayne Molina 05.10.2011 - 19:08
4

Mi experiencia con los registros es más grande cuanto mejor, pero sea lo suficientemente consistente como para que pueda filtrarse por máquina y pueda configurar un nivel de gravedad para cada componente de su aplicación individualmente.

Además, es muy difícil predecir qué registro necesitará para encontrar un error futuro. La mayoría de los lugares obvios para registrar errores se arreglan antes de que el producto salga por la puerta. No es raro que el resultado de un informe de error sea que acaba de agregar el registro para ayudar a diagnosticarlo si vuelve a suceder.

    
respondido por el Karl Bielefeldt 05.10.2011 - 00:51
2

Un par de notas del lado de operaciones de la casa aquí:

1) Asegúrese de que los registros sean configurables localmente, preferiblemente con una herramienta que no sea más pesada que un editor de texto. La mayoría de las veces no queremos obtener el nivel de registro TRACE, pero nos encanta poder activarlo.

2) Si es posible, asegúrese de que los registros puedan leerse con una herramienta que no sea más pesada que un editor de texto. Nada es peor que tener que ir en una búsqueda de herramientas en una hora extraña cuando el sistema de producción está fallando.

    
respondido por el Wyatt Barnett 06.10.2011 - 01:14
1

Desde mi propia experiencia trabajando con aplicaciones web:

(& considerando que el almacenamiento es muy barato hoy en día)

  • Registre toda la información disponible (en ese momento) que pueda.
  • Siempre incluyo DateTime. Ahora en mis cadenas de registro.
  • Siempre (si es posible) registro la duración del tiempo de alguna "acción" específica.
  • Sea consistente con sus cadenas de registro. Desde siempre utilizo este tipo de patrón:

    • "[Información X] [Información Y] [Información Z] [etc.]"
respondido por el sabiland 05.10.2011 - 09:49
1

Aparte del stacktrace, registre el estado actual de la aplicación y la entrada.

El software es determinista, estos dos suelen ser lo único que necesita para reproducir el error. En algunos casos, almacenar el estado completo puede ser problemático, por lo que las formas de reproducir el estado actual, por ejemplo, mediante entradas anteriores, también son buenas.

Por supuesto, más datos siempre son mejores, pero como mínimo estos dos son un buen comienzo para los choques más fáciles.

    
respondido por el ladida 05.10.2011 - 21:38

Lea otras preguntas en las etiquetas