log4net从外部配置文件设置无效

4
我遇到了一个log4net的奇怪问题。
在一个ASP.NET应用程序中,我想要外部配置log4net,因此我有一个单独的log4net.config文件,我通过在属于我的Web应用程序的AssemblyInfo.cs文件中使用以下行来连接它:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4Net.config", Watch = true)]

现在,如果我像这样正常实例化log4net日志记录器类:
public class MyClass
{
    private static readonly ILog _logger = log4net.LogManager.GetLogger(typeof(MyClass));
    ....

这样做是有效的,记录日志也像平常一样工作。然而,我将我的日志代码封装在一个LogManager类中,它是一个单独的程序集(Infrastructure)的一部分,并且被多个项目重复使用。它有一个GetLogger方法,看起来像这样:

public static class LogManager
{
    public static ILog GetLogger()
    {
        var stack = new StackTrace();
        var frame = stack.GetFrame(1);
        return new log4net.LogManager.GetLogger(frame.GetMethod().DeclaringType);
    }
}

所以我可以在我的asp.net代码中使用这个:

public class MyClass
{
    private static readonly ILog _logger = LogManager.GetLogger();
    ....

但是...这不起作用!没有日志记录。它似乎没有正确地连接配置文件。如果我直接将log4net配置放入web.config中,那么LogManager可以正常工作。


1
Log4Net在第一次被激活时是否会扫描程序集属性?因此,如果该属性未在该程序集中定义,则不会按预期设置它? - Tim Lloyd
是的,可能是这样-这可能与Eben在下面的回复有关。 - Matt Roberts
2个回答

3

总结Bibhu所说的内容,与log4net.Config.XmlConfigurator有关。

在开始记录日志之前,您必须配置log4net。因此,无论何时使用LogManager类,主机应用程序(Windows、Web)都必须配置日志记录。

要么是这样,要么您需要在您的LogManager中进行配置。


所以,如果使用LogManager类,并且该类在另一个程序集中,则需要在global.asax.cs中手动调用XmlConfigurator.Configure()。这样可以解决问题,但我不明白为什么如果我按照正常方式设置我的_logger,它也能工作? - Matt Roberts
啊!根据chibacity的评论,我可能错过了那个--- [assembly: log4net.Config.XmlConfigurator...] 这一部分是在哪里定义的?关键是托管应用程序必须配置log4net(不管是怎么配置的)。 - Eben Roux
没错 - 看起来就是这个问题!因为我把LogManager移动到另一个没有程序集属性的程序集中,所以它不起作用了!现在一切都说得通了。 - Matt Roberts

2
告诉应用程序使用外部配置文件配置log4net。实际上有两个位置可以这样做。首先是global.asax文件,其次是assemblyInfo.cs文件。请注意,大多数情况下,您将从包含所有代码的global.asax文件开始。出于某种原因,我唯一能让它工作的方法是将global.asax拆分为使用代码后台,然后再添加assemblyInfo.cs文件。所以最终看起来像这样。
global.asax:

<%@ Application Language="C#" Inherits="GlobalAsax" %>

global.asax.cs (in your App_Code folder):

using System;
using System.Web;

public class GlobalAsax : HttpApplication
{
    // you may have lots of other code here
    void Application_Start(object sender, EventArgs e)
    {
        log4net.Config.XmlConfigurator.Configure();
    }
}

现在您的应用程序已经调用log4net的配置,您可以在程序集信息中设置一个属性,以便log4net知道在哪里查找配置文件。

AssemblyInfo.cs (in your App_Code folder):

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]

watch标记告诉log4net监视配置文件的潜在更改。如果您想在测试中从记录全部更改为仅记录错误,则此功能非常有用。

接着,开始记录日志。


不太确定为什么你给了我一个Udp配置要使用,但我认为你的主要观点是调用.Configure()方法。但我印象中程序集属性可以省去这个步骤,不需要这样做吧? - Matt Roberts
@Matt Roberts - 看看这个问题,它可能会对你有所帮助。https://dev59.com/pHI-5IYBdhLWcg3wq6do - Bibhu
谢谢,但那更多是最佳实践。我所做的对我来说是有效的,而且我很满意,但将代码移入LogManager后出现了问题 :) - Matt Roberts
@Matt Roberts - 你的代码应该是可以工作的。你能再检查一下log4net.config文件吗?http://logging.apache.org/log4net - Bibhu
感谢您的努力,但是您最新的答案有点错误。如果您使用程序集属性来连接配置文件,则不需要在Global.asax.cs中再次连接它。相反,您只需调用XmlConfigurator.Configure();即可。 - Matt Roberts

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接