2009-08-13 7 views
5

Estoy tratando de descubrir las mejores prácticas cuando se inician las excepciones.Quién debería registrar un error/excepción

Hasta ahora, estoy registrando cada vez que atrapo una excepción. Pero cuando una clase de palanca inferior capta una excepción (por ejemplo, desde la capa de la base de datos) y la envuelve en nuestra propia excepción de aplicación, ¿debería también registrar allí la excepción original o debería dejar que la clase de palanca superior registre todos los detalles?
¿Y qué pasa con las ubicaciones donde mi clase de nivel inferior decide lanzar una excepción debido a los parámetros de entrada incorrectos? ¿Debería registrar también la excepción o, una vez más, dejar que el código de captura lo registre?

Respuesta

6

Principalmente debe evitar iniciar sesión en una captura de nivel inferior y una captura de nivel superior, ya que esto satura el registro con información redundante (sin mencionar que toma recursos de E/S adicionales para escribir en el registro).

Si está buscando información general de mejores prácticas sobre el manejo de excepciones, this link is handy.

-1

log donde lo atrapas, si estás envolviendo, entonces deberías. Si la envoltura inferior no tiene, entonces tienes una razón (para debugability) para hacerlo. Sin embargo, no trague la excepción a menos que sepa que es benigno o que puede manejarlo.

me gustaría sugerir

try{ 
. 
. 
. 
} catch(Exception ex){ 
... log .... 
throw; 
} 

si tienes que entrar y pasar la excepción de.

+0

"Sin embargo no lo hacen tragar la excepción a menos que sepa su benigno o puedes manejarlo ". - Incluso entonces no deberías tragarlo. En mi humilde opinión, para eso existen los niveles de registro. –

+0

No estoy de acuerdo: si una API está diseñada para dar excepciones cuando, como MSMQ, debe tragar y aceptar que eso es todo. Obviamente, debe estar seguro del tipo y contenido de la excepción. –

4

Puede iniciar sesión solo una vez en el nivel superior de su aplicación, siempre que su código de registro (a) registre el seguimiento de la pila de una excepción y (b) registre toda la cadena de excepciones internas como bien.

El bloque de aplicaciones de manejo de excepciones de Microsoft se encarga de ambas cosas. Creo que otros frameworks de registro harían lo mismo.

0

En las aplicaciones de mi winform creé algunos Observer para el registro. Observer tiene suscriptores que pueden escribir el registro en algún lugar o procesarlo. mirada de It: clase abstracta

public static class LoggingObserver 
    { 
     /// <summary> 
     /// Last getted log message 
     /// </summary> 
     public static string LastLog; 

     /// <summary> 
     /// Last getted exception 
     /// </summary> 
     public static Exception LastException; 

     /// <summary> 
     /// List of log's processors 
     /// </summary> 
     public static List<BaseLogging> loggings = new List<BaseLogging>(); 

     /// <summary> 
     /// Get Exception and send for log's processors 
     /// </summary> 
     /// <param name="ex">Exception with message</param> 
     public static void AddLogs(Exception ex) 
     { 
      LastException = ex; 
      LastLog = string.Empty; 
      foreach (BaseLogging logs in loggings) 
      { 
       logs.AddLogs(ex); 
      } 
     } 

     /// <summary> 
     /// Get message log for log's processors 
     /// </summary> 
     /// <param name="str">Message log</param> 
     public static void AddLogs(string str) 
     { 
      LastException = null; 
      LastLog = str; 
      foreach (BaseLogging logs in loggings) 
      { 
       logs.AddLogs(str); 
      } 
     } 

     /// <summary> 
     /// Close all processors 
     /// </summary> 
     public static void Close() 
     { 
      foreach (BaseLogging logs in loggings) 
      { 
       logs.Close(); 
      } 
     } 
    } 

del suscriptor:

public abstract class BaseLogging 
    { 
     /// <summary> 
     /// Culture (using for date) 
     /// </summary> 
     public CultureInfo culture; 

     /// <summary> 
     /// Constructor 
     /// </summary> 
     /// <param name="culture">Culture</param> 
     public BaseLogging(CultureInfo culture) 
     { 
      this.culture = culture; 
     } 

     /// <summary> 
     /// Add log in log system 
     /// </summary> 
     /// <param name="str">message of log</param> 
     public virtual void AddLogs(string str) 
     { 
      DateTime dt = DateTime.Now; 

      string dts = Convert.ToString(dt, culture.DateTimeFormat); 

      WriteLine(String.Format("{0} : {1}", dts, str)); 
     } 

     /// <summary> 
     /// Add log in log system 
     /// </summary> 
     /// <param name="ex">Exception</param> 
     public virtual void AddLogs(Exception ex) 
     { 
      DateTime dt = DateTime.Now; 

      string dts = Convert.ToString(dt, culture.DateTimeFormat); 
      WriteException(ex); 
     } 

     /// <summary> 
     /// Write string on log system processor 
     /// </summary> 
     /// <param name="str">logs message</param> 
     protected abstract void WriteLine(string str); 

     /// <summary> 
     /// Write string on log system processor 
     /// </summary> 
     /// <param name="ex">Exception</param> 
     protected abstract void WriteException(Exception ex); 

     /// <summary> 
     /// Close log system (file, stream, etc...) 
     /// </summary> 
     public abstract void Close(); 
    } 

y la aplicación para el registro en el archivo:

/// <summary> 
    /// Logger processor, which write log to some stream 
    /// </summary> 
    public class LoggingStream : BaseLogging 
    { 
     private Stream stream; 

     /// <summary> 
     /// Constructor. 
     /// </summary> 
     /// <param name="stream">Initialized stream</param> 
     /// <param name="culture">Culture of log system</param> 
     public LoggingStream (Stream stream, CultureInfo culture) 
      : base(culture) 
     { 
      this.stream = stream; 
     } 

     /// <summary> 
     /// Write message log to stream 
     /// </summary> 
     /// <param name="str">Message log</param> 
     protected override void WriteLine(string str) 
     { 
      try 
      { 
       byte[] bytes; 

       bytes = Encoding.ASCII.GetBytes(str + "\n"); 
       stream.Write(bytes, 0, bytes.Length); 
       stream.Flush(); 
      } 
      catch { } 
     } 

     /// <summary> 
     /// Write Exception to stream 
     /// </summary> 
     /// <param name="ex">Log's Exception</param> 
     protected override void WriteException(Exception ex) 
     { 
      DateTime dt = DateTime.Now; 

      string dts = Convert.ToString(dt, culture.DateTimeFormat); 
      string message = String.Format("{0} : Exception : {1}", dts, ex.Message); 
      if (ex.InnerException != null) 
      { 
       message = "Error : " + AddInnerEx(ex.InnerException, message); 
      } 
      WriteLine(message); 
     } 
     /// <summary> 
     /// Closing stream 
     /// </summary> 
     public override void Close() 
     { 
      stream.Close(); 
     } 

     private string AddInnerEx(Exception exception, string message) 
     { 
      message += "\nInner Exception : " + exception.Message; 
      if (exception.InnerException != null) 
      { 
       message = AddInnerEx(exception.InnerException, message); 
      } 
      return message; 
     } 
    } 

Usando:

//initialization 
FileStream FS = new FileStream(LogFilePath, FileMode.Create); 
LoggingObserver.loggings.Add(new LoggingStream(FS, Thread.CurrentThread.CurrentCulture)); 
//write exception 
catch (Exception ex) { 
LoggingObserver.AddLog(new Exception ("Exception message", ex)); 
} 
//write log 
LoggingObserver.AddLog("Just a log"); 
+0

¿Cómo responde esto las preguntas del OP? – Nelson

+0

Uso de varios suscriptores para los registros de proceso. Son mis mejores prácticas. – Chernikov

Cuestiones relacionadas