Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 谁应该记录错误/异常_C#_Exception_Logging_Exception Handling - Fatal编程技术网

C# 谁应该记录错误/异常

C# 谁应该记录错误/异常,c#,exception,logging,exception-handling,C#,Exception,Logging,Exception Handling,我试图找出记录异常时的最佳实践 到目前为止,我每次捕获异常都会记录日志。但是,当一个较低级别的类捕获到一个异常(例如,来自数据库层)并将其包装到我们自己的应用程序异常中时,我应该在那里记录原始异常,还是应该让较高级别的类记录所有细节? 那么,我的低级类由于输入参数错误而决定抛出异常的位置呢?它是否也应该在那里记录异常,或者再次让捕获代码记录它?记录捕获的位置,如果您正在包装,那么您应该这样做。如果较低的包装没有,那么您有理由这样做(为了可调试性)。但是,除非你知道异常是良性的或者你能处理它,否则

我试图找出记录异常时的最佳实践

到目前为止,我每次捕获异常都会记录日志。但是,当一个较低级别的类捕获到一个异常(例如,来自数据库层)并将其包装到我们自己的应用程序异常中时,我应该在那里记录原始异常,还是应该让较高级别的类记录所有细节?

那么,我的低级类由于输入参数错误而决定抛出异常的位置呢?它是否也应该在那里记录异常,或者再次让捕获代码记录它?

记录捕获的位置,如果您正在包装,那么您应该这样做。如果较低的包装没有,那么您有理由这样做(为了可调试性)。但是,除非你知道异常是良性的或者你能处理它,否则不要接受它

我建议

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

如果需要记录并传递异常。

主要应避免将其同时记录在较低级别的捕获和较高级别的捕获中,因为这会使日志中包含冗余信息(更不用说会占用额外的IO资源写入日志)


如果您正在寻找有关异常处理的一般最佳实践信息,.

只要您的日志代码(a)记录异常的堆栈跟踪,以及(b)记录整个内部异常链,您就可以在应用程序的最高层只记录一次日志


Microsoft异常处理应用程序块为您处理这两件事。我想其他日志框架也会这样做。

在我的winform应用程序中,我创建了一些日志观察程序。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();
            }
        }
    }

“但是,除非你知道它是良性的,或者你能处理它,否则不要吞下它。”——即使这样,你也不应该吞下它。这就是日志级别存在的目的。我不同意——如果api设计为在类似MSMQ的情况下提供异常,那么您必须接受并接受这一点。显然,您必须确定异常类型和内容。这是如何回答OP的问题的?使用各种订阅服务器获取流程日志。这是我的最佳实践。
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");