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
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.
log4net.Config.XmlConfigurator.Configure(new Uri(System.IO.Directory.GetCurrentDirectory() + @"\Config\LogConfig.xml"));
– o_weisman