动态设置日志输出文件路径的最佳方法

53

我正在尝试寻找比我更聪明的人来验证我写的一些语法。我的想法是将RollingFileAppender的文件名配置为程序集的名称,以使其更易于在我的项目中重复使用。

我看过这篇SO文章, 但它并不能完全回答我的问题...

我花费了很多时间来理解Log4net的内部组件,以下是我想到的(位于Global.asax文件的Application_Start方法中):

// Bind to the root hierarchy of log4net
log4net.Repository.Hierarchy.Hierarchy root = 
  log4net.LogManager.GetRepository() 
    as log4net.Repository.Hierarchy.Hierarchy;

if (root != null)
{
  // Bind to the RollingFileAppender
  log4net.Appender.RollingFileAppender rfa = 
    (log4net.Appender.RollingFileAppender)root.Root.GetAppender("RollingLogFileAppender");

  if (rfa != null)
  {
    // Set the file name based on the assembly name
    string filePath = 
      string.Format("~/App_Data/{0}.log", GetType().Assembly.GetName().Name);

    // Assign the value to the appender
    rfa.File = Server.MapPath(filePath);

    // Apply changes to the appender
    rfa.ActivateOptions();
  }
}

有人能告诉我,“这很丑陋”,或者“这应该可以正常工作”吗?另外,如果我动态设置文件,我仍然可以期望log4net根据log4net.config文件设置轮换文件的行为吗?

非常感谢!

4个回答

127

你正在采用一种比较麻烦的方式!在应用程序的配置文件中将log4net配置定义为XML格式,并使用%property{}来获得优势:

<appender name="YourAppender" type="log4net.Appender.RollingFileAppender">
  <file type="log4net.Util.PatternString" value="~/App_Data/%property{LogName}" />
  ....
</appender>

这是动态的 -- 你只需要在初始化 log4net 之前设置 "LogName" 属性即可。因此,在你配置 log4net 之前的任何时间,都可以设置此属性的期望值:

string LogName = GetType().Assembly.GetName().Name + ".log";
log4net.GlobalContext.Properties["LogName"] = LogName;

当然,您可以使用任何属性名称。我选择“LogName”只是为了举一个简单的例子,但如果需要的话,您可以每个应用程序设置一个属性名,只要您的代码知道正确的属性名和正确的值就可以了。


2
啊,这正是我发帖的原因...它看起来比应该的要困难。谢谢你... - Dscoduc
2
你知道在使用log4netfactoryadapter时是否有相应的方法或方式来做到这一点吗?我在我的所有代码中都使用common.logging,并声明性地定义配置(app.config)。我尝试过GlobalContext方法,但最终在我的文件名中得到了(null),而我知道我使用的变量不是null。 - Kyle LeNeau
24
值得一提的是,type="log4net.Util.PatternString" 这一行非常重要。我花了两个小时搜索为什么我在 Debug 文件夹中得到 "%property{FileName}" 文件而不是 Log 文件夹中的 "events.txt"。 - Aleksey
1
多线程情况怎么办?它似乎是一个静态设置。在我的应用程序中,有许多类同时尝试将日志记录到不同的文件中,我想动态设置它们的名称。我需要同步写入并为每个线程更改相应的“LogName”属性吗? - user1713059
6
只有通过调用 log4net.Config.XmlConfigurator.ConfigureAndWatch("log4net.config.xml") 重新加载配置,这才对我起作用。 - Tobias
显示剩余7条评论

14

以下是在运行时设置或更改第一个appender日志文件的方法:

var appender = (log4net.Appender.FileAppender)LogManager.GetRepository().GetAppenders()[0];
appender.File = "C:\whatever.log";
appender.ActivateOptions();

10

2015年,我们是这样做的:

<file type="log4net.Util.PatternString">
  <conversionPattern value="%appdomain.log" />
</file>

无需其他代码。

应用程序域是执行程序集的文件名。


4

对我而言,这个日期格式是有效的 <file type="log4net.Util.PatternString" value="./Log/logQueueService%date{yyyy_MM_dd}.log" />


3
尝试更清楚地解释为什么这是问题的答案。 - Jeroen Heier
它将创建动态文件名。例如:./Log/logQueueService%date{yyyy_MM_dd}.log". -> 根路径 log -> 文件夹 logQueueService -> 固定文件名 %date{yyyy_MM_dd} -> 动态日期。 - M Danish

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