【问题标题】:log4net RollingFileAppender requiring call to Configure() on every log attemptlog4net RollingFileAppender 要求在每次日志尝试时调用 Configure()
【发布时间】:2012-04-19 23:34:15
【问题描述】:

不确定这里发生了什么,但我的日志记录代码不会写入 rollingFileAppender,除非我在每次调用时调用 XmlConfigurator.Configure()。我已经在下面的代码中打开了调试,并且可以确认当在构造函数中只调用一次 Configure 时,它​​似乎确实在拉入我的配置,但是当实际调用 Log() 时,日志文件没有任何反应或出现在调试窗口中。 如果我取消注释 Log() 中对 Configure() 的调用并让它在每次调用时重新配置,那么它工作得很好,但我认为这不是预期的用途。

奖励积分! - 我注意到第一次调用 log.Info() 没有记录,但每次运行过程中的所有后续调用都很好。

谢谢!

  public static class LogToFile
{
    public const string RollingFileAppenderName = "RollingFileLogger";

    static LogToFile()
    {
        log4net.Config.XmlConfigurator.Configure();
    }

    public static void Log(string fileNameBase, string message, string context)
    {
        if (fileNameBase == null) throw new ArgumentNullException("fileNameBase");
        if (message == null) throw new ArgumentNullException("message");
        if (context == null) throw new ArgumentNullException("context");

        //log4net.Config.XmlConfigurator.Configure();

        string fileName = string.Format("{0}_{1}.log", fileNameBase, context);
        string fullFileName = Path.Combine(Properties.Settings.Default.LogFilePath, fileName);

        if (!Directory.Exists(Properties.Settings.Default.LogFilePath)) Directory.CreateDirectory(Properties.Settings.Default.LogFilePath);

        LogicalThreadContext.Properties["LogName"] = string.Format(fullFileName);
        ILog log = LogManager.GetLogger(RollingFileAppenderName);

        log.Info(message);
    }
}

    <appender name="rollingFileAppender" type="log4net.Appender.RollingFileAppender">
  <file type="log4net.Util.PatternString" value="%property{LogName}" />
  <appendToFile value="true" />
  <rollingStyle value="Size" />
  <maxSizeRollBackups value="10" />
  <maximumFileSize value="2MB" />
  <countDirection value="-1"/>
  <LockingModel value="log4net.Appender.FileAppender+MinimalLock"/>
  <staticLogFileName value="false" />
  <immediateFlush value="true" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="AlertMessageHandler Message : %-25date [%thread] - %newline%message%newline" />
  </layout>
</appender>

【问题讨论】:

    标签: c# log4net


    【解决方案1】:

    您的配置文件表明日志文件名称设置为使用您在运行时更改的 LogName 属性。我一直认为,如果不重新初始化 appender(通过调用 ActivateOptions)或调用 XmlConfigurator.Configure(),则不允许您在运行时更改 appender 的属性,这更容易但会做更多的事情。

    同样在你的日志方法中,如果你在设置 LogName 之前调用 XmlConfigurator.Configure(),那么我怀疑你的第一个调用会失败(试图写入 null)并且你的第二个调用会写到应该与第一次调用一起使用的文件。

    如果您将 XmlConfigurator.Configure() 移至 设置 LogName,它应该可以正常工作。

    【讨论】:

    • 你说的很有道理。 :) 我尝试获取我的 RollingFileAppender 并调用 ActivateOptions(),但这不起作用。也许设置 LogName 属性超出了 ActivateOptions() 可以刷新的范围。所以我一直在调用configure ...但是您确实在更改属性后引导我调用Configure(),这意味着我不再丢失第一条消息或写入错误的文件。谢谢!
    • 如果您有对 appender 的引用,那么您应该可以直接将其 File 属性设置为 fullFileName,然后调用 ActivateOptions 这可能意味着您不需要 LogName 属性。
    • 我看到你打败了这个结论 -)
    • 是的,我做到了。但这只是因为你让我更多地考虑在代码中弄乱附加程序。谢谢!
    【解决方案2】:

    尝试在你的方法之外声明 log 变量:

    private static readonly ILog log = LogManager.GetLogger(typeof(LogToFile));
    

    这就是我使用它的方式,我不得不提出问题。但是,就我而言,我没有登录静态类。

    另外,我的附加信息位于我在 XmlConfigurator.Configure() 函数中指定的文件中。

    log4net.Config.XmlConfigurator.Configure(new FileInfo(configFile));
    

    【讨论】:

    • 我尝试将 ILog 移出,但没有改变任何东西。我确实注意到我不需要在每个日志记录调用上调用配置,但我确实需要调用它直到第一个成功的消息。这可以解释为什么在构造函数中调用它不起作用(log4net 没有记录第一条消息)。
    【解决方案3】:

    实际上 sgmoore 的建议让我找到了解决方案。如果我可以只在 Appender 对象上命名日志文件而不是弄乱配置文件属性,那么调用 ActivateOptions 就可以了。这是工作代码。谢谢!

    public static class LogToFile
    {
        public const string RollingFileLoggerName = "RollingFileLogger";
    
        public const string RollingFileAppenderName = "rollingFileAppender";
    
        private static readonly ILog Logger = LogManager.GetLogger(RollingFileLoggerName);
    
        /// <summary>
        /// Logs to log4net rollingFileAppender
        /// </summary>
        /// <param name="fileNameBase">prefix of log filename</param>
        /// <param name="message">log4net message property</param>
        /// <param name="context">files grouped by context</param>
        public static void Log(string fileNameBase, string message, string context)
        {
            if (fileNameBase == null) throw new ArgumentNullException("fileNameBase");
            if (message == null) throw new ArgumentNullException("message");
            if (context == null) throw new ArgumentNullException("context");
    
            string fileName = string.Format("{0}_{1}.log", fileNameBase, context);
            string fullFileName = Path.Combine(Properties.Settings.Default.LogFilePath, fileName);
    
            if (!Directory.Exists(Properties.Settings.Default.LogFilePath)) Directory.CreateDirectory(Properties.Settings.Default.LogFilePath);
    
            ActivateAppenderOptions(string.Format(fullFileName));
    
            Logger.Info(message);
        }
    
        /// <summary>
        /// Update the appender in log4net after setting the log file path
        /// </summary>
        /// <param name="filename"></param>
        private static void ActivateAppenderOptions(string filename)
        {
            var hierarchy = (Hierarchy)LogManager.GetRepository();
            var appenders = hierarchy.GetAppenders();
            foreach (
                var rfa in appenders.OfType<RollingFileAppender>().Where(rfa => rfa.Name == RollingFileAppenderName))
            {
                rfa.File = filename;
                rfa.ActivateOptions();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多