如何在写入时以线程安全的方式在 NLog 中检索 MemoryTarget Logs 属性

问题描述 投票:0回答:1

我在代码中使用 MemoryTarget Logger,它将从另一个线程提供。

有时,我需要向某些 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);

我走在正确的道路上还是完全错了?

c# logging nlog .net-4.8
1个回答
0
投票

NLog v5.2.6 已发布,允许对 NLog 进行线程安全枚举 MemoryTarget

Logs
-属性:

另请参阅:https://github.com/NLog/NLog/pull/5409

© www.soinside.com 2019 - 2024. All rights reserved.