提问人:Jean-Baptiste Zeller 提问时间:11/15/2023 最后编辑:Jean-Baptiste Zeller 更新时间:11/19/2023 访问量:58
如何在写入 MemoryTarget Logs 时在 NLog 中以线程安全的方式检索该属性
How to retrieve a MemoryTarget Logs property in a thread-safe manner in NLog while it is being written to
问:
我在我的代码中使用了 MemoryTarget 记录器,它将从另一个线程馈送。
有时,我需要向某些 webapi 调用提供日志,因此我需要检索 Logs 属性的内容。
问题是,Logs 属性是由 List 支持的 IList。因此,在写入日志时,通过 NLog 的帮助保持线程安全。在写入日志时,我无法访问日志的内容,并且我无法控制人们何时何地写入日志,并且似乎没有线程安全选项来检索数据。
我正在使用 .Net 4.8 框架。
当前简化代码
public const string filter = "theFilterHere";
public string TargetName { get; set; }
public MemoryTarget Logger { get; private set; }
public void InitLog() {
Logger = new MemoryTarget();
var rule = new LoggingRule(filter, LogLevel.Debug, Logger);
LogManager.Configuration.AddTarget(TargetName, Logger);
LogManager.Configuration.LoggingRules.Add(rule);
LogManager.ReconfigExistingLoggers();
}
public List<string> Logs {
// Crash happens here. I need the list in reverse order because reasons, but looking at it I know I would have the same problem if I did a ToList first.
return Logger.Logs.Reverse().ToList();
}
我知道使用日志的 SyncRoot 无济于事,因为我没有锁定对日志的写入访问权限。我今天唯一的想法是将日志(IList)转换为列表,然后执行类似于以下内容的代码:
List<string> currentLogs = Logger.Logs as List<string>;
if (currentLogs is null) {
// NLog changed the internal structure of MemoryTarget.
return Logger.Logs.Reverse().ToList();
}
int count = currentLogs.Count;
string[] logs = new string[count];
// Assumption : the list doesn't shrink, the log will only grow and never empty.
// this is only available on List<T>, and internally seems to do an Array copy of the _items array.
currentLogs.CopyTo(0, logs, 0, count);
我是走在正确的轨道上,还是无可救药地错了?
答:
1赞
Rolf Kristensen
11/19/2023
#1
NLog v5.2.6 已发布,允许对 NLog MemoryTarget 属性进行线程安全枚举:Logs
Смотритетакже: https://github.com/NLog/NLog/pull/5409
评论