Как получить путь к текущему целевому файлу с помощью NLog во время выполнения?
Я использую NLog со следующей конфигурацией:
<targets>
<target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
layout="${longdate} ${uppercase:${level}} ${message}" />
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="f" />
</rules>
Я попытался получить FileName
свойство FileTarget
(я проверяю, что там только один набор FileTarget)
NLog.LogManager.GetCurrentClassLogger().Info("test");
var logFile = (from t in NLog.LogManager.Configuration.AllTargets
where t is NLog.Targets.FileTarget
select (NLog.Targets.FileTarget)t).FirstOrDefault();
Но logFile.FileName содержит только шаблон имени файла, точно как он указан в настройках.
Как я могу получить во время выполнения текущего файла журнала?
Ответы
Ответ 1
Это сделало трюк для меня:
var fileTarget = (FileTarget) LogManager.Configuration.FindTargetByName("file");
// Need to set timestamp here if filename uses date.
// For example - filename="${basedir}/logs/${shortdate}/trace.log"
var logEventInfo = new LogEventInfo {TimeStamp = DateTime.Now};
string fileName = fileTarget.FileName.Render(logEventInfo);
if (!File.Exists(fileName))
throw new Exception("Log file does not exist.");
Ответ 2
Этот метод будет работать, даже если вы установили async="true"
(т.е. ваша цель обернута AsyncTargetWrapper
) в вашей конфигурации XML NLog:
private string GetLogFileName(string targetName)
{
string fileName = null;
if (LogManager.Configuration != null && LogManager.Configuration.ConfiguredNamedTargets.Count != 0)
{
Target target = LogManager.Configuration.FindTargetByName(targetName);
if (target == null)
{
throw new Exception("Could not find target named: " + targetName);
}
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());
}
var logEventInfo = new LogEventInfo { TimeStamp = DateTime.Now };
fileName = fileTarget.FileName.Render(logEventInfo);
}
else
{
throw new Exception("LogManager contains no Configuration or there are no named targets");
}
if (!File.Exists(fileName))
{
throw new Exception("File " + fileName + " does not exist");
}
return fileName;
}
Ответ 3
Я знаю, что мой ответ не совсем отвечает на вопрос, но самое сложное - найти правильную цель и правильно ее перевести, тогда мы сможем получить доступ к любым свойствам. Я также не нашел вопроса, который соответствовал бы моему ответу, таким образом, размещая здесь...
Этот метод будет работать, даже если вы установили async="true"
(т.е. ваша цель обернута AsyncTargetWrapper
или любым TargetWrapper) в вашей конфигурации XML NLog:
Использование версии NLog: 3.1.0.0
Версия выполнения: v4.0.30319
private Target FindTargetByName(string targetName)
{
if (LogManager.Configuration == null)
return null;
Target t = LogManager.Configuration.FindTargetByName(targetName);
if (t is NLog.Targets.Wrappers.WrapperTargetBase)
{
var list = LogManager.Configuration.AllTargets.ToList();
t = list.Find(x => x.Name == targetName + "_wrapped");
return t;
}
else
{
return t;
}
}
Использование для MailTarget с именем emailError
var emailError = (MailTarget)FindTargetByName("emailError");
emailError.SmtpServer = "" //you can set or get
Ответ 4
Цели могут быть завернуты несколько раз (в моем случае у меня был фильтр), поэтому следующий фрагмент - это более общий подход к развертыванию, который работает для нескольких уровней, и не делает предположений о именах целей.
Target target = LogManager.Configuration.FindTargetByName(targetName);
while ((target != null) && (target is WrapperTargetBase))
{
target = (target as WrapperTargetBase).WrappedTarget;
}