Подтвердить что ты не робот

Уникальный файл журнала для каждого экземпляра класса

В настоящее время я запускаю службу Windows, которая создает несколько экземпляров класса.

В верхней части класса сервиса и каждого другого класса в моем решении у меня есть что-то вроде этого:

private static readonly ILog _log = LogManager.GetLogger(typeof(SomeClassTypeHere));

В моем приложении 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>

Это отлично работает во многих отношениях, и все регистрируется в одном файле. Тем не менее, мне бы очень хотелось создать отдельный файл журнала для каждого экземпляра определенного класса, который создает мой сервис.
Это класс, который нам часто нужно отслеживать для поддержки, и у нас может быть несколько экземпляров, запущенных одновременно.
Мы не знаем, какие экземпляры будут выполняться в данный момент времени, поэтому он делает создание статических файлов в конфигурации более болезненным.

Я попытался снять модификатор readonly и установить в конструкторе класса следующее:

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

Но для этого требуется, чтобы я определял приложение вручную в конфигурации, что было бы громоздким и жестким, чтобы не отставать.

Любые мысли об этом в L4N? Я видел ссылки здесь, но на самом деле не знаю, нужна ли такая каркас.

4b9b3361

Ответ 1

В приведенном ниже коде показано, как вы можете программно настроить 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);
        }
    }
}

Ответ 2

Используйте приложение ADO.Net и войдите в базу данных SQL Server и просто запросите необходимую информацию.

Другой альтернативой является панель мониторинга log4net: http://www.l4ndash.com/. Он делает довольно приличную работу по интеграции журналов из разных источников, а затем разрезает и нарезает их по-разному. Reasonbly тоже оценена.

Ответ 3

log4net имеет концепцию, называемую иерархией журналов.

Говорят, что логгер предка другого регистратора, если его имя, за которым следует точка, является префиксом имя регистратора потомков. Регистратор считается родителем ребенка logger, если нет предков между собой и потомком регистратор. Иерархия работает очень так же, как пространство имен и иерархии классов в .NET. Это очень как мы скоро увидим.

Таким образом, вам действительно нужно создавать специфические для вашего экземпляра журналы с символами . вместо _ символов.

_log = LogManager.GetLogger("DataCollectionClass." + deviceName + "." + DateTime.Now.ToString("MMddyyyy"), typeof(SomeClassTypeHere));

Затем в файле конфигурационного файла укажите иерархию журнала, как показано ниже.

<log4net>
  <!-- Other log4net configuration omitted for brevity -->
  <logger name="DataCollectionClass">
    <!-- Put your appender-ref entries here -->
  </logger>
</log4net>

Обратите внимание, что ссылка на имя журнала не содержит полного имени, используемого в коде. Он ссылается только на корень имени. Подумайте об этом так же, как вы думаете об пространствах имен.

Ответ 4

У меня есть статья, которая может помочь:

http://horth.com/blog/?p=165

Речь идет об изменении файла журнала во время выполнения. Что вы можете сделать, так это передать имя файла для каждого экземпляра в файл log4net. Таким образом, вы можете создать файл журнала для каждого экземпляра вашего класса. Таким образом, ваш конфигурационный файл прост, но вы можете создать новый файл журнала для каждого экземпляра класса.

Было упомянуто выше, что вы также можете регистрироваться в базе данных с индикаторами для каждого экземпляра. Если вы ничего не хотите покупать, используйте SQL Express, который позволяет создавать базы данных 10 ГБ. Вы даже можете писать непосредственно в файл MDF вместо установки SQL.