在异常日志记录中跟踪用户 ID

Tracking UserID in Exception Logging

我有一个有数百个并发用户的 Web 服务,我有一个静态日志记录 class 来记录抛出的错误。我需要在最初未被跟踪的记录器中跟踪 UserID。

这听起来很容易,因为我可以将 UserID 传递到 Logger 函数调用中,但因为这是一个遗留系统,我 不能 更改调用参数。我可以在程序第一次启动时或在记录器本身内部添加一些代码,但是修改每个调用签名是不可能的。

如何在记录器中获取用户 ID 而无需在每次记录器调用时传递给它?

这是我当前的功能,我的问题是什么:

public static class Log
{
    public static void Error(object message, Exception ex)
    {
        log.Error(message, ex);

        IDictionary customData = new Dictionary<string, string>() {{"message", message.ToString()}};
        customData.Add("UserID",???????);
        DoLogging(ex, customData);
    }
}

这是我无法使用的琐事解决方案:

public static class Log
{
    public static void Error(object message, Exception ex, int userID)
    {
        log.Error(message, ex);

        IDictionary customData = new Dictionary<string, string>() {{"message", message.ToString()}};
        customData.Add("UserID", userID.ToString());
        DoLogging(ex, customData);
    }
}

一个可能的解决方案是在 Logger class 中保存某种类型的静态变量,但请记住,这个 class 是静态的,并且可能有数百个并发实例,我怎么知道哪个实例正在调用记录器?

public static class Log
{
    private static concurrent DataStrucutre userIDs;
    public static void Error(object message, Exception ex)
    {
        log.Error(message, ex);

        IDictionary customData = new Dictionary<string, string>() {{"message", message.ToString()}};
        customData.Add("UserID",userIDs[????]);
        DoLogging(ex, customData);
    }
}

答案是你不能。

但是可以使参数可选。这样您修改的代码将具有 user_id 而其他代码不会中断。

How can you use optional parameters in C#? 的答案讨论了如何在 4.0 版或早期版本中(通过重载)执行此操作。