2016-08-12 7 views
1

У меня есть служба Windows, которая принимает веб-запросы для запуска долгого выполнения задачи async. Я хочу, чтобы каждая задача выводила журналы в разные каталоги (имя которых определяется идентификатором запроса и пользователем, вызвавшим задание). Внутри каждого каталога у меня есть несколько файлов журнала.Регистрация в нескольких папках

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

protected ILog CreateLoggerInstance(string loggerName, string logFolder) 
    { 
     logFolder += "/"; 
     // This is a hack to avoid creation of a folder called (null), because of limitation in log4net. 
     // More details: https://github.com/net-commons/common-logging/issues/81 
     log4net.GlobalContext.Properties["LogsDirectory"] = logFolder; 

     this.LogInstance = LogManager.GetLogger(loggerName); 
     this.LogInstance.GlobalVariablesContext.Set("LogsDirectory", logFolder); 
     LogManager.Reset(); 
     this.LogInstance = LogManager.GetLogger(loggerName); 

     this.LogFolder = logFolder; 
     return this.LogInstance; 
    } 

Есть ли способ установить журнал только для определенного регистратора? Или я могу избежать Reset() каким-то образом? Кроме того, этот конкретный фрагмент кода является единственным местом, где я имею в виду log4net. Поэтому я нормально перехожу к NLog, если могу создать несколько папок для каждого набора журналов.

Edit: Я нашел эту функцию в NLog - https://github.com/NLog/NLog/wiki/Configure-component-logging

Но это не выглядит как Common.Logging поддерживает его.

+0

Если вы хотите написать в нескольких местах в то же время вам понадобится один файл для каждого места. Единственной альтернативой является использование блокировки вокруг создания журнала, что будет пагубно сказываться на производительности. – stuartd

ответ

1

Решение довольно простое в NLog,

Просто используйте requestId и user в атрибуте fileName.

<targets> 
    <target name="file" xsi:type="File" 
     layout="${longdate} ${logger} ${message}" 
     fileName="${basedir}/${var:requestid}_${var:user}.log" /> 
</targets> 

<rules> 
    <logger name="*" minlevel="Debug" writeTo="file" /> 
</rules> 

Вы можете установить имя пользователя RequestID & в различных контекстах: глобальные переменные, GDC/MDC и т.д. См https://github.com/NLog/NLog/wiki/Gdc-layout-renderer

+0

Блестящий, это сработало. Я смог создать регистратор с MDC, а затем использовать Common.Logging везде. В одном файле мне пришлось использовать NLog.MappedDiagnosticsContext. Быстрый вопрос, MDC должен отлично работать с задачами TPL? Мои тесты пока показывают, что они работают, но будут ли проблемы с ThreadPool? – Narayana

+1

для TPL (Задачи) вам нужен MDLC: https://github.com/NLog/NLog/wiki/MDLC-Layout-Renderer – Julian