NLog:在运行时从模板生成配置
NLog: Generate configurations at runtime from template
我正在尝试基于另一个目标在运行时生成目标和记录器。假设我有一个功能性 Foo
记录器:我想为 Foo.1
、Foo.2
等生成单独的规则,但我不知道最后一个记录器是什么我必须创建(因此,我不能以声明方式定义它们)。
到目前为止,我做了这样的事情:
public GetNewClonedLogger(int fooId)
{
var config = NLog.LogManager.Configuration;
var newFooName = $"Foo.{fooId}";
FileTarget baseTarget = NLog.LogManager.Configuration.FindTargetByName<FileTarget>("Foo");
// Copy the base target
var newTarget = new FileTarget(newFooName)
{
Layout = baseTarget.Layout,
CreateDirs = true,
FileName = baseTarget .FileName.ToString().Replace("${var:filename}", newFooName),
ArchiveAboveSize = baseTarget.ArchiveAboveSize,
BufferSize = baseTarget.BufferSize,
ArchiveFileName = baseTarget.ArchiveFileName,
MaxArchiveFiles = baseTarget.MaxArchiveFiles,
ArchiveDateFormat = baseTarget.ArchiveDateFormat,
ArchiveEvery = baseTarget.ArchiveEvery,
FileAttributes = baseTarget.FileAttributes,
KeepFileOpen = baseTarget.KeepFileOpen,
ArchiveNumbering = baseTarget.ArchiveNumbering,
};
// Add configs & flush
NLog.LogManager.Configuration.AddTarget(newTarget);
NLog.LogManager.Configuration.AddRuleForAllLevels(newTarget, newFooName);
// I tried every combinations of the following, without success
NLog.LogManager.ReconfigExistingLoggers();
NLog.LogManager.Configuration = config;
NLog.LogManager.Configuration.Reload();
NLog.LogManager.GetLogger(newFooName);
}
这个函数 returns 一个记录器,在每一点上似乎都可以:目标名称可以,文件名可以,NLog.LogManager.Configuration
有一个名称正确的新规则(Foo.1
, Foo.2
, ...), AllTargets
也是如此。但是当我使用返回的记录器进行记录时,没有创建任何文件,就像什么都没发生过一样....
我已经尝试了 this thread 中提出的解决方案,但没有成功....我错过了什么?
感谢您的帮助!
实际上,这是一个非常愚蠢的错误,因为这可能会像我预期的那样工作。问题是 baseTarget.FileName
是一个 Layout
对象,使用 .ToString()
的字符串化通过在输出中添加引号 ('C:\...'
) 进行了错误的转换。因此,NLog 抛出了错误,这些错误被 NLog 配置部分隐藏了,而且无论如何都很难理解。我通过检查 baseTarget.FileName
是否是 SimpleLayout
(我必须处理的唯一 class)来修复它,然后从该布局中检索 OriginalText
。然后,它就像一个魅力。
我正在尝试基于另一个目标在运行时生成目标和记录器。假设我有一个功能性 Foo
记录器:我想为 Foo.1
、Foo.2
等生成单独的规则,但我不知道最后一个记录器是什么我必须创建(因此,我不能以声明方式定义它们)。
到目前为止,我做了这样的事情:
public GetNewClonedLogger(int fooId)
{
var config = NLog.LogManager.Configuration;
var newFooName = $"Foo.{fooId}";
FileTarget baseTarget = NLog.LogManager.Configuration.FindTargetByName<FileTarget>("Foo");
// Copy the base target
var newTarget = new FileTarget(newFooName)
{
Layout = baseTarget.Layout,
CreateDirs = true,
FileName = baseTarget .FileName.ToString().Replace("${var:filename}", newFooName),
ArchiveAboveSize = baseTarget.ArchiveAboveSize,
BufferSize = baseTarget.BufferSize,
ArchiveFileName = baseTarget.ArchiveFileName,
MaxArchiveFiles = baseTarget.MaxArchiveFiles,
ArchiveDateFormat = baseTarget.ArchiveDateFormat,
ArchiveEvery = baseTarget.ArchiveEvery,
FileAttributes = baseTarget.FileAttributes,
KeepFileOpen = baseTarget.KeepFileOpen,
ArchiveNumbering = baseTarget.ArchiveNumbering,
};
// Add configs & flush
NLog.LogManager.Configuration.AddTarget(newTarget);
NLog.LogManager.Configuration.AddRuleForAllLevels(newTarget, newFooName);
// I tried every combinations of the following, without success
NLog.LogManager.ReconfigExistingLoggers();
NLog.LogManager.Configuration = config;
NLog.LogManager.Configuration.Reload();
NLog.LogManager.GetLogger(newFooName);
}
这个函数 returns 一个记录器,在每一点上似乎都可以:目标名称可以,文件名可以,NLog.LogManager.Configuration
有一个名称正确的新规则(Foo.1
, Foo.2
, ...), AllTargets
也是如此。但是当我使用返回的记录器进行记录时,没有创建任何文件,就像什么都没发生过一样....
我已经尝试了 this thread 中提出的解决方案,但没有成功....我错过了什么?
感谢您的帮助!
实际上,这是一个非常愚蠢的错误,因为这可能会像我预期的那样工作。问题是 baseTarget.FileName
是一个 Layout
对象,使用 .ToString()
的字符串化通过在输出中添加引号 ('C:\...'
) 进行了错误的转换。因此,NLog 抛出了错误,这些错误被 NLog 配置部分隐藏了,而且无论如何都很难理解。我通过检查 baseTarget.FileName
是否是 SimpleLayout
(我必须处理的唯一 class)来修复它,然后从该布局中检索 OriginalText
。然后,它就像一个魅力。