Enterprise Library Wrapper - Making the LOG API more intitutive!
For my recent project I had to use the "Enterprise Logging Block" from the Enterprise Library.
Having used log4net for all the previous projects, this was something new and it turned out to be
an interesting experience..
The version I had to use was 3.2. I believe that there is a version 4.0 out right now.
Update: If you need to use version 4 , you would have to strong name your assemblies. Version I used were already signed. Here is a link that explains what I am talking about: http://blogsprajeesh.blogspot.com/2008/05/strong-naming-enterprise-library.html
Anyway one thing I dint like about Enterprise Logger was the way you write Logs..You can use
one of the 18 or so overloaded "Write" methods. It is great that Microsoft provided so many
overloads but they are not just so intuitive like log4net..As a developer I am mostly going to
log errors, warnings, info or debug statements and I loved the fact that you can just call .Info,
.Warn methods using log4Net ....
To construct a log entry with all required parameters like "User name", "Exception" you
had to define extended propertied, Construct a LogEntry object then fill it with properties
and then call the Write Method with the LogEntry object...aarg..I am just too lazy to do that ![]()
So I wrote a Wrapper Logger class that has methods like Debug, Info, Warn that can be used by
developers to log messages...Each of these method then has overloads that take in Category/Exception/Message etc etc ...All these methods then call the Write method
of the Microsoft Logger class that take a LogEntry as the parameter...
for example Debug method overloads will be ...
public static void Debug(object message)
{
WriteMessage(message, TraceEventType.Verbose, null, null);
}
public static void Debug(object message, Category category)
{
WriteMessage(message, TraceEventType.Verbose, category, null);
}
public static void Debug(object message, object category)
{
WriteMessage(message, TraceEventType.Verbose, category, null);
}
public static void Debug(object message, Exception ex)
{
WriteMessage(message, TraceEventType.Verbose, null, ex);
}
public static void Debug(object message, object category, Exception ex)
{
WriteMessage(message, TraceEventType.Verbose, category, ex);
}
The WriteMessage is given below
private static void WriteMessage(object message, TraceEventType eventType,
object category, Exception exception)
{
try {
LogEntry entry = new LogEntry();
entry.Severity = eventType;
//Add Message
if (((message != null))) {
entry.Message = message.ToString();
}
//Add category
if (((category != null))) {
entry.Categories.Add(category.ToString());
}
//Add exception, user name, detailed date & time if needed
AddExtendedProperties(entry, exception);
entry.TimeStamp = DateTime.Now;
//Only log the entry if we have a valid user name
if ((IsValidUser(entry))) {
try {
MicrosoftLogger.Write(entry);
}
catch (Exception ex) {
//Something wrong with the Logger ..make sure we
//dispose it properly
if (((MicrosoftLogger.Writer != null))) {
MicrosoftLogger.Writer.Dispose();
}
}
}
}
catch (Exception ex) {
//Logger exception we dont do anything about it as it will
//lead to recursive call
//Write to the file system or event log ?
}
}
One important line is "AddExtendedProperties(entry, exception); which does
the following
- Constructs the User name (first tries to get it from HttpContext, if not gets
it from the Thread)and writes it as an extended property - Constructs the Exception details (inner exception also) and writes it as an Extended Property
- Constructs the detailed Date and Time(in format yyyy-MM-dd hh:mm:ss.fff) and
writes it as an extended property
I have included the code for this class where you can go over and see how these are
exactly constructed...
Using the Logger - Sample Project:
The Logger file is included within the "HariEdge.Util.Logging" project. To use the
Logger class you just need to add the "HariEdge.Util.Logging" dll to your project
(This will also copy the required Enterprise dlls (3 of them) along with the
logging dll to the bin directory of your project)
Then to use the Logger, you would just call the corresponding Info, Warn or Debug messages...
Logger.Info("Test Message 1", "Custom Category");
Logger.Warn("Test Message 2", Category.UI);
Logger.Critical("Test Message 3", Category.WebServices);
Logger.Info("Test Message 4");
There are two Sample Applications included with the source file "Test.ConsoleApp"
and "Test.WebSite" that has the required configuration you would need to add
to the App.config or web.config file.
As you can see there are also some predefined categories that you can use
like Category.UI, Category.WebServices that you can use as the Category or
you can just pass in a custom category as a String.
If you have used Enterprise logging before, you do already know that one
cool concept of using categories is to have a custom filter on the Severity of
the Error (Info, Warn etc) and also specify a separate file for the category!!
Logs only Errors, Warnings and Info when switchValue is set to "Info"
<!-- Configure for Web Services category Source-->
<add switchValue="Info" name="WebServices">
<listeners>
<add name="WebServices category Rolling Flat File Trace Listener"/>
</listeners>
</add>
<add fileName="C:\Logs2\Application_WebServices_Category.log"
rollSizeKB="1024" timeStampPattern="yyyy-MM-dd"
rollFileExistsBehavior="Increment"
rollInterval="Day" formatter="Text Formatter" header="" footer="" listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.
RollingFlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging,
Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
traceOutputOptions="Timestamp"
type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.
RollingFlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging,
Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
name="WebServices category Rolling Flat File Trace Listener"/>
SharePoint Users
One of the things that would bite you when trying to use this in
SharePoint is Security!!!!! If your logging dll is in GAC or if the application is
running under "Full Trust" you wont see any issue..If it is not as stated
above(most shared environments run under WSS-Medium)not you would most probably
see an "Unexpected error" or "a beautiful stack trace quoting some
security permission error" if you have custom errors turned off.
So to take care of this you would need a custom Security Policy file that gives your
logging dll full trust. So one thing you would need to do is find out what the Trust
level is , find out where the trust file is located and then do the following
If you change for "trust" in web.config you will see an element like this
<trust level="WSS_Medium" originUrl="" />
Then if you search for the value in trust (WSS_Medium in our case) you
will see where the policy file is located as shown below
<trustLevel name="WSS_Medium"
policyFile="C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\CONFIG\wss_mediumtrust_custom.config" />
Insert the CodeGroup element given below in the custom trust file. The CodeGroup
elements should be placed under the following CodeGroup element in the Configuration file:
<CodeGroup class="FirstMatchCodeGroup" version="1" PermissionSetName="Nothing">
<CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="FullTrust">
<IMembershipCondition version="1"
Name="HariEdge.Util.Logging" class="UrlMembershipCondition" Url="$AppDirUrl$/bin/HariEdge.Util.Logging.dll" />
</CodeGroup>
Hopefully this helps someone....
Source Files: Logging Source File
Hari





This was pretty useful on my SharePoint project, thanks.
I just had to sign it with my strong name and change Referenced binaries to the latest version Enterprise Library 4.1. (3.1. binaries were missing in GAC and I was getting error "File not found"). I had to debug it to find out what is going on.
To move it from bin to GAC I changed class of the CodeGroup declaration from UrlMembershipCondition to StrongNameMembershipCondition and add PublicKeyBlob of the strong name.
Reply to this