4

d: が存在する場合は d:\logs にログを書き込み、d: が存在しない場合は代わりに c:\logs にログを書き込むように NLog を構成することはできますか?

4

2 に答える 2

4

カスタム LayoutRenderer と XML 構成の組み合わせでそれを行うことができると思います。XML 構成では、LayoutRenderers を使用してファイル名を指定できます。例えば:

<target name="logfile" xsi:type="File" fileName="${basedir}/${shortdate}.log" />

${basedir}FileTarget オブジェクトは、および${shortdate}レイアウト レンダラーの値に基づいてファイルを作成します。

カスタム LayoutRenderer を簡単に作成し、「FindAvailableDrive」と呼んで、次のように構成できます。

<target name="logfile" xsi:type="File" fileName="${FindAvailableDrive}/logs/${shortdate}.log" />

FindAvailableDrive LayoutRender は、「C:」などのドライブ文字で始まり、有効なドライブが見つかるまで変化します。さらに一歩進めるために、FindAvailableDrive は、有効なドライブを検索する方法を定義するのに役立つ 1 つ以上のパラメーターを取ることができます。

<target name="logfile" xsi:type="File" fileName="${FindAvailableDrive:Drives=DC}/logs/${shortdate}.log" />

この場合、FindAvailableDrive はドライブ D をチェックしてからドライブ C をチェックします。

以下は、そのような LayoutRenderer を記述する方法の例 (未テスト) です (これは、NLog 1.0 に対して記述した既存の LayoutRender に基づいているため、NLog 2.0 では必要でない (または有効でない) ものがあることに注意してください)。

  [LayoutRenderer("FindAvailableDrive")]
  class FindAvailableDriveLayoutRenderer : LayoutRenderer
  {
    private string validDrive;

    [DefaultParameter]
    public string DriveCandidates { get; set; }

    protected override void Append(StringBuilder builder, LogEventInfo logEvent)
    {
      builder.Append(FindValidDrive());
    }

    protected override int GetEstimatedBufferSize(LogEventInfo logEvent)
    {
      return 2;
    }

    private string FindValidDrive()
    {
      if (!String.IsNullOrEmpty(validDrive)) return validDrive;

      if (String.IsNullOrEmpty(DriveCandidates))
      {
        if (Directory.Exists("C:"))
          validDrive = "C:";
        else
        if (Directory.Exists("D:"))
          validDrive = "D:";
        //And so on if you want to continue to check for valid drives.
        return validDrive;
      }

      validDrive = DriveCandidates.Select(c => string.Format("{0}:", c).Where(d => Directory.Exists(d)).FirstOrDefault();

      //What to do if no drives exists?

      return validDrive;
    }
  }

NLog でカスタム LayoutRenderer を記述して使用する方法の詳細については、別の質問に対する私の回答をここで見ることができます。

于 2012-11-16T15:53:25.527 に答える
0

はい、可能ですが、xml 構成ではできません: プログラムがロードされている場合は、次のようにします: vb.net コード:

    Dim mt As NLog.Targets.FileTarget= Nothing
    For Each Target In LogManager.Configuration.AllTargets
        If Target.Name Like "YourTargetNameIntheXML" Then
            mt = DirectCast(Target, NLog.Targets.FileTarget)
        End If
    Next

if isnothing(mt)=false then
        mt.FileName="YourPath"
Check here if the drive exists, if not, change the path to your liking.
End If

構成をリロードする必要がある場合があります: Logger.Factory.Configuration.Reload()

コードで新しいファイルターゲットを構築してこれをnlogに追加しようとするよりも、これはうまくいかないかもしれません。次に、Memorytarget の例を示します。

Dim ThisLog As New MemoryTarget

ThisLog.Name = "PPTXLOG"
ThisLog.Layout = "${threadid} | ${time} | ${level:uppercase=true} | ${logger} | ${message} | ${exception}"


Logger.Factory.Configuration.AddTarget("PPTXLOG", ThisLog)
'the Logrule is needed to "route" the logs to your new target

    Dim LogRule As New LoggingRule("*", LogLevel, ThisLog)

    Logger.Factory.Configuration.LoggingRules.Add(LogRule)
    Logger.Factory.Configuration.Reload()
于 2012-11-15T08:06:12.700 に答える