1/- http://www.devx.com/dotnet/Article/36184/1954
2/-http://oddiandeveloper.blogspot.com/2008/09/microsoft-enterprise-library-1-logging.html
3/-http://www.codeproject.com/KB/architecture/GetLoggingWithEntLib.aspx
Enterprise Library 2.0 Logging Application Block Part III - Programmatically Using Logging Application Block With No Configuration File
by David Hayden ( Florida .NET Developer )
This is Part III in a series of tutorials on the Enterprise Library 2.0 Logging Application Block. The first two parts were:
* Enterprise Library 2.0 Logging Application Block Part I - TraceListeners
* Enterprise Library 2.0 Logging Application Block Part II - Simple ASP.NET 2.0 Website Example - Logging Unhandled Exceptions
In this example, I will show one how to programmatically use the Enterprise Library 2.0 Logging Application Block without a configuration file.
Before I begin, special thanks goes to Alois Kraus who has written a similar article, called Programatic Configuraton - Enterprise Library (v2.0) Logging Block. While I was learning this myself, Alois came out with his very timely article that cleared up a number of questions.
Enterprise Library 2.0 Logging Application Block Key Objects
There are several key objects that you need to familiar yourself with before you go any furthere
1. LogFormatter - typically a TextFormatter or BinaryFormatter. The role of formatters in the Logging Application Block is to specify the way you want your log messages to look in the intended datastore ( file, database, email, etc. ). Most of the time you will use the TextFormatter, which has a Template Property that specifies the “template“ of the message. Inside this template you can have a number of tokens ( e.g. {timestamp} ) that the Logging Application Block will fill for you.
2. TraceListener - As mentioned in Part I, tracelisteners provide the logging services. They are the conduit for which messages make it to their intended destinations ( database, email, flat file, event log ). The Logging Application Block comes with several tracelisteners such as: Database TraceListener, Email TraceListener, Flat File TraceListener, Formatter Event Log TraceListener , etc. The TraceListener requires a Formatter to specify the message format.
3. LogSource - LogSource is a collection of TraceListeners that work as a unit.
4. LogWriter - This is The Man. The LogWriter is the focal point of the Logging Application Block. It is the glue that binds all the tracelisteners, filters, and everything else together to make sure the messages that you log and pass through the filters get to the respective tracelisteners. It is the LogWriter.Write(LogEntry log) method that makes it all happen.
5. LogEntry - This is the class that holds your message. You will set the Message, Category, Priority, EventId, Severity, and other properties on this class for logging. You may not knowingly use the class directly, because often classes in the Logging Application Block may fill it out for you. However, this is the class that ultimately gets passed to the LogWriter that pushes the message through to the intended LogSource and its TraceListeners.
6. ILogFilter - I will talk about this in another post, but utimately it is a collection of objects implementing the ILogFilter Interface that determine if a message actually gets logged by the LogWriter. It could be a CategoryFilter, LogEnabledFilter, PriorityFilter, or a custom filter you built yourself.
Why Use Logging Application Block Objects Directly
A good question is why one would use the Logging Application Block objects directly as opposed to using the facade and factory classes that work with an IConfigurationSource? My opinion is that you will gain more speed by losing all the configuration overhead. I haven't measured the difference so it may be negligible in the real world, but certainly there has to be some overhead of using the facade and factory classes.
The main drawback about using the objects directly is the ability to make changes in how, when, and where messages are logged without touching code. The beauty of the Logging Application Block is that one can modify the web.config or app.config to control logging without recompiling the application. I can add filters, new tracelisteners, etc. on the fly via the configuration file. If your needs are simple and will never change, this is no big deal. But if you see logging as a moving target, better to encapsulate it using the built in facade.
Enterprise Library 2.0 Logging Application Block Sample
Shown below is an example of programmatically using the Logging Application Block through code without the use of a configuration file. Note that this is very similar to Alois Kraus' example as his article finally helped me understand the true inner-working of the Logging Application Block. Per some comments on Alois' article, I chose to handle thread safety using a static constructor. It is a minor change, but I felt it made the MyLogger Class much more simple to comprehend. I checked with Alois and he gave me a thumbs up on the simplification :)
I have commented the code pretty heavily to guide you through the process, which hopefully will answers any questions on it.
///
/// MyLogger logs messages in the application.
///
public static class MyLogger
{
static readonly LogWriter _writer;
static MyLogger()
{
// The formatter is responsible for the
// look of the message. Notice the tokens:
// {timestamp}, {newline}, {message}, {category}
TextFormatter formatter = new TextFormatter
("Timestamp: {timestamp}{newline}" +
"Message: {message}{newline}" +
"Category: {category}{newline}");
// Log messages to a log file.
// Use the formatter mentioned above
// as well as the header and footer
// specified.
FlatFileTraceListener logFileListener =
new FlatFileTraceListener("c:\\messages.log",
"----------",
"----------",
formatter);
// My collection of TraceListeners.
// I am only using one. Could add more.
LogSource mainLogSource =
new LogSource("MainLogSource", SourceLevels.All);
mainLogSource.Listeners.Add(logFileListener);
// Assigning a non-existant LogSource
// for Logging Application Block
// Specials Sources I don't care about.
// Used to say "don't log".
LogSource nonExistantLogSource = new LogSource("Empty");
// I want all messages with a category of
// "Error" or "Debug" to get distributed
// to all TraceListeners in my mainLogSource.
IDictionary
new Dictionary
traceSources.Add("Error", mainLogSource);
traceSources.Add("Debug", mainLogSource);
// Let's glue it all together.
// No filters at this time.
// I won't log a couple of the Special
// Sources: All Events and Events not
// using "Error" or "Debug" categories.
_writer = new LogWriter(new ILogFilter[0],
traceSources,
nonExistantLogSource,
nonExistantLogSource,
mainLogSource,
"Error",
false,
true);
}
///
/// Writes an Error to the log.
///
/// Error Message
public static void Write(string message)
{
Write(message, "Error");
}
///
/// Writes a message to the log using the specified
/// category.
///
///
///
public static void Write(string message, string category)
{
LogEntry entry = new LogEntry();
entry.Categories.Add(category);
entry.Message = message;
_writer.Write(entry);
}
}
It perhaps is dangerous to map all of the Logging Application Block's Special Sources to a non-existant LogSource, such as the nonExistantLogSource. I could see not logging the All Events Special Source if you want more control of messages using Categories. However, as I did above, I would recommend logging at least any warnings and error messages emitted from the Logging and Error Warnings Special Source. These are errors and warnings coming from the Logging Application Block itself allowing you to monitor its health.
Testing the Class
I put together a quick web application to test out the new class. Here is the extent of the code:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
MyLogger.Write("My Error");
MyLogger.Write("My Debug", "Debug");
}
}
Configuring & Using Enterprise Library 2005 in .NET Applications
Name Account / Business Group Date
Author(s) I. Trinath
immaneni.trinath@wipro.com
Barwil, TMTS 27-09-2005
Reviewed by Rizwan Saulat
rizwan.saulat@wipro.com
Barwil, TMTS 04-10-2005
TABLE OF CONTENTS
1 Introduction 3
2 Advantages 4
3 Installing Enterprise Library 5
4 Using the Configuration Application block 7
5 Using the Logging & Instrumentation block 11
6 Using the Data Access Application Block 16
7 Using the Exception Handling Application Block 21
8 Using the Security Application block 29
9 References 33
1 Introduction
Enterprise Library is collection of Application Blocks designed to assist developers with common enterprise development challenges and to help address common problems that developers face in projects.
Enterprise Library comprises of the following application blocks.
1. Configuration Application block
2. Logging & Instrumentation Application block
3. Data Acces Application block
4. Exception Handling Application block
5. Caching Application block
6. Security Application block
7. Cryptography Application block
This document does not provide an in-depth coverage of all the features of each application block but rather aims to help the developer in getting up to speed with configuring and start using the Enterprise Library 2005.
The Caching and Cryptography Application blocks are left as an exercise to the user and are not covered in this document.
2 Advantages
The following are the advantages of using the Application blocks:
1. Reduces the need to write boilerplate code
2. Independence of underlying mechanisms from rest of the code. This allows the mechanisms to be changed / enhanced without need to recompile the rest of the code.
3. Easier to use and hence eases the learning curve for the developers.
4. Helps maintain consistent practices.
3 Installing Enterprise Library
Pre-requisites:
• Microsoft .NET Framework 1.1
• Microsoft Visual Studio 2003
• Data Access application block requires the use of database product like SQL Server or Oracle.
The following are the steps to be followed for setting up Enterprise Library for use in the Project:
1. Downloading the Enterprise Library
2. Patching the Data Access Application block to return multiple ref cursors for Oracle Databases.
3. Strong naming the Enterprise Library dlls.
4. Building & placing the dlls in the Global Assembly Cache.
5. Creating the VOSS project.
6. Opening the Web.config from Enterprise Library Configuration tool.
Details for each of the steps above are as follows:
1. Downloading the Enterprise Library: The Enterprise Library can be downloaded from the Microsoft patterns & practices site at: http://msdn.microsoft.com/practices/compcat/default.aspx?pull=/library/en-us/dnpag2/html/entlib.asp. The Enterprise Library will be installed at the following location C:\Program Files\Microsoft Enterprise Library June 2005. The src sub folder contains the source code which can be modified as required.
2. Patching the Data Access block: The Data Access block of Enterprise Library June 2005 edition does not support returning of multiple cursors from the Oracle Databases. A patch to fix this is available at: http://www.gotdotnet.com/Community/UserSamples/Download.aspx?SampleGuid=C2528304-A1F2-4F51-9265-ECC7FF4902E7. Replace the actual source files with the files in the patch.
3. Strong naming the Enterprise Libarary dlls: The instructions to strong name the Enterpirse Library are present at http://bloggingabout.net/blogs/erwyn/archive/2005/07/17/8545.aspx.
4. Once the Projects are assigned a Strong named, the following steps must be performed. From the C:\Program Files\Microsoft Enterprise Library June 2005\src directory the following batch files must be run:
• BuildLibrary.bat, with the parameter ”Release”. This builds the dlls in the Release mode. The default is the ”Debug” mode.
• CopyAssemblies.bat, with the parameter ”Release”. This copies the dlls in to C:\Program Files\Microsoft Enterprise Library\bin. This is needed for the Enterprise Library Configuration tool.
• InstallServices.bat. This installs the instrumentation schema.
• Drag and drop the files in GAC.
5. Creating the Project: Now create an ASP.NET project and add a Web.config file to the project. The Web.config file will be used by the Enterprise Library Configuration Tool to store the settings needed for Enterprise Library.
6. Now open the Enterprise Library Configuration tool from the location:
Once the Enterprise Library Configuration tool opens, click on Open Application in the File menu. Browse and select the Web.config file created in the 5th step.
4 Using the Configuration Application block
1. Right click on the Application in the Enterprise Configuration tool. Then click on New -> Configuration Application Block.
2. Right click on the Configuration Application Block. Then click on New -> Configuration Section.
3. Rename the new added section to appConfiguration.
4. Right click on the appConfiguration and then click on New -> XML File Storage Provider.
5. Change the FileName for XML File Storage Provider to appConfiguration.config.
6. Right click on the appConfiguration section and then click on New -> XML Serializer Transformer.
7. Now create a class which will hold the configuration information read from the appConfiguration section. The public members will be the sub sections within the appConfiguration element.
8. The following code snippet illustrates how the Configuration data is written.
9. The following code snippet illustrates how the configuration data can be updated.
5 Using the Logging & Instrumentation block
1. Right click on the Application in the Enterprise Configuration tool. Then click on New -> Logging and Instrumentation Application Block.
The Configuration Application Block is used by the rest of the blocks. So the Configuration Application Block is added by default when other blocks are added. Once the Logging block is added the Configuration tool looks like below:
2. Now right click on the Sinks and add a new Flat File Sink.
Change the settings of the New sink that we have just added as follows:
3. Next step is to define the categories of the messages that we are going to use in our application. Right click on Categories and then click on New -> Category.
Rename the new category as “Error”. Then right click on the new category and select New -> Destination.
For the new destination that we have added, select ”Text Formatter” as the Formatter and ”Error Sink”, created in Step 2, as the Sink.
Save the settings. Create a file ErrMsg.log in C:\ and provide write permissions for the ASPNET user. This is the user under which the WebApplications run in under .NET.
4. The Logging Application block is ready to be used in the Application. The following steps list the steps needed to use the Logger component:
a. Add a reference to Microsoft.Practices.EnterpriseLibrary.Logging.dll for the project.
b. Import the namespace in each page or component wherever the logging is needed.
c. Use Logger.Write method in code to start logging.
The steps have been marked as solid boxes in the screenshot below:
6 Using the Data Access Application Block
1. Right click on the Application in the Enterprise Configuration tool. Then click on New -> Data Access Application Block.
After adding the Data Access Application block the Enterprise Library Configuration tool will be as follows:
The Sql Connection String and Sql Server are added by default. These need to be changed to access the Oracle Database. Also, a dataConfiguration element is added in the Configuration Application block.
2. Under Database Types, for the ”Sql Server” that has been added by default, change the Name to ”Oracle Server” and select the Type Name as OracleDatabase.
3. Rename the ”Sql Connection String” which has been added by default to ”Oracle Connection String”.
4. Delete/rename the parameters of the Connection String as needed. Oracle connection string has Data Source, User Id, Password.
5. Rename the Database Instance to Oracle Instance, and make sure that the ConnectionStringNode has ”Oracle Connection String” as the value and DatabaseTypeNode has ”Oracle Server” as the value.
6. Click on the Data Access Application Block and make sure that ”Oracle Instance” has been selected as DefaultInstanceNode.
7. Now click on dataConfiguration under the Configuration Application Block.
The Encrypt value is False. As the Connection String settings are stored under the dataConfiguration, it is advisable to Encrypt the dataConfiguration section.
8. Change the Encrypt value of dataConfiguration element to True and then right click on Encryption Settings and add a new File Key Algorithm Storage Provider.
The steps for Adding the File Key Algorithm Storage Provider are straight forward.
9. Once the File Key Algorithm Storage Provider has been added, the Data Access Application block is ready to be used by the application. The following code snippet shows how the Data Access Application block can be used.
• Add a reference to Microsoft.Practices.EnterpriseLibrary.Data.dll and Microsoft.Practices.EnterpriseLibrary.Configuration.dll.
• Import the namespace Microsoft.Practices.EnterpriseLibrary.Data.
• Use DatabaseFactory.CreateDatabase to create a Database object and then use one of the various methods available on the Database object to get a DataReader or DataSet.
Note: Data Access using the ADO.NET objects (Connection, Command) would require at least 5 lines of code to be written. Using the Data Access Application block the same code can be written in 2 lines.
Moreover the Data Access Application block provides a Database Vendor independent way of accessing the data, thus allowing us to change to any other database with no changes to the code.
7 Using the Exception Handling Application Block
Exception Handling Application block provides a way to define exception handling policies. Policies contain a series of exception types that the policy handles. Each exception type has a list of handlers that are executed sequentially.
For example, when a Database exception occurs we would like to log the actual error and replace the actual exception message with a user friendly message so that the same can displayed back to the user. The following steps lists the procedure to implement this Log & Replace policy.
1. Right click on the Application in the Enterprise Configuration tool. Then click on New -> Exception Handling Application Block.
2. Right click on the Exception Handling Application block, and click on New -> Exception Policy.
3. Rename the policy to “Data Access Policy”.
4. Right click on the Data Access Policy and then click on New -> Exception type.
Clicking on Exception Type will open a Type Selector dialog box. Select Exception in the Type Selector dialog box and click on Ok.
5. Select the PostHandlingAction for the Exception type to “ThrowNewException”.
6. Right click on the Exception Type and then click on New -> Logging Handler.
A Logging Handler logs the exception. Since the Logging Handler is the first handler being added, it will receive the actual exception. Logging Handler use the “Logging & Instrumentation block” for logging.
7. After the Logging handler is added, a LogCategory has to be specified.
Select General as the LogCategory and this will log the Exception to the Event Log.
8. Next add a Replace Handler to the Exception type.
9. For the Replace Handler, enter “Database Internal Error” as ExceptionMessage and select System.Exception as ReplaceExceptionTypeName.
10. This completes the configuration of the Exception Handling Application block for use in the code.
The developer of the Data Layer Code should write the code as follows:
• Add a reference to Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.dll.
• Import the namespace Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.
• Pass the Exception object and Policy Name as arguments to ExceptionPolicy.HandleException method.
• The return value specifies if the exception has to be rethrown.
The developer catches exceptions raised by the Data Access code and will apply the “Data Access Policy” before propogating the exception back to the calling Application/page. As defined by the “Data Access Policy”, the original exception will be logged and replaced with a user friendly exception.
The developer of the page will simply call the GetData method and catch & display the exceptions raised by the method.
Running the above code logs the actual error in the Event Log.
And the user sees a user-friendly message
The Exception Handling application block is a complement to the exception handling recovery code and is not a replacement for it. Any Exception Handling recovery code needed, has to be written in the Application Code.
8 Using the Security Application block
Using the Security Application block involves writing a Custom Authentication Provider.
1. Create a Class Library Project “Providers”. Add a class “AuthenticationProvider ” to the project. Implement the interfaces IConfigurationProvider, IauthenticationProvider for the class.
Provide the implementation from IConfigurationProvider methods:
Provide the implementation for Authenticate method of the IauthenticationProvider interface. This method contains the actual authentication code as required by the application.
Compile the code into a dll.
2. Now in the Enterprise Configuration Tool, right click on the Application and then click on New -> Security Application block.
3. Right click on the Authentication under Security Application Block and then click on New -> Custom Authentication Provider.
4. Rename the Custom Authentication Provider to “Voss Authentication Provider” and then click on the the ellipsis (…) on the type name button. In the Type Selector window that opens select the dll that has been built in the step 1.
5. Once the type has been selected, click on the Security Application block and select “VOSS Authentication Provider” as the DefaultAuthenticationInstance.
6. The Security Application block is now ready to be used in the application. The following code snippet shows how this can be done:
• Add a reference to Microsoft.Practices.EnterpriseLibrary.Security.dll.
• Import the namespace Microsoft.Practices.EnterpriseLibrary.Security.
• Use the AuthenticationFactory.GetAuthenticationProvider to get the default Authentication Provider.
• Use the Authenticate method on the provider to do the user name and password verification.
9 References
• Microsoft patterns & practices Home - http://msdn.microsoft.com/practices/
• Application blocks Guidance - http://msdn.microsoft.com/practices/guidetype/appblocks/
• Gotdotnet Workspace - http://www.gotdotnet.com/codegallery/codegallery.aspx?id=295a464a-6072-4e25-94e2-91be63527327
• Tom Hollander’s blog - http://blogs.msdn.com/tomholl/
No comments:
Post a Comment