3

不确定这里发生了什么,但我的日志记录代码不会写入 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>
4

3 回答 3

2

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

同样在您的日志方法中,如果您在设置 LogName之前调用 XmlConfigurator.Configure() ,那么我怀疑您的第一次调用会失败(尝试写入 null),而您的第二次调用将写入应该使用的文件第一个电话。

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

于 2012-04-19T14:58:32.883 回答
1

实际上 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();
        }
    }
}
于 2012-04-19T15:34:15.143 回答
1

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

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

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

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

log4net.Config.XmlConfigurator.Configure(new FileInfo(configFile));
于 2012-04-19T14:01:54.177 回答