如何在运行时使用NLog获取当前目标文件的路径?

时间:2012-07-12 13:14:43

标签: c# 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的{​​{1}}属性(我检查一下,集合中只有一个FileTarget)

FileTarget

但是logFile.FileName只包含文件名的模式,具体如何在设置中指定。

如何获取当前日志文件的运行时路径?

4 个答案:

答案 0 :(得分:56)

这对我有用:

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.");

答案 1 :(得分:25)

即使您在NLog XML配置中设置了async="true"(即您的目标被AsyncTargetWrapper包装),此方法仍然有效:

    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;
    }

答案 2 :(得分:3)

目标可以被多次包装(在我的情况下我有一个过滤器),所以下面的代码片段是一种更通用的解包方法,适用于多个级别,并且不会对目标名称做出假设。

inventory_sales_history

答案 3 :(得分:1)

我知道我的答案并没有完全回答这个问题,但最困难的事情是找到合适的目标并正确投射,然后我们就可以访问任何属性了。我也没有找到一个适合我答案的问题,因此在这里张贴......

即使您在NLog XML配置中设置async="true"(即您的目标由AsyncTargetWrapper或任何TargetWrapper包装),此方法也会起作用:

使用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;
        }
    }

名为emailError的MailTarget的用法

var emailError = (MailTarget)FindTargetByName("emailError");
emailError.SmtpServer = "" //you can set or get