1
votes

I have found other posts with similar problems, but thus far I haven't been able to solve my particular case.

If I put the log4net configuration in the app.config then all works fine, but I want it in a separate file.

I have looked at the following links, and have tried to implement some of the proposed solutions (but perhaps I didn't understand it correctly):

Similar SO question, but with web scenario

Apache documentation, 'Reading Files Directly' section

Tim Corey's log4net tutorial

So here is my Log4NetSettings.config file's content (wrapped in a configuration element):

<log4net>
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
  <bufferSize value="1" />
  <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  <connectionString value="" />
  <commandText value="INSERT INTO [Calculation Engine Log] ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" />
  <parameter>
    <parameterName value="@log_date" />
    <dbType value="DateTime" />
    <layout type="log4net.Layout.RawTimeStampLayout" />
  </parameter>
  <parameter>
    <parameterName value="@thread" />
    <dbType value="String" />
    <size value="255" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%thread" />
    </layout>
  </parameter>
  <parameter>
    <parameterName value="@log_level" />
    <dbType value="String" />
    <size value="50" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%level" />
    </layout>
  </parameter>
  <parameter>
    <parameterName value="@logger" />
    <dbType value="String" />
    <size value="255" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%logger" />
    </layout>
  </parameter>
  <parameter>
    <parameterName value="@message" />
    <dbType value="String" />
    <size value="4000" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%message" />
    </layout>
  </parameter>
  <parameter>
    <parameterName value="@exception" />
    <dbType value="String" />
    <size value="2000" />
    <layout type="log4net.Layout.ExceptionLayout" />
  </parameter>
</appender>


<root>
  <level value="INFO"/>
  <appender-ref ref="AdoNetAppender"/>
</root>
</log4net>

I change the connectionstring value during runtime.

Here is what I have in the app.config:

<configSections>
 <section name="log4net"  type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<appSettings>
 <add key="log4net.Config" value="Log4NetSettings.config" />
</appSettings>
<log4net configSource="Log4NetSettings.config" />

In the executable class I have this:

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

and then as soon as I can get hold of the connectionstring and configure it to the AdoNetAppender, I call:

 log.Info("Testing");

I also have:

private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

in the class with the assembly attribute and first logging call.

The Log4NetSettings.config file has its Build Action set to Content and its 'Copy to Output Directory' set to 'Copy Always'.

I have been pulling my hair out, and I don't know what I am doing wrong. Should I have Log4NetSettings.config as just a normal xml file? Should I put the assembly attribute in the AssemblyInfo.cs file? Should I rather call:

XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo(AppDomain.CurrentDomain.BaseDirectory + "Log4NetSettings.config"));

than have the assembly attribute?

It feels like I've tried so many different things, that perhaps I have mixed them up and gotten the wrong combination.

2
Did you try something like: log4net.Config.XmlConfigurator.Configure(new Uri(System.IO.Directory.GetCurrentDirectory() + @"\Config\LogConfig.xml"));o_weisman
I have tried something similar to your suggestion, but it seems it isn't working.Igavshne

2 Answers

1
votes

Yes, you should have the log4net config in an XML file. When you have log4net in a separate file, it's no longer related to the app.config so the configuration section is not required, and the config should not be wrapped in a configuration element. (It isn't necessary to have the assembly attribute in the AssemblyInfo.cs, and I note you have initialised the logging system in your startup code, which is required when using the assembly attribute technique)

Thus your log4net file will look like this:

<?xml version="1.0" encoding="utf-8" ?>
<log4net>  
    <!-- config .. -->

If you still have problems, log4net has diagnostic and debugging capability, see this question for how to enable it.

(Also, if you're using log4net 1.2.11 or later, you can set the connection string name in the log4net config, assuming it is in your app.config)

2
votes

Adding debug = "true" to the <log4net> tag (i.e. <log4net debug="true"> ) gives a lot of helpful information which may help to resolve.