在 nlog 上添加临时附加内存记录器
Add temporary additonal Memory Logger on nlog
我的 nlog 配置在 C# 程序上运行良好。
nlog 配置是通过独立文件完成的 nlog.config
然而,在代码的特定部分,我想创建一个额外的内存记录器目标,以便将日志的这个特定部分保存在缓冲区中(稍后我会将这个缓冲区附加到数据库中的特定对象)。
为此,我尝试以编程方式添加记录器及其配置。
我检查是否添加了记录器并添加了规则,但是新创建的记录器什么也没有。
我想我想念一些要告诉 nlog 实际考虑新记录器的东西。
一旦执行了目标函数,我想停止记录这段代码,仍然使用其他记录器,并在下一个项目上做同样的事情。
我用这行代码添加内存记录器:
MemoryTarget memoryLogger = new MemoryTarget("memoryTarget");
memoryLogger.Layout = "${message}";
LogManager.Configuration.AddTarget(memoryLogger);
LogManager.Configuration.AddRule(LogLevel.Trace, LogLevel.Fatal, memoryLogger);
下面是我添加新记录器之前的 nlog 配置:
添加新记录器后配置如下:
- LogManager.Configuration.LoggingRules 有一个新元素
- LogManager.Configuration.AllTargets 有一个新元素
但是在目标的详细信息中我看到:
- IsInitialized 为 false
- 将配置记录为空(而我将规则添加到 LogManager.Configuration
- 本应包含所有记录行的 'Logs' 属性 为空
我不想重新初始化所有 nlog,因为它会重置我的日志文件,我希望在每次进程启动时都有一个新的日志文件。
谢谢@Rolf Kristensen,
的确如此,
LogManager.ReconfigExistingLoggers();
允许初始化内存记录器而不重置我在文件上的其他记录器。
通过这样做,甚至不会触发 LogManager 的 ConfigurationChanged/ConfigurationReloaded 静态事件,而且效果很好!太棒了!
临时激活和停用内存中日志的最终代码:
MemoryTarget memoryTarget = new MemoryTarget("memoryTarget");
memoryTarget.Layout = "${message}";
LogManager.Configuration.AddTarget(memoryTarget);
var memoryRule = new LoggingRule("memoryRule");
memoryRule.EnableLoggingForLevels(LogLevel.Trace, LogLevel.Fatal);
memoryRule.Targets.Add(memoryTarget);
memoryRule.LoggerNamePattern = "*";
LogManager.Configuration.LoggingRules.Add(memoryRule);
LogManager.ReconfigExistingLoggers();
_log.Debug("this is dumped in memory");
foreach (string s in memoryTarget.Logs)
{
Console.Write("---------mem dumped: {0}", s);
}
LogManager.Configuration.RemoveTarget(memoryTarget.Name);
bool removed = LogManager.Configuration.LoggingRules.Remove(memoryRule);
LogManager.ReconfigExistingLoggers();
_log.Debug("no more in memory");
如果你阅读这篇文章 post,你可能有兴趣获取这段代码:
public class MemoryLogger
{
static Logger _log = LogManager.GetCurrentClassLogger();
MemoryTarget _memoryTarget;
LoggingRule _memoryRule;
public void Start()
{
_memoryTarget = new MemoryTarget("memoryTarget");
_memoryTarget.Layout = "${message}";
LogManager.Configuration.AddTarget(_memoryTarget);
_memoryRule = new LoggingRule("memoryRule");
_memoryRule.EnableLoggingForLevels(LogLevel.Trace, LogLevel.Fatal);
_memoryRule.Targets.Add(_memoryTarget);
_memoryRule.LoggerNamePattern = "*";
LogManager.Configuration.LoggingRules.Add(_memoryRule);
LogManager.ReconfigExistingLoggers();
}
public StringBuilder Stop()
{
LogManager.Configuration.RemoveTarget(_memoryTarget.Name);
bool removed = LogManager.Configuration.LoggingRules.Remove(_memoryRule);
if (!removed)
_log.Error("cannot remove rule "+_memoryRule.RuleName);
LogManager.ReconfigExistingLoggers();
var ret = new StringBuilder();
foreach (string s in _memoryTarget.Logs)
{
ret.AppendLine(s);
}
return ret;
}
}
我的 nlog 配置在 C# 程序上运行良好。 nlog 配置是通过独立文件完成的 nlog.config 然而,在代码的特定部分,我想创建一个额外的内存记录器目标,以便将日志的这个特定部分保存在缓冲区中(稍后我会将这个缓冲区附加到数据库中的特定对象)。
为此,我尝试以编程方式添加记录器及其配置。 我检查是否添加了记录器并添加了规则,但是新创建的记录器什么也没有。 我想我想念一些要告诉 nlog 实际考虑新记录器的东西。 一旦执行了目标函数,我想停止记录这段代码,仍然使用其他记录器,并在下一个项目上做同样的事情。
我用这行代码添加内存记录器:
MemoryTarget memoryLogger = new MemoryTarget("memoryTarget");
memoryLogger.Layout = "${message}";
LogManager.Configuration.AddTarget(memoryLogger);
LogManager.Configuration.AddRule(LogLevel.Trace, LogLevel.Fatal, memoryLogger);
下面是我添加新记录器之前的 nlog 配置:
添加新记录器后配置如下:
- LogManager.Configuration.LoggingRules 有一个新元素
- LogManager.Configuration.AllTargets 有一个新元素 但是在目标的详细信息中我看到:
- IsInitialized 为 false
- 将配置记录为空(而我将规则添加到 LogManager.Configuration
- 本应包含所有记录行的 'Logs' 属性 为空
我不想重新初始化所有 nlog,因为它会重置我的日志文件,我希望在每次进程启动时都有一个新的日志文件。
谢谢@Rolf Kristensen,
的确如此,
LogManager.ReconfigExistingLoggers();
允许初始化内存记录器而不重置我在文件上的其他记录器。 通过这样做,甚至不会触发 LogManager 的 ConfigurationChanged/ConfigurationReloaded 静态事件,而且效果很好!太棒了!
临时激活和停用内存中日志的最终代码:
MemoryTarget memoryTarget = new MemoryTarget("memoryTarget");
memoryTarget.Layout = "${message}";
LogManager.Configuration.AddTarget(memoryTarget);
var memoryRule = new LoggingRule("memoryRule");
memoryRule.EnableLoggingForLevels(LogLevel.Trace, LogLevel.Fatal);
memoryRule.Targets.Add(memoryTarget);
memoryRule.LoggerNamePattern = "*";
LogManager.Configuration.LoggingRules.Add(memoryRule);
LogManager.ReconfigExistingLoggers();
_log.Debug("this is dumped in memory");
foreach (string s in memoryTarget.Logs)
{
Console.Write("---------mem dumped: {0}", s);
}
LogManager.Configuration.RemoveTarget(memoryTarget.Name);
bool removed = LogManager.Configuration.LoggingRules.Remove(memoryRule);
LogManager.ReconfigExistingLoggers();
_log.Debug("no more in memory");
如果你阅读这篇文章 post,你可能有兴趣获取这段代码:
public class MemoryLogger
{
static Logger _log = LogManager.GetCurrentClassLogger();
MemoryTarget _memoryTarget;
LoggingRule _memoryRule;
public void Start()
{
_memoryTarget = new MemoryTarget("memoryTarget");
_memoryTarget.Layout = "${message}";
LogManager.Configuration.AddTarget(_memoryTarget);
_memoryRule = new LoggingRule("memoryRule");
_memoryRule.EnableLoggingForLevels(LogLevel.Trace, LogLevel.Fatal);
_memoryRule.Targets.Add(_memoryTarget);
_memoryRule.LoggerNamePattern = "*";
LogManager.Configuration.LoggingRules.Add(_memoryRule);
LogManager.ReconfigExistingLoggers();
}
public StringBuilder Stop()
{
LogManager.Configuration.RemoveTarget(_memoryTarget.Name);
bool removed = LogManager.Configuration.LoggingRules.Remove(_memoryRule);
if (!removed)
_log.Error("cannot remove rule "+_memoryRule.RuleName);
LogManager.ReconfigExistingLoggers();
var ret = new StringBuilder();
foreach (string s in _memoryTarget.Logs)
{
ret.AppendLine(s);
}
return ret;
}
}