问题
My solution contains a Windows Service application project and a Unit Test project, as shown here:
-------------------Windows Service application project Setup--------------------
I've setup log4net in my Windows Service application project, as shown below:
Step 1) I've added the reference to log4net to my Windows Service application project.
Step 2) My app.config looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,Log4net"/>
</configSections>
<log4net>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="log.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="5" />
<maximumFileSize value="100KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %level %logger - %message %exception%newline" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="LogFileAppender" />
</root>
</log4net>
</configuration>
Step 3) I've added this the Program.cs main:
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
namespace MyAppService
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
log4net.Config.XmlConfigurator.Configure();
Step 4) In my classes where I am logging I've added this:
private static ILog logger = LogManager.GetLogger(typeof(Reader));
Step 5) I've added logging statements like this:
logger.Info("Data Read Completed Successfully.");
-----------------------------Unit Test project Setup----------------------------
I've setup log4net in my Unit Test project, as shown here:
Step 1) I've added the reference to log4net to my Unit Test project.
Step 2) I've added a app.config file that looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
</configSections>
<log4net>
<!-- A1 is set to be a ConsoleAppender -->
<appender name="A1" type="log4net.Appender.FileAppender">
<file value="logfile.txt" />
<appendToFile value="false" />
<!-- A1 uses PatternLayout -->
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-4timestamp [%thread] %-5level %logger %ndc - %message%newline" />
</layout>
</appender>
<!-- Set root logger level to DEBUG and its only appender to A1 -->
<root>
<level value="DEBUG" />
<appender-ref ref="A1" />
</root>
</log4net>
</configuration>
Step 3) I've added this the ForecastIOTest.cs unit test class:
using log4net;
using log4net.Config;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using WeatherAppService;
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
namespace WeatherAppTests
{
[TestClass]
public class ForecastIOTest
{
private static ILog logger = LogManager.GetLogger(typeof(WeatherController));
[AssemblyInitialize]
public static void Configure(TestContext tc)
{
log4net.Config.XmlConfigurator.Configure();
}
Step 4) In my test class where I am logging I've added this:
private static ILog logger = LogManager.GetLogger(typeof(ForecastIOTest));
Step 5) I've added logging statements like this:
logger.Info("This is a test.");
-------------------------------------Problem------------------------------------
Now, the error that I receive indicates that I have more than one configSections element: One in the Service app and another in the test app.
log4net:ERROR Exception while reading ConfigurationSettings. Check your .config file is well formed XML.
System.Configuration.ConfigurationErrorsException: Configuration system failed to initialize ---> System.Configuration.ConfigurationErrorsException: Only one <configSections> element allowed per config file and if present must be the first child of the root <configuration> element. (C:\Users\pdl\Documents\Visual Studio 2013\Projects\WeatherAppService\WeatherAppTests\bin\Debug\WeatherAppTests.dll.config line 9)
But if I remove the the configSections from the test app, I receive this error:
log4net:ERROR Exception while reading ConfigurationSettings. Check your .config file is well formed XML.
System.Configuration.ConfigurationErrorsException: Configuration system failed to initialize ---> System.Configuration.ConfigurationErrorsException: Unrecognized configuration section log4net. (C:\Users\pdl\Documents\Visual Studio 2013\Projects\WeatherAppService\WeatherAppTests\bin\Debug\WeatherAppTests.dll.config line 7)
-------------------------------------Question------------------------------------
Does anybody know how to set up log4net, so I can run the unit test, which runs the service app and get my log files written to? Or, given everything I have done, can someone please tell me what is incorrect or incomplete?
回答1:
The error is because, configSection should be the first element after <Configuration>
in the config file.
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,Log4net"/>
</configSections>
<ConfigSections>
element specifies the configuration and handler declaration, so this must be the first child of <Configuration>
来源:https://stackoverflow.com/questions/42634200/log4net-configuration-for-project-and-unit-test-in-one-solution