2009-08-13 2 views
5

로그 예외가 발생할 때 모범 사례를 파악하려고합니다.누가 오류/예외를 기록해야합니까?

지금까지 예외를 잡을 때마다 기록했습니다. 그러나 하위 레버 클래스가 예외 (예 : 데이터베이스 계층)를 catch하고 자체 응용 프로그램 예외에서 래핑 할 때 - 원래 예외를 기록해야합니까? 아니면 상위 레버 클래스가 모든 세부 정보를 기록하도록해야합니까?
입력 매개 변수가 잘못되어 하위 클래스에서 예외를 throw하기로 결정한 위치는 어떻게됩니까? 그것도 거기에 예외를 기록해야합니까, 아니면, 다시 한번, 잡기 코드가 그것을 기록하게 만드시겠습니까?

답변

6

주로 하위 수준의 catch와 상위 수준의 catch에 모두 기록하지 않아야합니다. 중복되는 정보로 로그를 압축하므로 로그에 쓸 IO 리소스가 추가로 필요하지 않습니다.

예외 처리에 대한 일반적인 최상의 방법 정보를 찾고있는 경우 this link is handy입니다.

-1

로그 어디에 붙잡습니까? 다음에 랩핑해야합니다. 하위 래퍼가 그렇지 않으면 디버깅 가능성에 대한 이유가 있습니다. 그러나 자각하지 못하거나 처리 할 수 ​​없다면 예외를 삼가십시오. 당신이 로그에 예외를 전달해야하는 경우

나는

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

을 건의 할 것입니다.

+0

"그러나 삼키지 않는다 예외를 알지 못한다면 양성이거나 당신이 그것을 처리 할 수 ​​있습니다. " - 그럼에도 불구하고 그것을 삼켜서는 안됩니다. IMHO는 로그 수준이 존재하는 곳입니다. –

+0

나는 동의하지 않는다. API가 MSMQ와 같은 예외를주기 위해 고안된 것이라면, 그것을 삼키고 받아 들여야한다. 물론 예외 유형과 내용을 확실히 알아야합니다. –

4

로깅 코드 (a)가 예외의 스택 추적을 기록하고 (b) 내부 예외의 전체 체인을 다음과 같이 기록하는 경우 앱의 최상위 수준에서 한 번만 로깅 할 수 있습니다. 잘.

Microsoft 예외 처리 응용 프로그램 블록은 이러한 두 가지 작업을 모두 처리합니다. 나는 다른 로깅 프레임 워크가 똑같이 할 것이라고 생각한다.

0

내 winform의 응용 프로그램에서 로깅을위한 Observer를 만들었습니다. Observer에는 구독자가 있습니다. 구독자는 어딘가에서 로그를 작성하거나 처리 할 수 ​​있습니다. 그것의 모양 :

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(); 
      } 
     } 
    } 

가입자의 추상 클래스 :

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(); 
    } 

그리고 구현은 로깅 파일을 위해 :

/// <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; 
     } 
    } 

사용 :

//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

OP의 질문에 어떻게 대답합니까? – Nelson

+0

프로세스 로그에 다양한 가입자를 사용합니다. 그것은 제 모범 사례입니다. – Chernikov

관련 문제