简体   繁体   English

Program.cs中的log4net

[英]log4net in Program.cs

I have just set up log4net in my C# WinForms application by adding the reference, adding the configuration to App.config and the load entry in AssemblyInfo.cs. 我刚刚在C#WinForms应用程序中通过添加引用,在App.config中添加配置以及在AssemblyInfo.cs中添加了加载项来设置了log4net。 The config is set to catch ALL levels. 配置设置为捕获所有级别。

In my Program.cs, I am trying to make it catch every single error. 在我的Program.cs中,我试图使其捕获每个错误。

I currently have this: 我目前有这个:

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

I put the "this works" in just to test that I can actually write to the log file, and this what shows up in the log: 我输入“ this works”只是为了测试我是否可以实际写入日志文件,并且日志中会显示以下内容:

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

My log4net is also set up to write to the Immediate Window, so I've created some errors on purpose and this is what I see in the window: 我的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

I would have expected to see the second error in the logs as well, but there is no sign of it :( 我本来希望在日志中也看到第二个错误,但是没有迹象表明:(


Following Keith Nicholas's comment, I have done this: 根据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());

}

And the log file shows: 日志文件显示:

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
A first chance exception of type 'System.Data.SqlServerCe.SqlCeException' occurred in System.Data.SqlServerCe.dll

It's not a problem with your log4net configuration. 您的log4net配置不是问题。 One of the internal libraries threw an exception and then caught it so it never made it to your catch clause. 内部库之一引发了异常,然后将其捕获,因此它从未进入您的catch子句。 The development environment wrote out the the information about the caught exception directly to the immediate window. 开发环境将有关捕获的异常的信息直接写到立即窗口。

Yes log4net is writing to the immediate window, but not everything in the immediate window is from log4net. 是的,log4net正在写入即时窗口,但并非即时窗口中的所有内容都来自log4net。

[update - to reflect more general issues with logging multiple threads] [更新-以反映与记录多个线程有关的更多一般性问题]

Although not directly related to your question, sometimes a class which has been instrumented with log4net logging, can be executing in different threads at the same time. 尽管与您的问题没有直接关系,但是有时已用log4net日志记录的类可以同时在不同的线程中执行。 You may get debug, info and/or error methods from multiple threads at the same time. 您可以同时从多个线程获取调试,信息和/或错误方法。 Recommend you update the message pattern in your App.config to include the thread, so you can keep track of which message came from which thread. 建议您在App.config中更新消息模式以包括该线程,以便您可以跟踪哪个消息来自哪个线程。 For example: 例如:

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

This is just an example - you did not include your conversion pattern so I'm not sure exactly what yours would look like if you were to add %thread. 这只是一个例子-您没有包括转换模式,因此我不确定如果要添加%thread的情况。

If an exception is thrown from a new thread, it won't get caught by that catch block.... 如果从新线程抛出异常,则该异常不会被该catch块捕获...。

Just to prove your logging is working ok :- 只是为了证明您的日志记录工作正常:-

instead of running your application, just throw a new Exception right after the first log.Info to prove your exception logging works. 无需运行您的应用程序,只需在第一个log.Info之后立即抛出一个新的Exception即可证明您的异常日志记录有效。

like :- 喜欢 :-

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

Lots of Googling later, I have: 大量使用Google搜索之后,我得到了:

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

This catches the FirstChanceExceptions I was hoping to capture: 这捕获了我希望捕获的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 ]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM