Capturing User Identity with Loupe

Loupe records the current user information on each log message, making it easy to separate out just one user’s activity in a session from everything else going on

Loupe Log User Info

You get this all for free most of the time - ASP.NET authentication providers will automatically set and clear this on each request, for example - but what do you do if you’ve implemented your own system?

Recording User from Your Security System

Take the case of a Loupe customer that has a Point of Sale system using WinForms:  User identity is changing all of the time as various people walk up to the system to complete transactions.  When reviewing diagnostic information they want to be sure they know what user was using the system when a problem happened, and that identity needs to be carried down to asynchronous tasks that were done on that user’s behalf.

Fortunately, .NET has a built-in way of handling this - Thread.CurrentPrincipal.  Whenever you want to change who the current user is, just set this property to the updated principal.  Now, you can do this by adding an IPrincipal or IIdentity implementation to your own user object (a great approach so your whole code can reference other things that you probably want to have anyway) or use the built-in Generic implementations, like this:

Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity(
                                                   "Your User Name"),
                                               null);

What’s better, this identity is automatically carried to other threads when you initiate work.  For example, if you queue a task to the thread pool:

Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity(
                                                   "Your User Name"),
                                               null);
Log.Information(LogCategory, "Now logged as Your User Name", null);

ThreadPool.QueueUserWorkItem((object state) =>;
{
    Log.Information(LogCategory, "This is from inside the user work item",
         "We are expecting it to be logged as Your User Name");
});

It also works with the new Task Parallel Library (TPL) options like Parallel.Invoke and Task.Run.

Even better, it doesn’t affect the OS identity your thread is running under so access to external resources like files, network shares, and network proxies are unaffected.

Even More Reason To Record Users

Development work is underway now to make Loupe Server smarter about user information in Loupe logs, allowing you to see exactly which users are affected by each error and how many users a problem is happening to based on the data on each log message.  So, if you’re still just getting the OS user name because your security system isn’t setting CurrentPrincipal now is a great time to change it!

You can read more about this and other tips for effective logging in the Loupe Documentation.

Related Posts

Loupe Agent for .NET Core Now Available

The first release of the Loupe Agent for .NET Core is also our first open source version of the Loupe Agent. This is the first step in our plan to open source the entire Loupe Agent to make it easier for anyone to extend and take advantage of what Loupe... Read more

We've Moved Loupe Service to App.OnLoupe.Com

Loupe Service now has a shorter, direct site name that's faster, anywhere in the world. Just to go App.OnLoupe.Com, the new CDN-accelerated endpoint for the Loupe Service. Your existing Agents and Loupe Desktops are unaffected by this change, but access to the web UI will be redirected to the new... Read more

Loupe 4.5 Released with New Log Viewer for Web

Rapidly diagnose each error in any .NET application with our new Web Log Viewer and Exception root cause analysis, new in Loupe 4.5. New integration with Azure Service Bus and Azure Search enables full Loupe functionality without any Virtual Servers in Azure. Read more

Rock solid centralized .NET logging

Unlimited applications, unlimited errors, scalable from solo startup to enterprise.