log4net RollingFileAppender需要在每次尝试日志时调用Configure()

时间:2012-04-19 13:33:22

标签: c# log4net

不知道这里发生了什么,但我的日志代码不会写入rollingFileAppender,除非我在每次调用时调用XmlConfigurator.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>

3 个答案:

答案 0 :(得分:2)

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

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

如果您在之后将XmlConfigurator.Configure()移动到,则设置LogName,它应该可以正常工作。

答案 1 :(得分:1)

尝试以这种方式在您的方法之外声明日志变量:

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

这就是我使用它的方式,我必须解决问题。但是,就我而言,我没有登录静态类。

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

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

答案 2 :(得分:1)

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