How to configure Enterpise Library 6.0 logging to database? - c#

In my App.config I have a second things:
<configSections>
<section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
<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>
<dataConfiguration defaultDatabase="Core" />
<loggingConfiguration name="" tracingEnabled="true" defaultCategory="General">
<listeners>
<add name="Database Trace Listener"
type="Microsoft.Practices.EnterpriseLibrary.Logging.Database.FormattedDatabaseTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging.Database, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Database.Configuration.FormattedDatabaseTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging.Database, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
databaseInstanceName="Core"
writeLogStoredProcName="WriteLog"
addCategoryStoredProcName="AddCategory" />
<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="rolling.log"
formatter="Text Formatter"
rollInterval="Hour"
rollSizeKB="10000"
traceOutputOptions="DateTime, Callstack" />
</listeners>
<formatters>
<add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
template="Application: {property(ApplicationName)}{newline}
Guid: {property(HandlingInstanceId)}{newline}
Timestamp: {timestamp}{newline}
Message: {message}{newline}
Exception type: {property(ExceptionType)}{newline}
Category: {category}{newline}
Severity: {severity}{newline}
Machine: {localMachine}{newline}
App Domain: {localAppDomain}{newline}
ProcessId: {localProcessId}{newline}
Process Name: {localProcessName}{newline}
Stack trace: {property(StackTrace)}{newline}
File: {property(FileName)}{newline}
Line: {property(LineNumber)}{newline}"
name="Text Formatter" />
</formatters>
<categorySources>
<add switchValue="All" name="General">
<listeners>
<add name="Database Trace Listener" />
<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 & Warnings">
<listeners>
<add name="Database Trace Listener" />
<add name="Rolling Flat File Trace Listener" />
</listeners>
</errors>
</specialSources>
</loggingConfiguration>
I also added this part into initialisation:
DatabaseFactory.SetDatabaseProviderFactory(new DatabaseProviderFactory());
LogWriterFactory logWriterFactory = new LogWriterFactory();
And, Exception write:
private static void LogExceptionDetails(Exception ex)
{
LogEntry logEntry = new LogEntry
{
Message = ex.Message
};
Logger.Write(logEntry);
}
The thing I cant get so far is, how I suppose to detect, in which table exception will be logged.
I mean, to make Enterprise see Core, I need to add:
<connectionStrings>
<add name="Core" connectionString="blablabla" />
</connectionStrings>
But this still doest explain how to select propher table and format it (the only way I know is creating procedure and putting it in writeLogStoredProcName= but I used this in 4.1, I never touched 6.0 before).
Also, the problem is that all my confirugations are stored in another database, and this is the reason why I want to get rid of connectionString from App.config).
So, to summarize, my question is:
Is there a way to set database, table and table columns outside the App.config (and procedure) for Enterprise Library Logging to database? Maybe it is done somewhere in DatabaseFactory?
P.S Local logging into rolling.log file works fine.
EDIT: Looks like I have no choise and I need to use procedure to write in needed table. Still trying to find a way to set connectionstring outside the App.config

As you found out the out of the box FormattedDatabaseTraceListener writes to the database using a stored procedure. You can configure the name of the stored procedure but a stored procedure contains the database specific logic. You can modify or create a new stored procedure to do whatever you want as long as it conforms to the stored procedure interfaces:
CREATE PROCEDURE [dbo].[WriteLog]
(
#EventID int,
#Priority int,
#Severity nvarchar(32),
#Title nvarchar(256),
#Timestamp datetime,
#MachineName nvarchar(32),
#AppDomainName nvarchar(512),
#ProcessID nvarchar(256),
#ProcessName nvarchar(512),
#ThreadName nvarchar(512),
#Win32ThreadId nvarchar(128),
#Message nvarchar(1500),
#FormattedMessage ntext,
#LogId int OUTPUT
)
CREATE PROCEDURE [dbo].[AddCategory]
#CategoryName nvarchar(64),
#LogID int
The other alternative is to create a custom trace listener to do exactly what you want.
In terms of placing the connectionStrings in an external configuration file you can use the built-in .NET configSource attribute:
<connectionStrings configSource="connections.config" />
Or the Enterprise Library redirectSections:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="enterpriseLibrary.ConfigurationSource" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ConfigurationSourceSection, Microsoft.Practices.EnterpriseLibrary.Common, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
</configSections>
<enterpriseLibrary.ConfigurationSource selectedSource="System Configuration Source">
<sources>
<add name="System Configuration Source" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.SystemConfigurationSource, Microsoft.Practices.EnterpriseLibrary.Common, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="File-based Configuration Source" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.FileConfigurationSource, Microsoft.Practices.EnterpriseLibrary.Common, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
filePath="data.config" />
</sources>
<redirectSections>
<add sourceName="File-based Configuration Source" name="dataConfiguration" />
<add sourceName="File-based Configuration Source" name="connectionStrings" />
</redirectSections>
</enterpriseLibrary.ConfigurationSource>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
If you want to be completely app.config "independent" then you can place all configuration in an external configuration file and then load that configuration programmatically using a FileConfigurationSource.
See my answer to EnterpriseLibrary Data Access Application Block redirect Section can't find default database
for more details.
If you want to mix and match declarative XML logging configuration with runtime programmatic database configuration then you can do it using something similar to:
class Program
{
static void Main(string[] args)
{
// Configure databases from some external source but ensure that
// database name matches XML config
DatabaseFactory.SetDatabases(
() => CreateDatabaseFromExternalSource(null),
name => CreateDatabaseFromExternalSource(name));
// Configure logging from XML config
LogWriterFactory factory = new LogWriterFactory();
Logger.SetLogWriter(factory.Create());
Logger.Write("Test", "General");
}
private static Database CreateDatabaseFromExternalSource(string name)
{
// SqlDatabase assumes SQL Server database
return new SqlDatabase(GetConnectionString(name));
}
private static string GetConnectionString(string name)
{
// do whatever you need to get the database connection
return #"Server=.\SQLEXPRESS;Database=myDataBase;User Id=myUsername;Password=myPassword;";
}
}

Related

Migrate Enterprise Library 5 to 6

Trying to move from Enterprise Library 5.0 to 6.0, I ran into some troubles. Maybe this will help others.
Following configuration is an example for (silent) exception logging to database:
<configSections>
<section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging" requirePermission="true" />
<section name="exceptionHandling" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling" requirePermission="true" />
</configSections>
<loggingConfiguration name="" tracingEnabled="true" defaultCategory="General">
<listeners>
<add name="Database Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.Database.FormattedDatabaseTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging.Database"
listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Database.Configuration.FormattedDatabaseTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging.Database"
databaseInstanceName="LogContext" writeLogStoredProcName="WriteLog"
addCategoryStoredProcName="AddCategory" formatter="Text Formatter" />
</listeners>
<formatters>
<add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging"
template="Timestamp: {timestamp}{newline}..."
name="Text Formatter" />
</formatters>
<categorySources>
<add switchValue="All" name="Exception">
<listeners>
<add name="Database Trace Listener" />
</listeners>
</add>
</categorySources>
</loggingConfiguration>
<exceptionHandling>
<exceptionPolicies>
<add name="UiPolicy">
<exceptionTypes>
<add name="All Exceptions" type="System.Exception, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
postHandlingAction="None">
<exceptionHandlers>
<add name="Logging Exception Handler" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging"
logCategory="Exception" eventId="100" severity="Error" title="Enterprise Library Exception Handling"
formatterType="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.TextExceptionFormatter, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling"
priority="0" />
</exceptionHandlers>
</add>
</exceptionTypes>
</add>
</exceptionPolicies>
</exceptionHandling>
I'm using following assemblies with version 5.0.414.0:
Microsoft.Practices.EnterpriseLibrary.ExceptionHandling
Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging
Microsoft.Practices.EnterpriseLibrary.Logging
Microsoft.Practices.EnterpriseLibrary.Logging.Database
With Enterprise Library 5.0 using all this within a asp.net MVC app is as easy as:
// ...
catch (Exception ex)
{
if (ExceptionPolicy.HandleException(ex, "UiPolicy")) throw;
// do something else
}
After upgrading the assemblies to Enterprise Library 6.0, I get following exception message:
Must set an ExceptionManager in the ExceptionPolicy class using the SetExceptionManager method.
So, what to do?
Step by Step
To get rid of this exception (credit to Randy's answer), one has to go with ExceptionManager, in my case via factory. I use this in global.asax' Application_Start() method:
protected void Application_Start()
{
IConfigurationSource source = ConfigurationSourceFactory.Create();
var exceptionPolicyFactory = new ExceptionPolicyFactory(source);
var exceptionManager = exceptionPolicyFactory.CreateManager();
ExceptionPolicy.SetExceptionManager(exceptionManager);
}
But with my handling and logging settings this was only half way. I now got the following exception at exceptionPolicyFactory.CreateManager()
The LogWriter has not been set for the Logger static class. Set it invoking the Logger.SetLogWriter method.
For this to go away I added
var logwriterFactory = new LogWriterFactory(source);
var logWriter = logwriterFactory.Create();
Logger.SetLogWriter(logWriter);
Now it said
Database provider factory not set for the static DatabaseFactory. Set a provider factory invoking the DatabaseFactory.SetProviderFactory method or by specifying custom mappings by calling the DatabaseFactory.SetDatabases method.
on logwriterFactory.Create(). So there was one more thing to add:
DatabaseFactory.SetDatabaseProviderFactory(new DatabaseProviderFactory(source));
Complete Solution
All together my Application_Start() now is
protected void Application_Start()
{
IConfigurationSource source = ConfigurationSourceFactory.Create();
DatabaseFactory.SetDatabaseProviderFactory(new DatabaseProviderFactory(source));
var logwriterFactory = new LogWriterFactory(source);
var logWriter = logwriterFactory.Create();
Logger.SetLogWriter(logWriter);
var exceptionPolicyFactory = new ExceptionPolicyFactory(source);
var exceptionManager = exceptionPolicyFactory.CreateManager();
ExceptionPolicy.SetExceptionManager(exceptionManager);
}
while the configuration and the actual exception handling code stays the same:
ExceptionPolicy.HandleException(exceptionToHandle, "UiPolicy");

Enterprise Library Logging isn't log on SQL

I'm using EntLib 6 in order to log one webapp.
Because I'm using n-layers, I wanted to put the logging in one library, accessible from all layers.
I'm trying to run the logging but nothing happends, all the code is running, no exception but nothing appears in DB.
So this is what I've done:
I've created DB with script provided in EntLib6 into the DB that is beneath DB_BELVAL Connexion string, I put this c# test code in the portable class that will handle logging:
public static void LogToDatabase()
{
try
{
//Bootstrapping logging
DatabaseFactory.SetDatabaseProviderFactory(new DatabaseProviderFactory());
IConfigurationSource configurationSource = ConfigurationSourceFactory.Create();
LogWriterFactory logWriterFactory = new LogWriterFactory(configurationSource);
Logger.SetLogWriter(logWriterFactory.Create());
if (Logger.IsLoggingEnabled())
{
LogEntry log = GetLogEntry();
log.Categories.Add("General"); // name of Categorie in EntLib Config editor
log.Priority = 5;
log.Severity = System.Diagnostics.TraceEventType.Information;
log.Message = "Hello dude, from AMLogger";
Logger.Write(log);
}
}
catch (Exception ex)
{
}
}
private static LogEntry GetLogEntry()
{
LogEntry log = new LogEntry();
log.TimeStamp = DateTime.Now;
log.Title = "TANOLIS";
log.Priority = 5; // default priority
log.Severity = System.Diagnostics.TraceEventType.Verbose; // default severity
log.MachineName = "MachineName";//HttpContext.Current.Server.MachineName;
log.ProcessId = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
return log;
}
And from the UnitTest, I call the LogToDatabase() method of the portable library.
I configured the config file of the Unit test as that:
or the xml:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<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" />
<section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
</configSections>
<loggingConfiguration name="" tracingEnabled="true" defaultCategory="General">
<listeners>
<add name="Database Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.Database.FormattedDatabaseTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging.Database, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Database.Configuration.FormattedDatabaseTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging.Database, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
databaseInstanceName="DB_Belval" writeLogStoredProcName="WriteLog"
addCategoryStoredProcName="General" formatter="Text Formatter" />
</listeners>
<formatters>
<add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
template="Timestamp: {timestamp}{newline}
Message: {message}{newline}
Category: {category}{newline}
Priority: {priority}{newline}
EventId: {eventid}{newline}
Severity: {severity}{newline}
Title:{title}{newline}
Machine: {localMachine}{newline}
App Domain: {localAppDomain}{newline}
ProcessId: {localProcessId}{newline}
Process Name: {localProcessName}{newline}
Thread Name: {threadName}{newline}
Win32 ThreadId:{win32ThreadId}{newline}
Extended Properties: {dictionary({key} - {value}{newline})}"
name="Text Formatter" />
</formatters>
<categorySources>
<add switchValue="All" name="General">
<listeners>
<add name="Database Trace Listener" />
</listeners>
</add>
</categorySources>
<specialSources>
<allEvents switchValue="All" name="All Events">
<listeners>
<add name="Database Trace Listener" />
</listeners>
</allEvents>
<notProcessed switchValue="All" name="Unprocessed Category">
<listeners>
<add name="Database Trace Listener" />
</listeners>
</notProcessed>
<errors switchValue="All" name="Logging Errors & Warnings">
<listeners>
<add name="Database Trace Listener" />
</listeners>
</errors>
</specialSources>
</loggingConfiguration>
<dataConfiguration defaultDatabase="DB_Belval" />
<connectionStrings>
<add name="DB_Belval" connectionString="Data Source=serverIP;Initial Catalog=APP_Dev;Persist Security Info=True;User=login;Password=password"
providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
Indeed, nothing happends, but I breakpointed the UnitTest and all looks right, no exception.
Thanks to help me
**EDIT 1 : **: logWriterFactory looks like it has loaded the XML:
EDIT 2 : I've edited the stored procedure [dbo].[WriteLog] in order to make a kind of flag (one INSERT INTO [dbo].[TestLog]) to know if stored proc is called and it looks that app doesn't call the stored proc:
ALTER PROCEDURE [dbo].[WriteLog]
(
#EventID int,
#Priority int,
#Severity nvarchar(32),
#Title nvarchar(256),
#Timestamp datetime,
#MachineName nvarchar(32),
#AppDomainName nvarchar(512),
#ProcessID nvarchar(256),
#ProcessName nvarchar(512),
#ThreadName nvarchar(512),
#Win32ThreadId nvarchar(128),
#Message nvarchar(1500),
#FormattedMessage ntext,
#LogId int OUTPUT
)
AS
INSERT INTO [dbo].[TestLog]
([text]) VALUES ('Storeproc1')
INSERT INTO [dbo].[Log] (
EventID,
Priority,
Severity,
Title,
[Timestamp],
MachineName,
AppDomainName,
ProcessID,
ProcessName,
ThreadName,
Win32ThreadId,
Message,
FormattedMessage
)
VALUES (
#EventID,
#Priority,
#Severity,
#Title,
#Timestamp,
#MachineName,
#AppDomainName,
#ProcessID,
#ProcessName,
#ThreadName,
#Win32ThreadId,
#Message,
#FormattedMessage)
SET #LogID = ##IDENTITY
RETURN #LogID
And there is no new lines in [dbo].[TestLog] when I launch the UnitTest so the issue seems to be in C#
Looks like you already spent some time tearing your hair out. My 2 cents would be to gather as much debug info as you can. I don't have any prior experience with EL.
Here are my tips;
I would advise you to monitor ALL transacitons/requests on the target database. To do so, just open the SQL Profiler from SSMS and run it without any filter other than the Database Name (or on your entire server). By the way, is it a local or remote DB?
If remote, filter on your username to avoid nose from other developers/users.
Check if there is no missing DLL or loading exceptions thrown by EL. Use Fusion Log. I can provide you with info about how to use it if needed.
Run the Fuslogvw.exe utility from MS SDK tools (C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6 Tools), take the highest version.
Run as admin to edit the settings of Fusion (set Custom Log Path to "C:\Fuslog")
Create the directory "C:\Fuslog" (must exist in order to enable the logging).
DISABLE fusion once you have finished.
From the Exceptions window of Visual Studio, disable "Enable Just My Code", enable "break when exception cross appdomain or..." (the last one is not really relevant in your case, we never know).
You can also enable ".NET Framework Source Stepping" but it will need some time to download the symbols.
If you go for this one, make sure the symbols are loaded corretcly for EL by displaying the Symbols Window.
More over here: http://blogs.msdn.com/b/saraford/archive/2008/08/26/did-you-know-how-to-load-symbols-from-the-modules-window-299.aspx
Keep us posted!

How to add RollingFlatFileTraceListenerData programmatically

I have a config file like:
<configSections>
<section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</configSections>
<loggingConfiguration name="Logging Application Block" tracingEnabled="true" defaultCategory="Tracing" logWarningsWhenNoCategoriesMatch="true">
<listeners>
<add listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.SystemDiagnosticsTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" type="System.Diagnostics.ConsoleTraceListener, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" name="System Diagnostics Trace Listener"/>
</listeners>
<formatters>
<add template="{message}" type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="Text Formatter"/>
</formatters>
<categorySources>
<add switchValue="All" name="AppLog">
<listeners>
<add name="System Diagnostics Trace Listener"/>
</listeners>
</add>
</categorySources>
<specialSources>
<allEvents switchValue="All" name="All Events"/>
<notProcessed switchValue="All" name="Unprocessed Category"/>
<errors switchValue="Off" name="Logging Errors & Warnings"/>
</specialSources>
Besides the console listener that I have, I want to define a RollingFlatFileTraceListenerData programmatically:
var listener = new RollingFlatFileTraceListenerData("AppLog", #"c:\log.log", "", "", 0, "yyyyMMdd-hhmm", Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollFileExistsBehavior.Increment, Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollInterval.Hour, TraceOptions.LogicalOperationStack, "Text Formatter");
How can I add my newly defined listener to the list of listeners programmatically?
In general, in asp.net apps, a simple way to programmatically add TraceListeners is with the diagnostics' Trace.Listeners.Add() method. I like to do this in my global.asax.cs on Application_Start():
using D = System.Diagnostics;
...
protected void Application_Start()
{
if (D.Trace.Listeners["MyTraceListener"] == null)
{
D.Trace.Listeners.Add(new MyTraceListener("") { Name = "MyTraceListener" });
}
...
}
The only reason I check if it's already in place is because I've seen Application_Start() fire more than once, albeit infrequently.

where enterprise library 4.1 logger, logs?

I have done its configurations using configuration wizard but I couldn't understand where it is logging messages. I even see app.config file but couldn't find any logging source.
Please guide me where it does logs and how I can check that log.
Here is my config file:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</configSections>
<loggingConfiguration name="Logging Application Block" tracingEnabled="true"
defaultCategory="General" logWarningsWhenNoCategoriesMatch="true">
<listeners>
<add fileName="C:\Users\Administrator\Desktop\EAMS\trace.log"
header="----------------------------------------" footer="----------------------------------------"
formatter="" listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
traceOutputOptions="LogicalOperationStack" filter="All" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="FlatFile TraceListener" />
<add source="Enterprise Library Logging" formatter="Text Formatter"
log="Application" machineName="" listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
traceOutputOptions="LogicalOperationStack" filter="All" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FormattedEventLogTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="Formatted EventLog TraceListener" />
</listeners>
<formatters>
<add template="Timestamp: {timestamp}
Message: {message}
Category: {category}
Priority: {priority}
EventId: {eventid}
Severity: {severity}
Title:{title}
Machine: {machine}
Application Domain: {appDomain}
Process Id: {processId}
Process Name: {processName}
Win32 Thread Id: {win32ThreadId}
Thread Name: {threadName}
Extended Properties: {dictionary({key} - {value}
)}"
type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="Text Formatter" />
</formatters>
<categorySources>
<add switchValue="All" name="General">
<listeners>
<add name="Formatted EventLog TraceListener" />
</listeners>
</add>
</categorySources>
<specialSources>
<allEvents switchValue="All" name="All Events" />
<notProcessed switchValue="All" name="Unprocessed Category" />
<errors switchValue="All" name="Logging Errors & Warnings">
<listeners>
<add name="Formatted EventLog TraceListener" />
</listeners>
</errors>
</specialSources>
</loggingConfiguration>
<connectionStrings>
<add name="ConnectionString" connectionString="Data Source=YAWARLAPTOP;Initial Catalog=EAMS;Integrated Security=true"
providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
You need to configure one or more Trace Listeners. Also see Configuration Overview
Edit 1
Thank you for an example of you config file. You are logging your messages into Application Event Log. Please open this Event Log as you normally do and you'll be able to see your messages in there.
Edit 2
In your original question you asked where the messages are logged. This answer has been provided to you. When you write a question, it's better to specify upfront, what are you trying to achieve. To log into a flat file, after you configured a flat file listener you need to add reference to this listener to your sources. See how it's done with the Event Log trace listener in your example and follow the same pattern.
This is correct.
Authentication has been added to the email tracelistener in v5.0.
If you must use v4.1, there's a version of the email tracelistener with authentication on EntLibContrib.

Activation error occured while trying to get instance of type LogWriter

I am trying to using the Logging Application block of Enterprise Library 5.0 to log simple message to the Windows event log on Win XP SP3 system using:
Logger.Write(msg);
I get the "Activation error occured while trying to get instance of type LogWriter" error message when trying to log.
Shown below is the config file used with MS Enterprise library
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
</configSections>
<loggingConfiguration name="" tracingEnabled="true" defaultCategory="General">
<listeners>
<add name="Event Log Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FormattedEventLogTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
source="Enterprise Library Logging" formatter="Text Formatter"
log="Application" machineName="." traceOutputOptions="None" />
</listeners>
<formatters>
<add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
template="Timestamp: {timestamp}{newline}
Message: {message}{newline}
Category: {category}{newline}
Priority: {priority}{newline}
EventId: {eventid}{newline}
Severity: {severity}{newline}
Title:{title}{newline}
Machine: {localMachine}{newline}
App Domain: {localAppDomain}{newline}
ProcessId: {localProcessId}{newline}
Process Name: {localProcessName}{newline}
Thread Name: {threadName}{newline}
Win32 ThreadId:{win32ThreadId}{newline}
Extended Properties: {dictionary({key} - {value}{newline})}"
name="Text Formatter" />
</formatters>
<categorySources>
<add switchValue="All" name="General">
<listeners>
<add name="Event Log Listener" />
</listeners>
</add>
</categorySources>
<specialSources>
<allEvents switchValue="All" name="All Events" />
<notProcessed switchValue="All" name="Unprocessed Category" />
<errors switchValue="All" name="Logging Errors & Warnings">
<listeners>
<add name="Event Log Listener" />
</listeners>
</errors>
</specialSources>
</loggingConfiguration>
</configuration>
I just wanted to add this error may be caused by another configuration issue. Make sure to look at the inner exceptions for this error. In my case it was:
"The type Database cannot be constructed. You must configure the container to supply this value."
To resolve this I had to add a providerName to my database connection string in the web.config. So the final connection string node looked like this:
<add name="DBConn" connectionString="Data Source=ServerName;Initial Catalog=Logging;Persist Security Info=True;integrated security=True;" providerName="System.Data.SqlClient" />
I realized that I was trying to use Config file from within a DLL which does not work. I should be using FileConfigurationSource instead.
If I use the same App.Config from an application, it worked fine.
Reading the other answers to this question, and from my own experiences, in general it seems this error occurs when your application cannot read some required configuration for the Logging application block from a config file.
To add to the scenarios mentioned in previous answers, I've come across this error a couple of times:
1) In a unit test project, where I forgot to add an app.config file at all;
2) In a config file where I deleted a particular listener from the loggingConfiguration section but forgot to remove the name of the listener from the categorySource that referenced it.
It is missing DLL; pay attension when you place your DLL's at GAC you may need to add more DLL's to GAC . Common, Data, Logging, Logging.Database and ServiceLocation DLLS make sure they reside together in one directory
I've also seen this error when forgetting to add a reference to the EntLib DLL's.
I've had the same error when using a separate entlib config file.
In Web.config, enterpriseLibrary.ConfigurationSource pointed to EntLib.config. When I used the EnterpriseLibrary.Config tool to edit EntLib.config to set up the logging database details, it put everything in EntLib.config. I got this error until I moved the connetionStrings section to Web.config.
Additionally to examples of
Simon Tewsi
 I want to add my example, when logging configuration was located in a separate file but section descriptions were missed in app.config
   
<section name ="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging" />  
 <loggingConfiguration configSource="EnterpriseLibraryLogging.config" />

Categories