【问题标题】:log4net in Program.csProgram.cs 中的 log4net
【发布时间】:2012-10-01 07:28:14
【问题描述】:

我刚刚在我的 C# WinForms 应用程序中设置了 log4net,方法是添加引用、将配置添加到 App.config 以及在 AssemblyInfo.cs 中加载条目。配置设置为捕获所有级别。

在我的 Program.cs 中,我试图让它捕获每一个错误。

我目前有这个:

    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        private static readonly ILog log = LogManager.GetLogger(typeof(Program));
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            try
            {
                log.Info("this works");
                Application.Run(new Forms.Main());
            }
            catch (Exception e)
            {
                log.Info("nothing here", e);
            }
        }
    }

我将“this works”放入只是为了测试我是否可以实际写入日志文件,这就是日志中显示的内容:

2012-09-30 23:00:53,959 [INFO ] - this works

我的 log4net 也设置为写入即时窗口,所以我故意创建了一些错误,这就是我在窗口中看到的:

ContractManagement.Program: 2012-09-30 23:08:09,177 [INFO ] - this works
A first chance exception of type 'System.Data.SqlServerCe.SqlCeException' occurred in System.Data.SqlServerCe.dll

我也希望在日志中看到第二个错误,但没有任何迹象:(


根据 Keith Nicholas 的评论,我这样做了:

static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    log.Info("this works");
    throw new System.ArgumentException("Keith Nicholas Test");
    //Application.Run(new Forms.Main());

}

日志文件显示:

2012-09-30 23:19:12,090 [INFO ] - this works
System.ArgumentException: Keith Nicholas Test
   at ContractManagement.Program.Main() in c:\ContractManagement\ContractManagement\Program.cs:line 25

【问题讨论】:

    标签: c# winforms log4net


    【解决方案1】:
    A first chance exception of type 'System.Data.SqlServerCe.SqlCeException' occurred in System.Data.SqlServerCe.dll
    

    这不是您的 log4net 配置的问题。其中一个内部库引发了异常,然后将其捕获,因此它永远不会出现在您的 catch 子句中。开发环境将捕获到的异常信息直接写到即时窗口中。

    是的 log4net 正在写入即时窗口,但并非即时窗口中的所有内容都来自 log4net。

    [更新 - 反映记录多个线程的更普遍问题]

    虽然与您的问题没有直接关系,但有时使用 log4net 日志记录的类可以同时在不同的线程中执行。您可以同时从多个线程获取调试、信息和/或错误方法。建议您更新 App.config 中的消息模式以包含线程,以便您可以跟踪哪个消息来自哪个线程。例如:

    <conversionPattern value="%level %thread %logger - %message%newline" />
    

    这只是一个示例 - 您没有包含转换模式,所以我不确定如果您要添加 %thread 会是什么样子。

    【讨论】:

    • 所以如果另一个线程导致错误,我如何让 ly log4net 也捕获它?我并不特别想在整个应用程序中添加日志条目。
    • 对不起,如果我不清楚。我已经重写了答案的那一部分。我不是建议你添加一堆 catch 语句,只是对你的配置文件做一个小的修改。
    • 抱歉,我好像不太清楚。我接受了你所说的并更新了我的配置,但我的评论是关于原始问题和你答案的第一段。
    • 一个很好的问题。我不知道如何将这些“第一次机会异常”消息重定向到 log4net 或什至可能。我只是忽略它们。如果异常没有出现在我的代码中,那么就我而言,这是其他人程序集的实现细节,而不是我的问题。
    【解决方案2】:

    如果从新线程抛出异常,它不会被那个 catch 块捕获....

    只是为了证明您的日志记录工作正常:-

    无需运行您的应用程序,只需在第一个 log.Info 之后立即抛出一个新异常,以证明您的异常日志记录有效。

    喜欢:-

    try
    {
        log.Info("this works");
        throw new System.ArgumentException("Keith Nicholas Test");
    }
    catch (Exception e)
    {
       log.Info("nothing here", e);
    }
    

    【讨论】:

    • 这在日志中给出了以下内容:2012-10-01 00:08:02,127 9 ContractManagement.Program [INFO] - 这个工作 2012-10-01 00:08:02,136 9 ContractManagement.Program [信息] - 这里什么都没有 System.ArgumentException: Keith Nicholas 在 c:\ContractManagement\ContractManagement\Program.cs:line 26 中的 ContractManagement.Program.Main() 测试
    • 对,所以日志记录工作正常......所以任何冒泡的异常都会达到这一点。所以真的,你的问题是异常是否会冒泡到那个时候。 (就像已经提到的那样,一些在 Visual Studio 窗口中获得输出的只是显示抛出异常,但它们随后会被处理,而且在不同线程上抛出的任何东西此时也不会出现)
    【解决方案3】:

    后来我用谷歌搜索了很多,我有:

    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        private static readonly ILog log = LogManager.GetLogger(typeof(Program));
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
    
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
            Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
            AppDomain.CurrentDomain.FirstChanceException += FirstChanceHandler;
    
            Application.Run(new Forms.Main());
        }
    
        private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
        {
            log.Info(e.Exception.Message);
        }
    
        private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            log.Info(e);
        }
    
        static void FirstChanceHandler(object source, FirstChanceExceptionEventArgs e)
        {
            log.Info(e.Exception.Message);
        }
    }
    

    这会捕获我希望捕获的 FirstChanceExceptions:

    2012-10-01 00:24:02,532 9 ContractManagement.Program [INFO ] - The database file cannot be found. Check the path to the database. [ Data Source = C:\ContractManagement\ContractManagement\bin\Debug\ContractManagement.sdf ]
    

    【讨论】:

      猜你喜欢
      • 2022-11-02
      • 1970-01-01
      • 1970-01-01
      • 2017-06-03
      • 2020-07-11
      • 1970-01-01
      • 1970-01-01
      • 2020-10-09
      • 1970-01-01
      相关资源
      最近更新 更多