Click here to Skip to main content
15,896,606 members
Articles / Desktop Programming / Windows Forms

NLog Log and Audit Advanced Target

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
26 May 2010CPOL6 min read 42.8K   750   35  
A way to audit your business objects using NLog.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NLog;
using App.Logger.Targets.ObjectHistoryLogger.Data;
using App.Logger.Targets.ObjectHistoryLogger.Configuration;

namespace App.Logger.Targets.ObjectHistoryLogger
{
	[Target("OHTarget")] 
	public sealed class OHTarget : NLog.TargetWithLayout
	{

		/* Options */

		/// <summary>
		/// Gets or sets the invariant database name.
		/// This is used to identify wich database client to use.
		/// </summary>
		public string DbProviderInvariantName { get; set; }

		/// <summary>
		/// Gets or sets the connection string.
		/// </summary>
		/// <value>The connection string.</value>
		public string ConnectionString { get; set; }

		/// <summary>
		/// Gets or sets the DB tables prefix.
		/// This is optional and is meant to prevent naming colisions on the destination database.
		/// </summary>
		/// <value>The DB tables prefix.</value>
		public string DBTablesPrefix { get; set; }

		bool _autoCreateDatabase = false;
		/// <summary>
		/// Gets or sets if the target automatically creates the needed database objects.
		/// The default value is true.
		/// </summary>
		public bool AutoCreateDatabase 
		{
			get { return _autoCreateDatabase; }
			set { _autoCreateDatabase = value; }
		}

		public string LogTypes { get; set; }


		/// <summary>
		/// Writes logging event to the log target. Must be overridden in inheriting
		/// classes.
		/// </summary>
		/// <param name="logEvent">Logging event to be written out.</param>
		protected override void Write(NLog.LogEventInfo logEvent)
		{
			ValidateMandatoryOptions();

			// Create the database if it doesn't exist
			if (AutoCreateDatabase)
				CreateDatabase();

			// this target only supports OHInfo objects
			List<OHInfo> objectsToLog = new List<OHInfo>();
			OHAuditInfo auditInfo = null;
			if (logEvent.Parameters != null && logEvent.Parameters.Length > 0)
			{
				for (int p = 0; p < logEvent.Parameters.Length; p++)
				{
					if (logEvent.Parameters[p] is OHAuditInfo)
					{
						auditInfo = (OHAuditInfo)logEvent.Parameters[p];
					}
					else
					{
						OHInfo info = new OHInfo(logEvent.Parameters[p], this);
						if (info.IsLoggable)
						{
							objectsToLog.Add(info);
						}
					}
				}
				
				Data.OHDbBaseClient dbClient = OHDbFactory.GetDbClient(this);

				for (int i = 0; i < objectsToLog.Count; i++)
				{
					if (auditInfo != null)
					{
						objectsToLog[i].User = auditInfo.UserName;
					}
					dbClient.SaveObject(objectsToLog[i], this);
				}
				
			}

			string cs = ConnectionString;

		}


		/// <summary>
		/// Validates the mandatory options.
		/// </summary>
		public void ValidateMandatoryOptions()
		{
			if (string.IsNullOrEmpty(ConnectionString))
			{
				throw new Exception("OHTarget needs the ConnectionString option defined.");
			}

			if (string.IsNullOrEmpty(DbProviderInvariantName))
			{
				throw new Exception("OHTarget needs the DbProviderInvariantName option defined.");
			}

		}

		public void CreateDatabase()
		{ 
			// I'll keep it simple for now, I'll only check if the ObjectLogs table exists.
			// In the futere I'll have to improve this to do a version comparison and create or update the schema.


			ValidateMandatoryOptions();
			Data.OHDbBaseClient dbClient = OHDbFactory.GetDbClient(this);
			dbClient.CreateDBSchema();
		}

		public XMLConfiguration XmlConfiguration()
		{
			return new XMLConfiguration(this);
		}


	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
Switzerland Switzerland
Senior IT Consultant working in Switzerland as Senior Software Engineer.

Find more at on my blog.

Comments and Discussions