Thursday, 14 November 2013

Creating a Support Ticket System with nLog


When the idea of Trekking for Charity came about we knew that any system is only as good as the team behind it. By that I don’t mean solely the development of the project but the support we give to our members. What we needed is a way that a user of the site could raise a support ticket whenever they encounter an error in the system.  This had to be done in such a way that we could track their support ticket straight back to the error that happened when they raised it. Trekking for Charity uses NLog for all it’s event logging, I find it easy to use, extend and implement and is also fairly well documented.  You can read more about NLog over at nlog-project.org. The support ticket system had the following requirements:
  • All errors in the system can be raised as tickets
  • Tickets must be related to an event in the log
  • Tickets should be raised by the user without ever seeing an error code.
So this raised an issue, normally event logging is a one way event, i.e. an exception occurred then that is written to the log.  What we needed was some kind of Id of the record in the database so that a ticket has a relevant error log about it.  What we wanted to do was use the Id from the database but that wasn’t an option.  Through the use of targets and renderers NLog allows for a value we give it to be push into the database and so we can create our tickets against that value. In this part I will go thought the steps of setting up a simple event log database with ASP.Net MVC 4 and you can find the example project here on bitbucket.org. For this all errors will be logged to the database. Here is the schema I used:
CREATE TABLE [dbo].[Log]
(
 [Id] int NOT NULL PRIMARY KEY IDENTITY(1, 1),
 [TimeStamp] datetime NOT NULL DEFAULT GETDATE(),
 [Host] nvarchar(MAX) NOT NULL,
 [Type] nvarchar(200) NOT NULL,
 [Source] nvarchar(200) NOT NULL,
 [Message] nvarchar(MAX) NOT NULL,
 [Level] nvarchar(50) NOT NULL,
 [Logger] nvarchar(200) NOT NULL,
 [Stacktrace] nvarchar(MAX) NULL
)
Next step is a way of creating the errors to log, for this I have created an empty MVC 4 website and added NLog via nuget. I like NLog and prefer it to log4net and Enterprise Library as it is simple, easy to drop into your project and does require anything to be added to the web/app.config file.  What it does need is a config file of its own, it’s named nlog.config and resides in the root of the site. Here is what is used in the example project:
<?xml version="1.0" ?>
<nlog autoreload="true">
  <targets>
    <target type="Database" name="databaselog">
      <dbprovider>sqlserver</dbprovider>
      <connectionstring>Data Source=(localdb)\v11.0;Initial Catalog=Logging;Integrated Security=True</connectionstring>
      <commandtext>
        INSERT INTO Log
        ([level],[host],[type],[source],[logger],[message],[stacktrace])
        VALUES
        (@level,@host,@type,@source,@logger,@message,@stacktrace);
      </commandtext>

      <parameter name="@level" layout="${level}" />
      <parameter name="@host" layout="${machinename}" />
      <parameter name="@type" layout="${exception:format=type}" />
      <parameter name="@source" layout="${callsite:className=true:fileName=false:includeSourcePath=false:methodName=false}" />
      <parameter name="@logger" layout="${logger}" />
      <parameter name="@message" layout="${message}" />
      <parameter name="@stacktrace" layout="${exception:stacktrace}" />
    </target>
  </targets>
  <rules>
    <logger name="*" minlevel="Info" writeto="databaselog" />
  </rules>
</nlog>
Now for the final part, create the logger instance and log something.  To do this create a controller, give it the name ‘HomeController.cs’ and add this to the class our logger instance.
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
Finally to the Index method add:
logger.Error("My Error");
Now when the site is run an error generated in the log because there isn’t a view for that action, but when in the database there is a log that was created. Just like this:



In the next part in this series I will talk about the steps we took to put in place a system that logs every error which happens in the system.

0 comments:

Post a Comment