none
Trace Filtering RRS feed

  • Question

  • I've been wanting to find a better way to debug some web services and it looks like this is probably the best way but I need some help filtering.

    First off I have a web service that uses the Sync framework and can have multiple users connected at the same time. I have figured out how to have different logs created for each new rep that gets connected but their logs are all intertwined. I want to write out using the TextWriterTraceListener so that I can easily find somebody's log and not have to hunt through the event log.

    I want to have only userA's activity logged to a specific file and say userB's activity logged to his file. A new log file will be created each time they reconnect to the server and start syncing. I've seen some examples for the TraceSource but no real way to implement it in the way that I want, since they seem to really set them up in the config which I don't believe will work for me.

    Any help would be great and I can try to answer any additional info questions that are needed to find a solution.

    Thanks

    Matt

     

    Thursday, May 20, 2010 4:15 PM

All replies

  •  

    Hi,

    From my understanding, there is a server that allows multiple users logging on at same time, the server also trace different user's activities to a same log file, as a result, the log looks like:

        [10:09] userA log on.

        [10:10] userB log on.

        [10:11] userA send a request.

        [10:12] userB logout.

        [10:13] userA logout.

     and now, you want to create separate log files for each user when the user logged on, so that one log file only contain one user's activities, for example:

        -----logForUserA.txt-----

        [10:09] userA log on.

        [10:11] userA send a request.

        [10:13] userA logout.

     

        -----logForUserB.txt-----

        [10:10] userB log on.

        [10:12] userB logout.

    am I right?

     

    If so, why not implement a custom trace listener to trace different users' activities in different log file.


    Sincerely,
    Eric
    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Friday, May 21, 2010 7:10 AM
  • Or you can create a simple logger object:

    class KeyedLogger : IDisposable
    {
      string rootPath;
      string filenameFormat;
      Dictionary<string, StreamWriter> map;
    
      // rootPath specifies the folder to log to
      // filenameFormat provides a conversion from key to filename
      //  i.e. "LogFileFor{0}.log"
      public KeyedLogger(string rootPath, string filenameFormat)
      {
        this.rootPath = rootPath;
        this.filenameFormat = filenameFormat;
        map = new Dictionary<string, StreamWriter>();
      }
    
      ~KeyedLogger()
      {
        Dispose();
      }
    
      public void Dispose()
      {
        foreach (StreamWriter writer in map.Values)
          writer.Dispose();
        GC.SuppressFinalize(this);
      }
    
      // Closes logfile for a given key
      public void Close(string key)
      {
        StreamWriter writer;
        if (map.TryGetValue(key, out writer))
        {
          writer.Dispose();
          map.Remove(key);
        }
      }
    
      public void Write(string key, string text)
      {
        StreamWriter writer;
        if (!map.TryGetValue(key, out writer))
        {
          writer = new StreamWriter(Path.Combine(rootPath, String.Format(filenameFormat, key)));
          map[key] = writer;
        }
        writer.Write(text);
      }
    
      public void Write(string key, string format, params object[] args)
      {
        Write(key, String.Format(format, args));
      }
    
      public void WriteLine(string key, string text)
      {
        Write(key, text);
        Write(key, Environment.NewLine);
      }
    
      public void WriteLine(string key, string format, params object[] args)
      {
        Write(key, String.Format(format, args));
        Write(key, Environment.NewLine);
      }
    }
    
    Friday, May 21, 2010 2:44 PM
  •  

    Hi,

    I'm writing to check the issue status, please feel free to let us know if you have any concern.


    Sincerely,
    Eric
    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Monday, May 24, 2010 5:16 AM
  • I'm just able to get back to this now. I'll post any comments or mark it as answered when I get this working.
    Monday, May 24, 2010 12:38 PM
  • I have created a custom class that inherits TraceListener and a seperate one that inherits TraceFilter. Just to test and see if ShouldTrace works I set it to return false. After doing this though the tracelistener class is still writing out all events.

    I thought that if you set a filter, it should run ShouldTrace before every Write/WriteLine call.

    Either I am implementing this wrong or just not understanding the concept.

     

    Monday, May 24, 2010 3:46 PM
  •  

     

    Hi,

    We may override a overload method Write for custom trace listener, for example:

     

            public override void Write(string message, string category)

            {

                // For different category, use different log files.

                string filePath = GenerateFilePathFromCategory(category);

     

                // Write log to log file.

                File.AppendAllText(filePath, message);

            }

     

     

    Writetakes two parameters, the first one is the log message, for the second one, we may pass current user's name, in this method, we create different log file according to different category, and write log to separate log files.

     

    and use this method like this:

     

    string userName = GetCurrentUserFromSession();

    Trace.Write("some message", userName);


    Sincerely,
    Eric
    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Tuesday, May 25, 2010 3:18 AM
  • That type of solution won't work. They don't essentially have a login to the webservices themselves other then an initial verification. The trace itself doesn't know who is logged in other than the trace name itself. I am also using the function Trace.Listeners.Add so I am actually not calling the write function myself it is being automated. Looking at the logs there isn't anything in there that can verify who it is that is writing the entry.

    What I am looking for is a way to only write to a specific log file for each user so they don't all share the same events.

    *************************
    UserA - Logs in
    UserA - Does work
    UserA - Does work
    UserB - Logs in
    UserB - DoesWork
    UserA - Logs Off
    UserB - Takes a break
    UserB - Logs off
    ************************

    I want logging for both userA and userB but userA should write to file userADate.txt and userB should write to userBDate.txt. Their log file should only contain events that they themselves performed and not each others. I currently can only get it to write out to two seperate files but they share events.

    I have created a custom listener but the WriteLine method is the only one being called and I don't see a way to know which listener it came from. I'm adding to the collection of listeners using the function. Trace.Listeners.Add. This way I am not calling the WriteLine function the trace itself is.

     

     

    Tuesday, May 25, 2010 12:50 PM
  •  

    I'm sorry, but from each log entry, we can see the user name, how do you construct log messages? where is the user name come from?

     

    You also mentioned "I currently can only get it to write out to two seperate files but they share events.", does it means, for example, userAData.txt contains log entries of userB? something like:

     

    ********userAData.txt********

    UserA - Logs in

    UserA - Does work

    UserA - Does work

    UserB - Logs in

    UserB - DoesWork

    ************************

     

    In our code, we can only use Trace or Debug class to write log messages, and all listeners will be notified when we invoke Trace.Write (or Treace.WriteLine, etc). In custom trace listener, we cannot not know where the log message comes form, instead, we just log it, to one file or to many files.

     

    This article provides a detail description of .NET Tracing, hope it can help:)


    Sincerely,
    Eric
    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Wednesday, May 26, 2010 7:23 AM
  • I probably should of added this, but this is a small snippet of what the log provides

    INFO   , WebDev.WebServer, 4, 05/25/2010 13:52:19:852,    ----- Enumerating Deletes for Table MfgPub -----
    VERBOSE, WebDev.WebServer, 4, 05/25/2010 13:52:19:852, Using Command: dbo.MfgPubSyncDeletes
    VERBOSE, WebDev.WebServer, 4, 05/25/2010 13:52:19:852,    Parameter: @sync_initialized Value: 0
    VERBOSE, WebDev.WebServer, 4, 05/25/2010 13:52:19:852,    Parameter: @sync_last_received_anchor Value: <zero length value>
    VERBOSE, WebDev.WebServer, 4, 05/25/2010 13:52:19:852,    Parameter: @sync_new_received_anchor Len: 8 Value: 00-00-00-00-08-4D-C4-27
    VERBOSE, WebDev.WebServer, 4, 05/25/2010 13:52:19:852,    Parameter: @sync_client_id Value: 7dd8f42c-34bd-498a-9ab7-6084e05b5f75
    VERBOSE, WebDev.WebServer, 4, 05/25/2010 13:52:19:852,
    INFO   , WebDev.WebServer, 4, 05/25/2010 13:52:19:852,       Changes Enumerated: 0
    INFO   , WebDev.WebServer, 4, 05/25/2010 13:52:19:852,    --- End Enumerating Deletes for Table MfgPub ---

     

    The first section up till the end of the date/time is standard on everything. There really is no username provided.

    Wednesday, May 26, 2010 2:41 PM
  •  

    I see, we log each requests sent from clients, but the request itself doesn't contains any user-related information, we can only get user information when user connect to server. In other words, we have no hint about which user is writing a log entry.

     

    If so, I'm sorry, I cannot find a way to do this. At least, I think, we need identify current user who is writing the log message. 


    Sincerely,
    Eric
    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Thursday, May 27, 2010 2:28 AM
  • Im not sure i really understand your problem but do your web services run in anonymous? if not why cant you retreive current user specific information (username for exemple)

    if yes, maybe you could create a logfile for each different IP adress or host name (wich can be retreived in HTTPContext object)?

    Thursday, May 27, 2010 4:12 AM
  • That's what I thought. Short of writing my own trace from scratch which is not on the table it won't work.

    Oh and yes it's anonymous..

     

    Thanks for everything though, I learned quite a bit on this little project.

    Thursday, May 27, 2010 12:29 PM