61

次の構成で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が1つしかないことを確認します)

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には、ファイル名のパターンのみが含まれています。これは、設定で指定されているとおりです。

現在のログファイルのランタイムパスを取得するにはどうすればよいですか?

4

4 に答える 4

75

これは私のためのトリックをしました:

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.");
于 2012-07-24T10:57:27.777 に答える
34

このメソッドは、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;
    }
于 2013-05-09T13:01:52.337 に答える
4

ターゲットは複数回ラップできるため(私の場合はフィルターがあります)、次のスニペットは、複数のレベルで機能し、ターゲット名についての仮定を行わない、より一般的なアンラップのアプローチです。

Target target = LogManager.Configuration.FindTargetByName(targetName);
while ((target != null) && (target is WrapperTargetBase))
{
    target = (target as WrapperTargetBase).WrappedTarget;
}
于 2016-12-19T23:53:53.637 に答える
2

私の答えが質問に正確に答えているわけではないことは知っていますが、最も難しいのは、適切なターゲットを見つけて適切にキャストすることです。そうすれば、任意のプロパティにアクセスできます。また、私の答えに合う質問が見つからなかったので、ここに投稿します...

このメソッドは、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
于 2015-01-23T00:34:33.700 に答える