我正在使用NLog和Common Logging 请找到我的完整代码片段
我也提到了当前的输出和预期的输出 我想要每个线程使用单独的内存记录器,它们不应该相互交互。
配置
<targets>
<target name="LogFile"
xsi:type="File"
fileName="${mdc:item=LogsDirectory}\logfile.txt"
layout="${message}"
maxArchiveFiles="10"
archiveAboveSize="20000000"
archiveNumbering="Sequence"
archiveFileName="${mdc:item=LogsDirectory}\logfile.{#}.txt"/>
<target name="Memory" xsi:type="Memory" layout="${message}"/>
</targets>`
<rules>
<!-- add your logging rules here -->
<logger name="LogFile" minlevel="Debug" writeTo="LogFile" />
<logger name="LogFile" minlevel="Info" writeTo="Memory" />
</rules>
使用config的代码段:
static void Main(string[] args)
{
List<Task> tasks = new List<Task>();
for (int ctr = 1; ctr <= 3; ctr++)
{
tasks.Add(Task.Factory.StartNew(FirstWorldTask));
}
Task.WaitAll(tasks.ToArray());
}
private static void FirstWorldTask()
{
var folderName = rnd.Next();
var scenarioId = rnd.Next().ToString();
Console.WriteLine(scenarioId);
NLog.MappedDiagnosticsContext.Set("LogsDirectory", folderName);
ILog logger = LogManager.GetLogger("LogFile");
var memoryTarget = (MemoryTarget)NLog.LogManager.Configuration.FindTargetByName("Memory");
memoryTarget.Logs.Clear();
for (int i = 0; i < 5; i++)
{
logger.Info(i + " " + scenarioId);
Thread.Sleep(10);
}
for (int i = 0; i < memoryTarget.Logs.Count; i++)
{
Console.WriteLine(memoryTarget.Logs[i] + " " + scenarioId);
}
memoryTarget.Logs.Clear();
}
随机数
当前输出
预期产出
使用编程方式的代码段
private static void FirstWorldTask()
{
var folderName = rnd.Next();
var scenarioId = rnd.Next().ToString();
Console.WriteLine(scenarioId);
NLog.MappedDiagnosticsContext.Set("LogsDirectory", folderName);
ILog logger = LogManager.GetLogger("LogFile");
var memoryTarget = new MemoryTarget();
memoryTarget.Name = "Memory_" + scenarioId;
memoryTarget.Layout = "${message}";
var config = NLog.LogManager.Configuration;
config.AddTarget(memoryTarget.Name, memoryTarget);
var rule = new LoggingRule("LogFile", LogLevel.Info, memoryTarget);
config.LoggingRules.Add(rule);
NLog.LogManager.Configuration = config;
for (int i = 0; i < 5; i++)
{
logger.Info(i + " " + scenarioId);
Thread.Sleep(10);
}
while (memoryTarget.Logs.Count > 0)
{
int i = 0;
while (memoryTarget.Logs.Count > 0 && i < 5)
{
Console.WriteLine(memoryTarget.Logs.First() + " " + scenarioId);
memoryTarget.Logs.RemoveAt(0);
i++;
}
}
}
随机数
程序输出
日志写在所有memoryTargets上,而不只是一个
答案 0 :(得分:1)
Github讨论了这个问题。
目标应具有固定名称(因此不应使用布局渲染器),因此应以编程方式创建目标和规则。这样做的代码示例:
private static Random rnd = new Random();
private static object sync = new object();
static void Main(string[] args)
{
List<Task> tasks = new List<Task>();
// Execute the task 10 times.
for (int ctr = 1; ctr <= 5; ctr++)
{
tasks.Add(Task.Factory.StartNew(FirstWorldTask));
Thread.Sleep(10);
}
Task.WaitAll(tasks.ToArray());
}
private static void FirstWorldTask()
{
string loggerName = "Logger";
string randomName = rnd.Next().ToString(); //or GUID
string targetFileName = "File";
string targetMemoryName = "Memory";
lock (sync)
{
//or using threadid here?
loggerName += randomName;
targetFileName += randomName;
targetMemoryName += randomName;
Console.WriteLine(loggerName);
}
var MB20 = 20 * 1024 * 1024;
var fileTarget = new FileTarget(targetFileName)
{
ArchiveAboveSize = MB20,
Layout = "${message}", //probably you need more here
FileName = "./" + randomName + "/logfile.txt",
};
LogManager.Configuration.AddTarget(fileTarget);
LogManager.Configuration.AddRule(LogLevel.Info, LogLevel.Fatal, fileTarget, loggerName); //filter on loggerName;
var memTarget = new MemoryTarget(targetMemoryName)
{
Layout = "${message}", //probably you need more here
};
LogManager.Configuration.AddTarget(memTarget);
LogManager.Configuration.AddRule(LogLevel.Info, LogLevel.Fatal, memTarget, loggerName); //filter on loggerName;
var m_log = LogManager.GetLogger(loggerName);
for (int i = 0; i < 5; i++)
{
m_log.Info(i + " " + randomName);
Thread.Sleep(10);
}
StringBuilder stringBuilder = new StringBuilder();
foreach (var loggingEvent in memTarget.Logs)
{
stringBuilder.AppendLine(loggingEvent);
}
memTarget.Logs.Clear();
Console.WriteLine(stringBuilder.ToString());
}
答案 1 :(得分:0)
我对Nlog并不是很熟悉,但更重要的是Log4net。这些工具不是针对特定于线程的。如果您关心的是记录哪个线程正在做什么,那么可能有一个配置供您在日志的每一行中包含线程ID。这不一定像每个线程都有一个单独的日志文件一样干净,但它总比没有好。检查文档。祝你好运。