Class code (Must add the nlog dll as a reference)
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Security.Principal;
using System.Text;
using NLog;
using PixelTrackingQueueService.Exceptions;
public class LogHelper
{
public static LogHelper CurrentHelper = new LogHelper();
[Flags]
public enum LogType
{
Error = 0x01,
CriticalError = 0x02,
Warning = 0x04,
Info = 0x08,
Debug = 0x10,
Trace = 0x20
}
public void Log(string message, LogType logType, Exception ex = null, Type currentType = null)
{
Logger logger = (currentType == null)
? LogManager.GetCurrentClassLogger()
: LogManager.GetLogger(currentType.FullName);
Action<string> log = null;
Action<string, Exception> exLog = null;
foreach (LogType flag in Enum.GetValues(typeof(LogType)))
{
LogType logLevel = (flag & logType);
LogLevel level = LogLevel.Off;
switch (logLevel)
{
case LogType.Warning:
level = LogLevel.Warn;
break;
case LogType.CriticalError:
level = LogLevel.Fatal;
break;
case LogType.Error:
level = LogLevel.Error;
break;
case LogType.Info:
level = LogLevel.Info;
break;
case LogType.Trace:
level = LogLevel.Trace;
break;
case LogType.Debug:
level = LogLevel.Debug;
break;
default:
continue;
}
DoLog(logger, message, level, ex, currentType);
}
}
private static void DoLog(Logger logger, string message, LogLevel level, Exception ex = null, Type type = null)
{
LogEventInfo info = new LogEventInfo(level,
((type == null) ? typeof(LogManager).FullName : type.FullName),
null,
message,null, ex);
info.Properties["ApplicationName"] = ConfigurationManager.AppSettings["ApplicationName"];
info.Properties["Host"] = System.Environment.MachineName;
info.Properties["Type"] = (ex == null) ? level.ToString() : ex.GetType().FullName;
info.Properties["CurrentUser"] = WindowsIdentity.GetCurrent().Name;
info.Properties["Source"] = ex == null ? level.ToString() : ex.Source;
string error = ex == null ? message : ex.ToString();
string stackTrace = ex == null ? level.ToString() : ex.StackTrace;
info.Properties["Error"] =
string.Format(
@"<error host=""{0}"" type=""{1}"" message=""{2}"" source=""{3}"" detail=""{4}"" ><serverVariables>
<item name=""SERVICE_NAME""><value string=""{5}""/></item>
<item name=""LOGON_USER""><value string=""{6}""/></item>
</serverVariables></error>",
System.Environment.MachineName,
info.Properties["Type"],
System.Security.SecurityElement.Escape(message),
info.Properties["Source"],
System.Security.SecurityElement.Escape(error),
"ServiceName",
info.Properties["CurrentUser"]);
logger.Log(info);
}
private Logger GetLoggerFromType(Type currentType)
{
return (currentType == null)
? LogManager.GetCurrentClassLogger()
: LogManager.GetLogger(currentType.FullName);
}
}
Nlog Config (with elmah proc)
Add this file to your solution, calling it Nlog.config. This is the file Nlog will look for:<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
<!--
See http://nlog-project.org/wiki/Configuration_file
for information on customizing logging rules and outputs.
-->
<targets>
<!-- add your targets here -->
<!--
<target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
layout="${longdate} ${uppercase:${level}} ${message}" />
-->
<target name="elmah" xsi:type="Database" keepConnection="true" useTransactions="true"
dbProvider="sqlserver" connectionString="Data Source=im-dev01\;Initial Catalog=Elmah;Integrated Security=False;User ID=Elmah;Password=1234;">
<commandText>
DECLARE @ID UNIQUEIDENTIFIER = NEWID(), @time DATETIME = GETUTCDATE()
SELECT @time
EXEC ELMAH_LogError @ID ,'${event-context:item=ApplicationName}', '${event-context:item=Host}',
'${event-context:item=Type}', '${event-context:item=Source}', '${message}','${event-context:item=CurrentUser}','${event-context:Error}', 1, @time
</commandText>
</target>
<target xsi:type="Mail" name="mailman" smtpServer="Mail.MailService.local" from="serviceerror@somewhere.com"
html="true" to="someone@somewhere.com"
subject="Service Error"
cc="someoneelse@somewhere.com"
body="<h1>Date and Time</h1>${longdate} <h1>Message</h1>${message} <h1>Exception Details</h1>
<h2>Error Details</h2> ${exception:format=ToString} <h2>Stack Trace Details</h2> ${exception:format=StackTrace}" />
<target name="TraceLog" xsi:type="File" fileName="Logs/Traces.log" createDirs="true"/>
<target name="ErrorLog" xsi:type="File" fileName="Logs/Errors.log" createDirs="true" layout="${message}\r\n${exception:format=ToString}"/>
<target name="WarningLog" xsi:type="File" fileName="Logs/Warnings.log" createDirs="true"/>
<target name="InfoLog" xsi:type="File" fileName="Logs/Info.log" createDirs="true"/>
</targets>
<rules>
<logger name="*" level="Fatal" writeTo="mailman" />
<logger name="*" level="Error" writeTo="elmah" />
<logger name="*" level="Info" writeTo="elmah" />
<logger name="*" level="Trace" writeTo="elmah" />
<logger name="*" level="Warn" writeTo="elmah" />
<logger name="*" level="Debug" writeTo="elmah" />
</rules>
</nlog>
Example on using the code:
LogHelper.CurrentHelper.Log("Error has occured", LogHelper.LogType.Debug | LogHelper.LogType.CriticalError, exceptionObject, this.GetType());will log to both elmah and send a mail at the same time.