Home > C#, Tips > [EN] NLog returning a log ID

[EN] NLog returning a log ID

There are plenty of .NET logging frameworks that allows a developer to log some messages. One of them are NLog, log4net, Elmah. Sometimes there is a need to present the user some kind of information when an error occured. The simplest way is to present the stacktrace with tons of usefull data for a hacker, or to present a simple message. In both cases when the client sees the screen, he calls the helpdesk and says “I have a problem” – and both sides cannot explain the reason of the error from the stack trace or the message. In this post I’ll present some way of presenting an error ticket to the client. By this the helpdesk can answer what was the reason by seeing a complete description of the error, the hacker knows almost nothing and the developer has full view into the exception.

The solution of presenting only a ticket is not new. On mostly any application (online application) You can see a message that tells You that You should contact the administrator sending him some kind of ID.

ERROR: An error has occurred while trying to launch the application. Please contact your administrator. Log ID: 54532

Let’s create such feature ourselve using NLog. First we will create a custom target for the NLog library. This target will be created only for our example, in a real application we can connect to database or send a SOAP message. Our custom target will generate the log ID – in the example I called it as COUNTER (in database this ID could be generated by some kind of sequence). This ID will be presented to the User.

[Target("TicketError")]
public sealed class TicketErrorTarget : TargetWithLayout
{
  public const string LOGTOKEN_NAME = "LOGTOKEN";
  private static int COUNTER = 0;
  protected override void Write(NLog.LogEventInfo logEvent)
  {
    Console.WriteLine("Write LOG:{0} {1}", logEvent.Message, SomeParameter);
    logEvent.Properties[LOGTOKEN_NAME] = (++COUNTER).ToString();
  }
  public string SomeParameter { get; set; }
}

Next, let’s create an extension method for our logging functionality. All logging methods in NLog return void. We will create a string method named ErrorToken that will return a string token (if generated). We can achieve this by using LogEventInfo and it’s Properties. Our property that will contain the token is named LOGTOKEN (of course You can name it in Your own way).

public static class LoggerExtensions
{
  public static string ErrorToken(this Logger log, string message)
  {
   if (log.IsErrorEnabled)
   {
     LogEventInfo logEventInfo =
              LogEventInfo.Create(LogLevel.Error, log.Name, message);
     logEventInfo.Properties[TicketErrorTarget.LOGTOKEN_NAME] = null;
     log.Log(logEventInfo);
     return logEventInfo.Properties[TicketErrorTarget.LOGTOKEN_NAME] as string;
    }
    return null;
  }
}

Next we have to tell NLog what should he do with the errors. We tell him, that our custom target is in MyNLogTargets.dll and that we will use an TicketError target for minimum Error log levels.

<nlog>
  <extensions>
    <add assembly="MyNLogTargets"/>
  </extensions>
  <targets>
    <target name="ticketError" 
            type="TicketError" 
            SomeParameter="SomeConnectionString" />
    <target name="fileTarget" 
            type="File" 
            layout="${longdate} ${logger} ${message}"
            fileName="logfile.txt" />
  </targets>
  <rules>
    <logger name="*" minLevel="Error" writeTo="ticketError"/>
    <logger name="*" minLevel="Info" writeTo="fileTarget"/>
  </rules>
</nlog>

Take a look closer to the SomeParameter in config file. You can see this value in our custom target. By this way we can configure our target by setting a connection string to database. The example, how we can use our method is presented below. In console window we write the ID of the log

public class LoggedClass
{
  private Logger _log = LogManager.GetCurrentClassLogger();
  public void MakeLog(string message)
  {
    Console.WriteLine(_log.ErrorToken(message));
  }
}

Unfortunatlly this does not solve all our problems. Not all errors can be catched, the mechanism of saving the log to database with returning a ticket can fail when there is no connection to database – but in most cases the mechanism helps us solving any handled error.

  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: