Log4net LogicalThreadContext未按预期工作

Ric*_*ard 9 c# log4net asynchronous async-await

我一直在尝试使用Log4nets LogicalThreadContext为我的每个日志条目提供上下文.我的应用程序非常重视async/await,但是从阅读各种文章开始,LogicalThreadContext应该可以与.NET 4.5以后的异步代码一起正常工作.我正在使用.NET 4.5.1和log4net 2.0.3

我遇到了Stephen Cleary关于日志记录和.NET CallContext的一篇很棒的文章,结果我决定采用他的代码并使其适应log4net,试图看看我的代码中是否有错误可能有一直在引发这个问题.

首先,我完全按原样运行Stephens代码并得到预期的输出

Main 1: <SomeWork>
Main 1 A: <MoreWork>
Main 2: <SomeWork>
Main 2 A: <MoreWork>
Main 1 A: </MoreWork>
Main 1 B: <MoreWork>
Main 2 A: </MoreWork>
Main 2 B: <MoreWork>
Main 2 B: </MoreWork>
Main 2: </SomeWork>
Main 1 B: </MoreWork>
Main 1: </SomeWork>
Run Code Online (Sandbox Code Playgroud)

接下来,我修改了代码以使用log4net而不是Stephens自定义 MyStack

internal class Program
{
    private static readonly ILog Log = LogManager.GetLogger(typeof(Program));
    private const string StackName = "test";

    private static void Main(string[] args)
    {
        XmlConfigurator.Configure();

        using (LogicalThreadContext.Stacks[StackName].Push("Main"))
        {
            Task.WhenAll(SomeWork("1"), SomeWork("2")).Wait();
        }

        Console.ReadKey();
    }

    private static async Task SomeWork(string stackName)
    {
        using (LogicalThreadContext.Stacks[StackName].Push(stackName))
        {
            Log.Info("<SomeWork>");
            await MoreWork("A");
            await MoreWork("B");
            Log.Info("</SomeWork>");
        }
    }

    private static async Task MoreWork(string stackName)
    {
        using (LogicalThreadContext.Stacks[StackName].Push(stackName))
        {
            Log.Info("<MoreWork>");
            await Task.Delay(10);
            Log.Info("</MoreWork>");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望得到与以前类似的输出,但这次我得到了以下内容

Main 1: <SomeWork>
Main 1 A: <MoreWork>
Main 1 A 2: <SomeWork>
Main 1 A 2 A: <MoreWork>
Main 1 A 2 A: </MoreWork>
Main 1 B: <MoreWork>
Main 1 B: </MoreWork>
Main 1 B B: <MoreWork>
Main 1 B B: </MoreWork>
Main 1 B: </MoreWork>
Main 1: </SomeWork>
Main 1: </SomeWork>
Run Code Online (Sandbox Code Playgroud)

请注意,单独的逻辑线程上下文开始重叠.这向我表明log4net没有正确使用CallContext但是从我能找到的所有内容看起来他们已经解决了这个问题.

有没有其他人遇到这个或知道为什么会发生这种情况?

Ste*_*ary 10

不幸的是,看起来log4net 仍然无法与async逻辑堆栈一起使用.

log4net NuGet包2.0.3是log4net 1.2.13(截至今天的当前版本).报告了一个错误(LOG4NET-317)因为当时LogicalThreadContext使用CallContext而不是LogicalCallContext.

当前版本LogicalThreadContext确实使用LogicalThreadContext,但目前的版本ThreadContextStacks没有正确地使用一个不可变的堆栈.

有趣的是,Andrew Arnott在原始错误报告中正确地指出他们必须使用不可变堆栈.在2011年.

随意编写一个最小的repro并将其报告为log4net错误.关键方案是在使用组合的多个任务中使用堆栈Task.WhenAll.

  • 看起来这个问题已在1.2.14中修复:https://issues.apache.org/jira/browse/LOG4NET-455 (2认同)