6
votes

I would like use from Spring.NET Aspect library Logging aspect together with log4Net. I found this article how to use log4Net with Common Logging API.

My test application is console and based on .NET 4.0 Client profile.

1st Attempt

So I refer in my project these libraries:

  • Spring.Core version 1.3.2.40943, runtime v4.0.30319
  • Spring.AOP version 1.3.2.40943, runtime v4.0.30319
  • Common.Logging version: 1.2.0.0, runtime v1.0.3705

Assemblies above I have from Program Files\Spring.NET 1.3.2\bin\net\4.0

  • log4net version: 1.2.10.0, runtime v2.0.50727

I couldn’t find assembly Common.Logging.Log4Net.dll in Program Files\Spring.NET 1.3.2\bin \net\4.0 so I download this assembly from SourceForge:

  • Common.Logging.Log4Net version 2.0.0.0 runtime v2.0.50727

I configured logger in app.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
      <sectionGroup name="spring">
          <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
          <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core"/>
      </sectionGroup>
      <sectionGroup name="common">
        <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
      </sectionGroup>
      <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
  </configSections>

  <common>
    <logging>
      <factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4Net">
        <arg key="configType" value="INLINE" />
      </factoryAdapter>
    </logging>
  </common>

  <log4net>
    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger %ndc - %message%newline" />
      </layout>
    </appender>

    <root>
      <level value="DEBUG" />
      <appender-ref ref="ConsoleAppender" />
    </root>

    <logger name="myLogger">
      <level value="DEBUG" />
    </logger>
  </log4net>

  <spring>
    <context>
      <resource uri="config://spring/objects"/>
    </context>
    <objects xmlns="http://www.springframework.net">
    </objects>
  </spring>
</configuration>

and tried this:

ILog log = LogManager.GetLogger("myLogger");
log.Error("hello world");

I got this runtime error:

{"Could not configure Common.Logging from configuration section 'common/logging'."}

Inner exception:

{"An error occurred creating the configuration section handler for common/logging: Unable to create type 'Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4Net' (E:\C# PROJECTS\STUDY\SPRING.NET\SpringNet.Aspects\LoggingWithLog4Net\bin\Debug\LoggingWithLog4Net.vshost.exe.Config line 18)"}

StackTrace:

at System.Configuration.BaseConfigurationRecord.EvaluateOne(String[] keys, SectionInput input, Boolean isTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult) at System.Configuration.BaseConfigurationRecord.Evaluate(FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult, Boolean getLkg, Boolean getRuntimeObject, Object& result, Object& resultRuntimeObject) at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject) at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject) at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject) at System.Configuration.BaseConfigurationRecord.GetSection(String configKey) at System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(String sectionName) at System.Configuration.ConfigurationManager.GetSection(String sectionName) at System.Configuration.ConfigurationSettings.GetConfig(String sectionName) at Common.Logging.ConfigurationReader.GetSection(String sectionName)
at Common.Logging.LogManager.BuildLoggerFactoryAdapter()

2nd Attempt

I think problem must be in version of assembly Common.Logging.Log4Net version 2.0.0.0 runtime v2.0.50727. Because I used Common.Logging version: 1.2.0.0, runtime v1.0.3705.

So I changed Common.Logging version from 1.2.0.0 to 2.0.0.0. I used Common.Logging from SourceForge.

And tested again. I got this error:

Unable to create type 'Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4Net'

Inner exception:

{"Could not load file or assembly 'Common.Logging.Log4Net' or one of its dependencies. The system cannot find the file specified.":"Common.Logging.Log4Net"}

StackTrace:

at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMarkHandle stackMark, Boolean loadTypeFromPartialName, ObjectHandleOnStack type) at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, Boolean loadTypeFromPartialName) at System.RuntimeType.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark) at System.Type.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase) at Common.Logging.ConfigurationSectionHandler.ReadConfiguration(XmlNode section) in c:\CCNet\netcommon\trunk\modules\Common.Logging\src\Common\Common.Logging\Logging\ConfigurationSectionHandler.cs:line 130

3rd and last attempt

Finally I found assembly Common.Logging.Log4Net version 1.2.0.2 in spring examples so I used it.

  • Common.Logging.Log4Net version 1.2.0.2
  • Common.Logging version 1.2.0.0
  • log4Net 1.2.10.0

Tested and got again error:

{"Could not configure Common.Logging from configuration section 'common/logging'."}

Inner exception:

{"An error occurred creating the configuration section handler for common/logging: Unable to create type 'Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4Net' (E:\C# PROJECTS\STUDY\SPRING.NET\SpringNet.Aspects\LoggingWithLog4Net\bin\Debug\LoggingWithLog4Net.vshost.exe.Config line 18)"}

StackTrace:

{"Unable to create type 'Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4Net'"}

I am really confuse what I do bad? Some problem with assemblies version?

3
You might be interested in stackoverflow.com/questions/8029460/… ...Marijn
... and the aop quickstart has a nice example on logging using Spring.NET AOP.Marijn

3 Answers

5
votes

For Spring.NET 1.3.2 you should use:

  • Common.Logging 2.0.0
  • Common.Logging.Log4Net 2.0.0
  • log4net 1.2.10

Make sure the last two log4net dll's are copied to the output directory. Since your code doesn't reference it directly, they might not be copied by Visual Studio.

1
votes

Also, instead of

<resource uri="config://springs/objects"/>

Try

<resource uri="config://spring/objects"/>

In your config file the sectionGroup name is "spring", NOT "springs". I copied from yours to make mine work and got in the same problem. Finally figured out why.

Hope that helps!

1
votes

Another possibility is:

  • Common.Logging 2.1.1
  • Common.Logging.Log4Net 2.1.1
  • log4net 1.2.10

I recommend skipping Common.Logging 2.1.0 as it did throw this exception when reading perfectly valid app.config section:

"Unable to cast object of type 'System.Configuration.DefaultSection' to type 'System.Configuration.AppSettingsSection'."

Installing 2.1.1 fixed the problem.