0

I have log4net configured to write to a database. My log config looks something like this:

<?xml version="1.0" encoding="utf-8" ?>
<log4net>
  <root>
    <appender-ref ref="SqlAppenderAll" />
    <level value="DEBUG" />
  </root>
  <appender name="SqlAppenderAll" type="log4net.Appender.ADONetAppender">
    <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    <connectionStringName value="MyConnectionString" />

    ...
  </appender>
</log4net>

The problem is, MyConnectionString is not available immediately. A number of configuration items for the service are stored in a config database, and retrieved when the service starts. This allows the connection strings to be configured once for the entire system, rather than at each service individually.

So when the service starts, it does something like this:

var myConnectionString = ConfigProvider.GetConnectionString("MyConnectionString");
AddConnectionString(myConnectionString, "web.config");

This causes log4net to ignore the sql appender because the connection string isn't available when it initializes.

log4net:ERROR [AdoNetAppender] ErrorCode: GenericFailure. Could not open database connection []. Connection string context [Unable to determine connection string context.].
log4net.Core.LogException: Unable to find [MyConnectionString] ConfigurationManager.ConnectionStrings item
    at log4net.Appender.AdoNetAppender.ResolveConnectionString(String& connectionStringContext)
    at log4net.Appender.AdoNetAppender.InitializeDatabaseConnection()

Any subsequent calls to log.Info/Debug/etc never get written.

Is there a way to make log4net retry the connection after adding the connection string to the web.config. Alternatively, is there a way to postpone the log4net init process?

ConditionRacer
  • 4,418
  • 6
  • 45
  • 67

1 Answers1

3

I have used this in our assemblyinfo.cs

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log.config", Watch = true)] 

and also for AZURE I would call

XmlConfigurator.Configure(<PathToYourConfigFile>);

Have you looked at this post

and if that does not work you could try

 public static void SetAdoNetAppenderConnectionStrings(string connectionStringKey)
 {
   var hier = (Hierarchy)LogManager.GetRepository();
   if (hier != null)
   {
     var appenders = hier.GetAppenders().OfType<ADONetAppender>();
     foreach (var appender in appenders)
     {
       appender.ConnectionString = ConfigurationManager.ConnectionStrings[connectionStringKey].ConnectionString;
       appender.ActivateOptions();
     }
   }
 }
Community
  • 1
  • 1
Craig Selbert
  • 737
  • 1
  • 8
  • 17
  • The logging is configured this way, with watch = true. The problem is the change is not happening in the logging file, it's in the web.config (and even then, only in memory, not the actual file). The logging file only references the connection string by name. So when the connection string gets added, it doesn't seem to be picked up by log4net. – ConditionRacer Feb 15 '17 at 18:36
  • @ConditionRacer - Check out the update and see if that would now work. – Craig Selbert Feb 15 '17 at 18:46
  • Works! Thanks a lot – ConditionRacer Feb 15 '17 at 18:52