d: が存在する場合は d:\logs にログを書き込み、d: が存在しない場合は代わりに c:\logs にログを書き込むように NLog を構成することはできますか?
2 に答える
カスタム 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 を記述して使用する方法の詳細については、別の質問に対する私の回答をここで見ることができます。
はい、可能ですが、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()