如果 d: 存在,是否可以将 NLog 配置为将日志写入 d:\logs,如果 d: 不存在,则改为登录到 c:\logs?
2 回答
我认为您可以结合使用自定义 LayoutRenderer 和 XML 配置来做到这一点。在 XML 配置中,您可以使用 LayoutRenderers 来指定文件名。例如:
<target name="logfile" xsi:type="File" fileName="${basedir}/${shortdate}.log" />
FileTarget 对象将根据${basedir}
和${shortdate}
布局渲染器的值创建一个文件。
您可以轻松编写自定义 LayoutRenderer,也许将其称为“FindAvailableDrive”,并像这样配置它:
<target name="logfile" xsi:type="File" fileName="${FindAvailableDrive}/logs/${shortdate}.log" />
FindAvailableDrive LayoutRender 可以以驱动器号开头,例如“C:”,然后更改直到找到有效的驱动器。为了更进一步,FindAvailableDrive 可以采用一个或多个参数来帮助定义如何搜索有效驱动器:
<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()