Tutorial - Logging and Exception Handling
support (Microsoft Enterprise Library)
CodeTrigger provides advanced support for logging and exception handling. This sample
shows how to use it with Microsoft Enterprise Library logger. It is also compatible
with other commonly used loggers (such as log4net etc)
This guide has been updated for version 5.1.0.0 (released June 10th 2017)
|
|
Microsoft Northwind Sample db
|
STEP 1 - Ensure you have a relevant test database
The CodeTrigger sample applications are designed to work with your existing database
schema to ensure that the samples are as relevant as possible. Ensure that you have
a TEST SQL Server/Oracle/MYSQL database handy. CodeTrigger and its associated supplier
companies do not accept any liability for data loss whilst using the CodeTrigger
product. It is important that you use a test database until you are familiar with
the functionality of the generated code. This code sample assumes MSQL DB Server/NORTHWIND
test database, but should work with your MYSQL/ORACLE db server and your test database
of choice.
|
|
Step 2 - Create and build a basic Console App
using CodeTrigger
Create a build a simple app using one of the CodeTrigger Wizards, perhaps following one of the basic tutorials.
|
|
Step 3 - Modify the CodeTrigger project
Choose the following settings in the Advanced options tab:
Enable logging support: Ticked
Enable exception handling support: Ticked
If you are using Northwind sample test database, select 'BOEmployees' in the Business
Objects tab, (If you are not using the Northwind sample test database, select suitable
objects from those listed in your Business Objects tab) and click Generate Code
to generate the files.
|
|
Step 4 - Modify the generated xxx_BaseData.cs
class
Modify the generated HandleException method stub in the generated basedata class
#region exception handling support
static partial void HandleException(object o, Exception ex);
static protected void Handle(object o, Exception ex, [CallerMemberName] string memberName = "")
{
//HandleException(o, ex, memberName);
throw ex;
}
#endregion
Important: Add the modified xxx_BaseData.cs
filename to the 'Escaped Files List' in CodeTrigger advanced options tab, to avoid
your changes being overwritten.
|
|
Step 5 - Add a reference to the Microsoft Enterprise
Library modules
Add project references to the modules (download and install Microsoft Enterprise
Library if you havent got it yet):
Microsoft.Practices.EnterpriseLibrary.Common
Microsoft.Practices.EnterpriseLibrary.Logging
System.Configuration
Now add a file called xxx_BaseBusiness_Extension.cs to your project to extend
your xxx_BaseBusiness class and add logging and exception handling code according
to your preferred policy.
(In the code fragment below, if necessary dont forget to change the class name from
Northwind_BaseBusiness to match whatever your actual base business class is called, and change the namespace to the appropriate namespace for your project)
Note the additional 'memberName' arguments/parameters to the support methods, these
are only necessary if you added the optional 'memberName' parameter in Step 4 above.
/*Northwind_BaseBusiness_Extension.cs - extends generated Northwind_BaseBusiness*/
using System;
using System.IO;
using System.Configuration;
using System.Xml.Serialization;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using Microsoft.Practices.EnterpriseLibrary.Logging.Formatters;
using Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners;
namespace LoggingAndExceptionSample
{
public static class Category
{
public const string Error = "Error";
public const string Info = "Info";
}
/******************************************************/
/******************************************************/
public partial class Northwind_BaseBusiness
{
#region exception support
static partial void HandleException(object o, Exception ex, string memberName)
{
string typeName = "";
if (o != null) typeName = o.GetType().FullName;
/*you can choose to swallow or rethrow all or some exceptions according to policy*/
throw new Exception("Error occurred in " + typeName + ":" + memberName + ". This error has been logged", ex);
}
#endregion
#region logging support
static string _logginglevel = "NORMAL";
static Northwind_BaseBusiness()
{
Logger.SetLogWriter(new LogWriterFactory().Create());
Logger.Write("Northwind_BaseBusiness:Start", Category.Info);
string configLogLevel = ConfigurationManager.AppSettings["logginglevel"];
_logginglevel = ((configLogLevel != null) ? configLogLevel.ToUpper() : _logginglevel);
}
public static string SerializeObject(object toSerialize)
{
XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
StringWriter textWriter = new StringWriter();
xmlSerializer.Serialize(textWriter, toSerialize);
return textWriter.ToString();
}
static partial void LogDoing(object o, string memberName)
{
string typeName = "";
if (o != null) typeName = o.GetType().FullName;
string message = typeName + ":" + memberName + ":Start";
if (_logginglevel == "VERBOSE" && (o != null))
message += SerializeObject(o);
Logger.Write(message, Category.Info);
}
static partial void LogDone(object o, string memberName)
{
string typeName = "";
if (o != null) typeName = o.GetType().FullName;
string message = typeName + ":" + memberName + ":Done";
if (_logginglevel == "VERBOSE" && (o != null))
message += SerializeObject(o);
Logger.Write(message, Category.Info);
}
static partial void LogFailed(object o, Exception ex, string memberName)
{
string typeName = "";
if (o != null) typeName = o.GetType().FullName;
string message = typeName + ":" + memberName + ":Failed";
message += " Exception:" + ex.Message;
if (ex.InnerException != null) message += " InnerException:" + ex.InnerException.Message;
message += " StackTrace:" + ex.StackTrace;
if (_logginglevel == "VERBOSE" && (o != null))
message += SerializeObject(o);
Logger.Write(message, Category.Error);
}
#endregion
}
}
Build your project to make sure it builds successfully and fix any namespace issues.
|
|
Step 6 - Add the relevant config entries to your
App.config file for the logger
Add the following config entries to the 'configuration' section of your app.config
file for logger initialisation. Insert just below your top level 'configuration'
element:
<configSections>
<section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings,
Microsoft.Practices.EnterpriseLibrary.Logging, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
requirePermission="true" />
</configSections>
<loggingConfiguration name="" tracingEnabled="true" defaultCategory="General">
<listeners>
<add name="Rolling Flat File Trace Listener"
type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollingFlatFileTraceListener,
Microsoft.Practices.EnterpriseLibrary.Logging, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.RollingFlatFileTraceListenerData,
Microsoft.Practices.EnterpriseLibrary.Logging, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
fileName="c:\Logs\test.rolling.log" footer="End Log Entry."
formatter="Text Formatter" header="Log Entry: "
traceOutputOptions="DateTime, Timestamp" />
</listeners>
<formatters>
<add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter,
Microsoft.Practices.EnterpriseLibrary.Logging,
Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
template="Category:{category} Message:{message} Timestamp:{timestamp}" name="Text Formatter" />
</formatters>
<categorySources>
<add switchValue="All" name="Info">
<listeners>
<add name="Rolling Flat File Trace Listener" />
</listeners>
</add>
<add switchValue="All" name="Error">
<listeners>
<add name="Rolling Flat File Trace Listener" />
</listeners>
</add>
</categorySources>
<specialSources>
<allEvents switchValue="All" name="All Events" />
<notProcessed switchValue="All" name="Unprocessed Category" />
<errors switchValue="All" name="Logging Errors and Warnings" />
</specialSources>
</loggingConfiguration>
Add the following key value to your app.config file in the 'appSettings' section.
<add key="logginglevel" value="verbose"/>
|
|
Step 7 - Write some code to test our your logging
and exception handling Implementation
You are ready to test out your logging and exception handling implementation. Here
is some code that (using the Northwind sample database) shows retrievals and updates
to an employee record, and a forced exception that gets handled (and rethrown).
Set your log viewer to watch the log file as setup in your config file (c:\Logs\test.rolling.log)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LoggingAndExceptionSample
{
class Program
{
static void Main(string[] args)
{
string originalFirstName = "";
int invalidReportingLine = -1;
/*loading this objects data will write to the log*/
Console.WriteLine("Selecting one object from db");
BOEmployees boEmployee = new BOEmployees(1);
originalFirstName = boEmployee.FirstName;
Console.WriteLine("Employee first name: " + originalFirstName);
/*updating this objects data will write to the log*/
boEmployee.FirstName = "Test Name";
boEmployee.Update();
Console.WriteLine("Employee first name updated to : " + boEmployee.FirstName);
/*restore the objects data*/
boEmployee.FirstName = originalFirstName;
boEmployee.Update();
Console.WriteLine("Employee first name restored to : " + originalFirstName);
/*cause an exception, this will be handled, and rethrown as per our exception handling code*/
Console.WriteLine("Deliberately going to cause an error here so we can log it");
boEmployee.ReportsTo = invalidReportingLine;
try{ boEmployee.Update(); }
catch(Exception ex){ Console.WriteLine(ex.Message); }
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine("Demo complete. lookup the logs in the log file as listed in app.config.");
Console.WriteLine("as listed in app.config 'c:\\logs\\test.rolling.log'");
Console.WriteLine("Test complete. Press any key to exit");
Console.ReadLine();
}
}
}
|
|