2013-12-24 1 views
15

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

Вокруг Интернета я нашел, как создать цель, программируя меня. Я бы просто обновил имя файла, программируя. Я попробовал код ниже. Ошибка я получаю это «LayoutRender не может быть найден 'logDirectory'

Любая идея

Спасибо,

var target = (FileTarget)LogManager.Configuration.FindTargetByName("logfile"); 
target.FileName = "${logDirectory}/file2.txt"; 

LoggingConfiguration config = new LoggingConfiguration(); 
var asyncFileTarget = new AsyncTargetWrapper(target); 
config.AddTarget("logfile", asyncFileTarget); 

LogManager.Configuration = config; 

конфигурационный файл является:.?

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <variable name="logDirectory" value="C:/MyLogs"/> 
    <targets> 
     <target name="logfile" xsi:type="File" layout="${date:format=dd/MM/yyyy HH\:mm\:ss.fff}|${level}|${stacktrace}|${message}" fileName="${logDirectory}/file.txt" /> 
    </targets> 

    <rules> 
     <logger name="*" minlevel="Info" writeTo="logfile" /> 
    </rules>  
    </nlog> 
+0

Вы когда-нибудь находили решение? Если нет, я могу предложить некоторые ответы. – KOTIX

+0

Вот очень четкий ответ: [Установка файла журнала вручную] (http://stackoverflow.com/questions/3516242/add-remove-logfiles-during-runtime-in-nlog) – aozan88

+0

Вот очень четкий ответ: [ Установка целевых заданий вручную вручную (http://stackoverflow.com/questions/3516242/add-remove-logfiles-during-runtime-in-nlog) – aozan88

ответ

15

Попробуйте ReconfigExistingLoggers метод:

var target = (FileTarget)LogManager.Configuration.FindTargetByName("logfile"); 
target.FileName = "${logDirectory}/file2.txt"; 
LogManager.ReconfigExistingLoggers(); 

Как написано в документах:

Проводятся через все регистраторы, ранее возвращенные GetLogger. и пересчитывает список целей и фильтров. Полезно после изменения конфигурации для обеспечения правильной настройки всех регистраторов .

EDIT:

Попробуйте использовать пользовательский макет рендерер: NLog config file to get configuration setting values from a web.config

+0

Я пробовал ... ту же ошибку. –

+0

Как можно обходным путем попробуйте добавить свой собственный LayoutRenderer: http://stackoverflow.com/questions/7107499/nlog-config-file-to-get-configuration-setting-values-from-a-web-config – Tony

+0

Важно отметить, что если вы пытаетесь заменить часть имени файла, 'target.FileName.ToString()' может быть окружен одинарными кавычками, поэтому вы не можете повторно применить его непосредственно, например,'Path.GetDirectoryName (target.FileName.ToString(). Trim ('\' '))' – drzaus

1

Причина, почему вы получите ошибку в том, что NLog ничего не знает о "logDirectory" обозначением. Вы можете реализовать его самостоятельно (см. Инструкции here) или использовать предопределенные из here.

Затем вы можете использовать инструкции от here для изменения целей NLog во время выполнения.

+0

Или прочитайте (если возможно) значение logDirectory в NLog.config. Найдено: http://stackoverflow.com/questions/9635616/nlog-configuration-api-using-layouts-stored-in-variables –

3

Tony's Решение не работает, если вы используете NLog Async (<targets async="true">). Мне пришлось использовать цель-оболочку, чтобы получить файл FileTarget, иначе я получаю много ошибок. Я использую NLog 2.1.

if (LogManager.Configuration != null && LogManager.Configuration.ConfiguredNamedTargets.Count != 0) 
{ 
    Target target = LogManager.Configuration.FindTargetByName("yourFileName"); 
    if (target == null) 
    { 
     throw new Exception("Could not find target named: " + "file"); 
    } 

    FileTarget fileTarget = null; 
    WrapperTargetBase wrapperTarget = target as WrapperTargetBase; 

    // Unwrap the target if necessary. 
    if (wrapperTarget == null) 
    { 
     fileTarget = target as FileTarget; 
    } 
    else 
    { 
     fileTarget = wrapperTarget.WrappedTarget as FileTarget; 
    } 

    if (fileTarget == null) 
    { 
     throw new Exception("Could not get a FileTarget from " + target.GetType()); 
    } 

    fileTarget.FileName = "SetFileNameHere"; 
    LogManager.ReconfigExistingLoggers(); 
} 

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

var nlogConfigFile = "NLog.config"; 
var xdoc = XDocument.Load(nlogConfigFile); 
var ns = xdoc.Root.GetDefaultNamespace(); 
var fTarget = xdoc.Descendants(ns + "target") 
     .FirstOrDefault(t => (string)t.Attribute("name") == "yourFileName"); 
fTarget.SetAttributeValue("fileName", "SetFileNameHere"); 
xdoc.Save(nlogConfigFile);