#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, даже когда я пытаюсь клонировать его, скопировав все его цели и правила в новый экземпляр, поэтому решение, которое я подозреваю в этом случае, состоит в том, чтобыпродолжайте перезагружать его из файла, который мне кажется «грязным», но все же может быть лучшим решением.