Enterprise Library 5.0 - Logging to Database - The type LogWriter does not have an accessible constructor

Topics: Logging Application Block
Feb 9, 2013 at 11:54 PM
Edited Feb 9, 2013 at 11:55 PM
I'm trying to log messages to a database using Enterprise Library 5.0 but I'm running into couple of errors. I'm not sure if I'm missing anything here or doing something wrong. If anyone can help, I would really appreciate it. I'm in my 2nd day of trying to figure this out.

Sorry about the long post - I hope it helps others.

The Errors:
  • Activation error occurred while trying to get instance of type LogWriter, key \"\"
  • Resolution of the dependency failed, type = \"Microsoft.Practices.EnterpriseLibrary.Logging.LogWriter\", name = \"(none)........
  • The type LogWriter does not have an accessible constructor.
Please note the following:
  1. I'm using .NET 4.5 VS2012
  2. My config file passed all validations in Enterprise Library Configuration tool
  3. I named my logging database "EntLibLogDb" instead of the default called "Logging"
  4. I have executed the SQL command to create the necessary Enterprise Library stored procedures, etc. in the EntLibLogDb database
  5. My Enterprise Library config file is stored in C:\config folder since it's being used across multiple projects in my Visual Studio solution
  6. All EnterpriseLibrary.* references have their Copy Local attribute set to True
My Visual Studio References:
  • Microsoft.Practices.EnterpriseLibrary.Common
  • Microsoft.Practices.EnterpriseLibrary.Data
  • Microsoft.Practices.EnterpriseLibrary.Logging
  • Microsoft.Practices.EnterpriseLibrary.Logging.Database
  • Microsoft.Practices.ServiceLocation
  • Microsoft.Practices.Unity
  • Microsoft.Practices.Unity.Configuration
  • Microsoft.Practices.Unity.Interception
  • Microsoft.Practices.Unity.Interception.Configuration
Content of my App.config file:
<configuration>
  <configSections>
    <section name="enterpriseLibrary.ConfigurationSource" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ConfigurationSourceSection, Microsoft.Practices.EnterpriseLibrary.Common, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
  </configSections>
  <enterpriseLibrary.ConfigurationSource selectedSource="File Configuration Source"
      parentSource="">
    <sources>
      <add name="File Configuration Source" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.FileConfigurationSource, Microsoft.Practices.EnterpriseLibrary.Common, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
          filePath="c:\config\entlib.config" />
    </sources>
  </enterpriseLibrary.ConfigurationSource>
</configuration>
Content of Enterprise Library Config File (entlib.config):
<configuration>
  <configSections>
    <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
    <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>
  <dataConfiguration defaultDatabase="EntLibLogDb" />
  <connectionStrings>
    <add name="EntLibLogDb" connectionString="Initial Catalog=EntLibLogDb;Data Source=MyServer;User=XXX;Password=XXX;IntegratedSecurity=SSPI;"
        providerName="System.Data.SqlClient" />
  </connectionStrings>
  <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=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
          listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Database.Configuration.FormattedDatabaseTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging.Database, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
          databaseInstanceName="EntLibLogDb" writeLogStoredProcName="WriteLog"
          addCategoryStoredProcName="AddCategory" traceOutputOptions="LogicalOperationStack, DateTime, Timestamp, ProcessId, ThreadId, Callstack" />
    </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}&#xA;Message: {message}{newline}&#xA;Category: {category}{newline}&#xA;Priority: {priority}{newline}&#xA;EventId: {eventid}{newline}&#xA;Severity: {severity}{newline}&#xA;Title:{title}{newline}&#xA;Machine: {localMachine}{newline}&#xA;App Domain: {localAppDomain}{newline}&#xA;ProcessId: {localProcessId}{newline}&#xA;Process Name: {localProcessName}{newline}&#xA;Thread Name: {threadName}{newline}&#xA;Win32 ThreadId:{win32ThreadId}{newline}&#xA;Extended Properties: {dictionary({key} - {value}{newline})}"
          name="Text Formatter" />
    </formatters>
    <logFilters>
      <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Filters.LogEnabledFilter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
          enabled="true" name="Logging Enabled Filter" />
    </logFilters>
    <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 &amp; Warnings">
        <listeners>
          <add name="Database Trace Listener" />
        </listeners>
      </errors>
    </specialSources>
  </loggingConfiguration>
</configuration>
My Connection String:
<connectionStrings>
    <add name="EntLibLogDb" connectionString="Initial Catalog=EntLibLogDb;Data Source=MyServer;User=XXX;Password=XXX;IntegratedSecurity=SSPI;"
        providerName="System.Data.SqlClient" />
</connectionStrings>
I also tried using Database in place of Initial Catalog and Server in place of Data Source and it didn't make a difference.

My C# Code:
var logEntry = new LogEntry { Message = "My first EntLib log message" };
logEntry.Categories.Add("General");
var logger = EnterpriseLibraryContainer.Current.GetInstance<LogWriter>();
logger.Write(logEntry);
I also tried the following:
var logEntry = new LogEntry { Message = "My first EntLib log message" };
logEntry.Categories.Add("General");
Logger.Write(logEntry);
Basically, I'd like to log all errors/warnings/info in my EntLibLogDb database. I'm not sure if the problem is my code or configuration.

Thanks for your help!
Bobby Pejman
Feb 10, 2013 at 12:57 AM
Thanks for posting such a thorough question!

I took all of the code and configuration you posted and created a console application in VS2012 targeting .NET 4.5. The only changes were that I changed the database connection information. The sample application runs fine.

The exception you are seeing usually indicates that there is an issue with configuration.

What type of application are you working with? Since you've already answered most of the questions that I would ask it might be easier to create a sample application that recreates the issue.

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Feb 10, 2013 at 1:22 AM
Edited Feb 10, 2013 at 1:22 AM
Hi Randy,

Thank you for such a quick response!

I am building an MVC application with two projects in my solution. The first project is a class library and the second is the website. I am trying the logging code in the class library. Both projects have the Enterprise Library references but my web project is not referencing the entlib.config file. Only the class library is through the app.config.

Bobby Pejman
Feb 10, 2013 at 1:30 AM
Edited Feb 10, 2013 at 1:31 AM
OK, that helps. The configuration needs to go in the web.config of the MVC project instead of the app.config of the Class Library. If you do that then you should be OK.

Also, just be aware that in Enterprise Library 5.0.414.0 there is a bug with FileConfigurationSource resolving relative paths. You should be OK since you are using an absolute path but just a heads up in case you decide to change. This issue was fixed in Enterprise Library 5.0 Optional Update 1.

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Feb 10, 2013 at 7:06 AM
Edited Feb 10, 2013 at 7:07 AM
Awesome! It's working and I'm able to see logs in my database. Thanks for your help, Randy! Also, thanks for the relative path bug information.

Here's what I had to do in addition to what I posted earlier to get this working:

Before all of this started, I downloaded and installed the Enterprise Library MSI which installed all the necessary DLLs under C:\Program Files (x86)\Microsoft Enterprise Library 5.0\Bin directory. Then I went in Visual Studio and added the references to my projects using NuGet. However, NuGet creates references to the DLLs that are under the packages folder in the root directory of the project. This resulted in a manifest error during compilation.

I had to uninstall all Enterprise Library DLLs through NuGet to remove all references from my projects and then I added each DLL under C:\Program Files (x86)\Microsoft Enterprise Library 5.0\Bin manually to my projects. This resolved the manifest issue for me.

Finally, I ended up removing IntegratedSecurity=SSPI; from my connection string. This was preventing the application from connecting to the database. Once I removed it, I was able to see the logs in the database. Also, I changed User to User Id.

New Connection String:
<connectionStrings>
    <add name="EntLibLogDb" connectionString="Initial Catalog=EntLibLogDb;Data Source=MyServer;User Id=XXX;Password=XXX;"
        providerName="System.Data.SqlClient" />
</connectionStrings>
Bobby Pejman
Feb 10, 2013 at 7:25 AM
Edited Feb 10, 2013 at 7:14 PM
Good to hear you got it working and thanks for posting your solutions -- it could help someone else in the future. Also, a good article (for version 3 but still mostly applicable) about assembly mismatches is Avoiding configuration pitfalls with incompatible copies of Enterprise Library.

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to