每个类实例的唯一日志文件

Kil*_*ine 17 c# service logging log4net

我目前正在运行一个创建多个类实例的Windows服务.

在服务类的顶部和我的解决方案中的每个其他类,我有这样的事情:

private static readonly ILog _log = LogManager.GetLogger(typeof(SomeClassTypeHere));
Run Code Online (Sandbox Code Playgroud)

在我的App.config中,我为单个文件配置了Log4Net:

<log4net debug="true">
    <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
      <file value="Logs\SomeLogFileName.xml" />
      <appendToFile value="true" />
      <rollingStyle value="Size" />
      <countDirection value="1" />
      <maxSizeRollBackups value="30" />
      <maximumFileSize value="10MB" />
      <staticLogFileName value="true" />
      <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
      <layout type="log4net.Layout.XmlLayoutSchemaLog4j">
        <locationInfo value="true" />
      </layout>
    </appender>

    <root>
      <level value="INFO" />
      <appender-ref ref="RollingFileAppender" />
    </root>
  </log4net>
Run Code Online (Sandbox Code Playgroud)

这在大多数方面都很有效,并且所有内容都记录到单个文件中.但是,我真的想为我的服务创建的特定类的每个实例创建一个单独的日志文件.
这是一个我们经常需要监视以获得支持的类,我们可以同时运行少量实例.
我们不知道哪些实例将在给定时间运行,因此它使得在配置中创建静态文件有点痛苦.

我尝试取消readonly修饰符并在类构造函数中设置以下内容:

_log = LogManager.GetLogger("DataCollectionClass_" + deviceName + "_" + DateTime.Now.ToString("MMddyyyy"), typeof(SomeClassTypeHere));
Run Code Online (Sandbox Code Playgroud)

但这需要我在配置中手动定义一个appender,这将是繁琐且难以跟上的.

有关在L4N这样做的任何想法?我在这里看过链接,但不知道是否需要那么多的框架.

dho*_*hee 14

下面的代码显示了如何在不使用配置文件的情况下以编程方式配置log4Net以实现您正在寻找的效果.基本上,它只涉及创建一个命名的记录器并添加到层次结构中.

我用这里的答案作为起点之一.

using log4net;
using log4net.Appender;
using log4net.Layout;
using log4net.Repository.Hierarchy;

namespace LoggerTest
{
    class Program
    {
        static void Main(string[] args)
        {
            DeviceConnection dev1 = new DeviceConnection("Device1");
            DeviceConnection dev2 = new DeviceConnection("Device2");

            dev1.DoSomething();
            dev2.DoSomething();
        }
    }

    public class DeviceConnection
    {
        private string name;
        private readonly ILog logger;

        public DeviceConnection(string _name)
        {
            name = _name;

            logger = TestLogger.AddNamedLogger(name);

            logger.Info("----  Begin Logging for DeviceConnection: " + name);
        }

        public void DoSomething()
        {
            logger.Info("Doing something for device connection " + name);
        }
    }

    public static class TestLogger
    {
        private static PatternLayout _layout = new PatternLayout();
        private const string LOG_PATTERN = "%d [%t] %-5p %m%n";

        public static string DefaultPattern
        {
            get { return LOG_PATTERN; }
        }

        static TestLogger()
        {
            _layout.ConversionPattern = DefaultPattern;
            _layout.ActivateOptions();

            Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();
            hierarchy.Configured = true;
        }

        public static PatternLayout DefaultLayout
        {
            get { return _layout; }
        }

        public static ILog AddNamedLogger(string name)
        {
            Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();
            Logger newLogger = hierarchy.GetLogger(name) as Logger;

            PatternLayout patternLayout = new PatternLayout();
            patternLayout.ConversionPattern = LOG_PATTERN;
            patternLayout.ActivateOptions();

            RollingFileAppender roller = new RollingFileAppender();
            roller.Layout = patternLayout;
            roller.AppendToFile = true;
            roller.RollingStyle = RollingFileAppender.RollingMode.Size;
            roller.MaxSizeRollBackups = 4;
            roller.MaximumFileSize = "100KB";
            roller.StaticLogFileName = true;
            roller.File = name + ".log";
            roller.ActivateOptions();

            newLogger.AddAppender(roller);

            return LogManager.GetLogger(name);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)