NLog to DB with UserId

who-did-what_scaled

The Problem

A user (whether live or internal) allegedly has an issue with your ASP.NET web site that stores the user Id in the ASP.NET session. They describe the problem and the steps to reproduce, but even with that it would be nice to have more information about what specifically they did. Or better yet what the code did on their behalf.

For this, it helps to have more granular data than tracking. We will wade through the pile of application logs to find our smoking gun. If you’re using NLog odds are that you already have this.

Now there is a different problem, the sheer volume of log statements. Even for a relatively small site (~50 concurrent users) plucking out the relevant statements for your problem user becomes a problem.

The Solution

Simply add the userid or any other session variable to each log statement and then you can easily filter based on that. Wait a second though…I don’t want to have to edit each and every log statement. Fortunately thanks to NLog you don’t have to.

Install the NLog, NLog.Config, NLog.Schema and NLog.Web packages using the following commands. Install-Package_NLog

NLog.Config will stand up a shell configuration file with examples.

Install-Package NLog.Config

NLog.Web will add the ability to use ASP.NET session variables and other goodies with NLog.

Install-Package NLog.Web

Update the NLog.Config file like below to include the new value.


<targets>
<target name="dbLogger" xsi:type="Database"
connectionStringName="DefaultConnection" commandText="
insert into dbo.Log (
Date, Level, Message, Username,
ServerName, SessionId
) values (
@Date, @Level, @Message,
@Username, @ServerName, @SessionId
);">
<parameter layout="${Level}" name="@Level"/>
<parameter name="@username" layout="${identity}" />
<parameter name="@Date" layout="${date}" />
<parameter name="@Message" layout="${message}" />
<parameter name="@serverName" layout="${aspnet-request:serverVariable=SERVER_NAME}" />
<parameter name="@SessionId" layout="${aspnet-sessionid}" />
<!– repeated –>
</target>
<!–
add your targets here
See https://github.com/nlog/NLog/wiki/Targets for possible targets.
See https://github.com/nlog/NLog/wiki/Layout-Renderers for the possible layout renderers.
–>
<!–
Write events to a file with the date in the filename.
<target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
layout="${longdate} ${uppercase:${level}} ${message}" />
–>
</targets>

view raw

NLog.Config

hosted with ❤ by GitHub

https://gist.github.com/ryanvgates/daff6e67ae0ebe05637b6fb64a9cc506#file-nlog-config

There you have it. Now you can easily filter log entries by user. You can find my code here.

Logging_Auth_Info_And_Session_Info_2017-06-15_22-55-34

References

  1. AspNetSession layout renderer
  2. NLog Database target
  3. AspNetSession layout renderer not working
  4. NLogUserIdToDB code