C# log4net.LogicalThreadContext.Properties不能与OwinMiddleware一起正常工作

C# log4net.LogicalThreadContext.Properties不能与OwinMiddleware一起正常工作,c#,log4net,log4net-appender,C#,Log4net,Log4net Appender,我试图使用log4net.LogicalThreadContext在OWIN中间件中存储一些数据,以便稍后在ApicController中记录数据,但它似乎不起作用。存储在log4net.LogicalThreadContext中的数据似乎无法在ApicController中使用。以下是我的代码片段: 创建了API中间件,以便将一些日志数据注入LogicalThreadContext.Properties[“logdata”]: 我的问题是:日志中只写了“某物”。然而,CorellationId

我试图使用log4net.LogicalThreadContext在OWIN中间件中存储一些数据,以便稍后在ApicController中记录数据,但它似乎不起作用。存储在log4net.LogicalThreadContext中的数据似乎无法在ApicController中使用。以下是我的代码片段:

创建了API中间件,以便将一些日志数据注入LogicalThreadContext.Properties[“logdata”]:

我的问题是:日志中只写了“某物”。然而,CorellationId和Route没有被识别。通过代码调试,我发现“logEvent.Properties[“logdata”]as ConcurrentDictionary”在RollingFileAppenderEx中返回了可为null的值。所以我有一个理论:TestsController类似乎不在同一个线程中,或者不是来自ApiMiddleWare的子线程。因此,存储在LogicalThreadContext中的数据不会一直传播


如果有人能帮忙看看是否有办法做到这一点,或者我的代码中可能有一个bug。我将不胜感激。谢谢。

也许你必须调用
loggingEvent.GetLoggingEventData()

我有:

public abstract class AwsVerboseLogsAppender : AppenderSkeleton
{
    // ...
    protected override void Append(LoggingEvent loggingEvent)
    {
        // ...
    }
    // ...
}

// ...

var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log4net.config");
var fileinfo = new FileInfo(path);
XmlConfigurator.Configure(fileinfo);
var log = LogManager.GetLogger(GetType());

LogicalThreadContext.Properties["Test"] = "MyValue";

log.Debug("test");
loggingEvent.Properties
Append
中为空


但是,如果我调用了
loggingEvent.GetLoggingEventData()
,那么
的“Test”
MyValue
就会出现在
loggingEvent.Properties
中。因此,也许您必须调用该方法。

上次我检查源代码时,log4net的逻辑数据实现不完整。你试过使用AsyncLocal吗?是的,我试过AsyncLocal,它也没有。实际上,我使用AsyncLocal来确保问题不仅仅发生在LogicalThreadContext.Properties中。您运行的是4.5或更高版本,对吗?您使用的是最新版本的log4net吗?以前版本中的LogicalThreadContext存在问题。是的,我获得了最新的log4net。最后,我在WebApiConfig.cs中使用config.MessageHandlers.Add()而不是Owin,它可以正常工作。
public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.Use<ApiMiddleWare>();
        Log.Configure();
    }

}
public class RollingFileAppenderEx: RollingFileAppender
{
    protected static readonly JsonSerializerSettings JsonSettings = new JsonSerializerSettings
    {
        ContractResolver = new CamelCasePropertyNamesContractResolver(),
        NullValueHandling = NullValueHandling.Ignore,
        DateFormatHandling = DateFormatHandling.IsoDateFormat
    };
    protected override void Append(LoggingEvent loggingEvent)
    {
        if (FilterEvent(loggingEvent))
        {
            var logdata = loggingEvent.GetLoggingEventData();
            logdata.Message = GetLogData(loggingEvent);
            loggingEvent = new LoggingEvent(loggingEvent.GetType(), loggingEvent.Repository, logdata, loggingEvent.Fix);
            base.Append(loggingEvent);
        }

    }

    protected string GetLogData(LoggingEvent logEvent)
    {

        IDictionary<string, object> logData = new Dictionary<string, object>();
        var logD = logEvent.Properties["logdata"] as ConcurrentDictionary<string, object>;
        if logD != null)
        {
            foreach (var log in logD)
            {
                logData.Add(log.Key, log.Value);
            }
        }
        logData.Add("Message", logObject.Message);

        var logString = JsonConvert.SerializeObject(logData, JsonSettings);
        return logString;
    }

}
public class TestsController : ApiController
{
    private static readonly ILogger Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);  
    public string Get(int id)
    {
        Log.Info("Something");
        return id;
    }
}
public abstract class AwsVerboseLogsAppender : AppenderSkeleton
{
    // ...
    protected override void Append(LoggingEvent loggingEvent)
    {
        // ...
    }
    // ...
}

// ...

var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log4net.config");
var fileinfo = new FileInfo(path);
XmlConfigurator.Configure(fileinfo);
var log = LogManager.GetLogger(GetType());

LogicalThreadContext.Properties["Test"] = "MyValue";

log.Debug("test");