1

I have a web service with hundreds of concurrent users, I have a static Logging class to log errors that are thrown. I need to track UserID in the logger which originally wasn't been tracked.

This sound very easy because I could just pass the UserID into the Logger function call, but because this is a legacy system, I CANNOT change the call parameter. I can add some code when the program first start, or inside the logger itself, but to modify every call signature is out of the question.

How do I get userID in the logger without passing to it in every logger call?

Here is my current function and what my problem is:

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);
    }
}

Here is the trivia solution which I can't use:

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);
    }
}

One potential solution is to save some type of static variable in the Logger class, but remember, this class is static, and there could be hundreds of concurrent instances, how do I tell which instance is calling the logger?

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);
    }
}
Bill Software Engineer
  • 7,362
  • 23
  • 91
  • 174
  • If you don't want to pass it in each call, is there another method to retrieve the *user id*? In such a case, what's that? Otherwise, I cannot see how the logger could be able to get it without modifying the already existent codebase... – skypjack Jan 29 '16 at 23:34
  • Well, there are definitely function that can get the current userID given ANYTHING, but how is the static Logger suppose to know which user to get with just the Exception? – Bill Software Engineer Jan 29 '16 at 23:37
  • You can wrap the code as if it is a critical section, thus controlling who and how the logger is accessed, if the user id is tightly bound to the running thread. Not sure it works, I guess a lot of details are missed to be able to define a proper solution, I'm sorry... – skypjack Jan 29 '16 at 23:47

1 Answers1

2

The answer is that you can't.

But you can make the argument optional. That way code that you modify will have user_id and other code doesn't break.

The answers to How can you use optional parameters in C#? discuss both how to do this in version 4.0 or (through overloading) in earlier versions.

Community
  • 1
  • 1
btilly
  • 43,296
  • 3
  • 59
  • 88