Использование NLog как я могу заставить мои модули регистрироваться в их собственном уникальном файле журнала

#c# #logging #nlog

#c# #ведение журнала #nlog

Вопрос:

Я пытаюсь изменить приложение так, чтобы при создании экземпляра модуля (класса, определенного в другой сборке) оно могло предоставлять необходимую информацию модулю, чтобы он мог создать свой собственный регистратор на основе конфигурации приложения-службы, загружающего его.

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

 <variable name="module" value="Service"/>

<targets>
   <target name="logFile" xsi:type="File" fileName="${basedir}Logs/${var:module}.txt"
            layout="${time} ${uppercase:${level}} ${var:module} ${logger} ${message}" />
</targets>
  

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

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

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

Ответ №1:

Вы пытались использовать имя регистратора?

 <targets>
   <target name="ModulesTarget" xsi:type="File" fileName="${basedir}Logs/${logger:shortname=true}.txt" />
</targets>
<rules>
   <logger name="Modules.*" target="ModulesTarget"/>
</rules>
  

Затем создайте модульный регистратор следующим образом:

 var moduleLogger = NLog.LogManager.GetLogger("Modules.MyModuleName");
  

Комментарии:

1. Я знал, что вы можете объявлять регистраторы на основе имени, но я не знал, что вы можете задать имя файла, чтобы указать короткое имя типа. Вероятно, я мог бы заставить это работать, но это ограничит диапазон того, что я хочу с этим делать. Я действительно надеялся, что смогу просто передать, скажем, экземпляр ILogFactory, который будет передаваться по модулю, чтобы каждый класс в модуле мог создать свой собственный именованный регистратор, чтобы все они регистрировались в одном файле, но можно было отличить исходный класс или тип. Спасибо за ваше предложение, и я обновлю сообщение, если пойду по этому пути.

2. Мне не удалось использовать target=»ModulesTarget». Проблема решена, когда я использовал writeTo=»ModulesTarget». Кроме этого, хорошее решение. Использую его сейчас.

Ответ №2:

Вы также можете предоставить общий интерфейс для всех модулей. Этот интерфейс также включает в себя возможность получения пользовательского объекта Logger, который оборачивает регистратор NLog.

Затем пользовательский объект-регистратор вводит имя модуля LogEventInfo.Properties . Возможно, извлеченный из:

 System.Reflection.Assembly.GetCallingAssembly().Name
  

Затем вы можете использовать ${event-properties:item=ModuleName} в имени файла.

Смотрите также https://github.com/NLog/NLog/wiki/EventProperties-Layout-Renderer

Ответ №3:

Вы также можете создать изолированный LogFactory для каждого модуля:

https://github.com/NLog/NLog/wiki/Configure-component-logging

Комментарии:

1. Спасибо за ваш вклад, и я думаю, что я пропустил эту страницу в вики. Я еще не пробовал это в своем основном проекте, но это сработало в созданном мной тестовом проекте. Проблема, с которой я столкнулся изначально, заключается в том, что я, похоже, не могу повторно использовать XmlLoggingConfiguration поскольку изменения в нем распространяются по всем созданным с его помощью LogFactories, даже когда я пытаюсь клонировать его, скопировав все его цели и правила в новый экземпляр, поэтому решение, которое я подозреваю в этом случае, состоит в том, чтобыпродолжайте перезагружать его из файла, который мне кажется «грязным», но все же может быть лучшим решением.