NLog and Common.Logging nightmare
Asked Answered
V

4

5

So I have tried everything I can find to get these two to play together.

I have installed the nuget package Common.Logging.NLog20,

My config looks like:

<configSections>
    <sectionGroup name="common">
        <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
    </sectionGroup>
    <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog20" />
</configSections>
<common>
    <logging>
        <factoryAdapter type="Common.Logging.NLog.NLogLoggerFactoryAdapter, Common.Logging.NLog20">
            <arg key="configType" value="INLINE" />
        </factoryAdapter>
    </logging>
</common>
<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <dependentAssembly>
            <assemblyIdentity name="NLog" publicKeyToken="5120e14c03d0593c" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
        </dependentAssembly>
        <dependentAssembly>
            <assemblyIdentity name="Common.Logging" publicKeyToken="af08829b84f0328e" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
        </dependentAssembly>
    </assemblyBinding>
</runtime>

I am using the nuget NLog.Configuration package so my nlog config is in a separate file called NLog.config:

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  internalLogFile="nlog.ERRORS.txt" internalLogLevel="Error" >

<!-- 
See http://nlog-project.org/wiki/Configuration_file 
for information on customizing logging rules and outputs.
-->
<targets>
    <!-- add your targets here -->
    <target xsi:type="File" name="log" keepFileOpen="true"
            fileName="${basedir}/log_${date:format=yyyyMMdd}.txt"
            layout="${longdate} ${level:uppercase=true:padding=5} - ${logger:shortName=true} - ${message} ${exception:format=tostring}" />
    <target name="log_errors_memory" xsi:type="Memory"
            layout="${longdate} ${level:uppercase=true:padding=5} - ${logger:shortName=true} - ${message} ${exception:format=tostring}" />
    <target name="log_all_memory" xsi:type="Memory"
            layout="${longdate} ${level:uppercase=true:padding=5} - ${logger:shortName=true} - ${message} ${exception:format=tostring}" />
</targets>

<rules>
    <!-- add your logging rules here -->
    <logger name="*" minlevel="Trace" writeTo="log" />
    <logger name="*" minlevel="Trace" writeTo="log_all_memory" />
    <logger name="*" minlevel="Error" writeTo="log_errors_memory" />
</rules>
</nlog>

I have tried changing the FactoryAdaptor to NLog, NLog2 and NLog20, I have tried changing the binding redirect, I have tried updating the Common.Logging to version 2.2.0.0. No matter what I do I get the exception:

{"Failed obtaining configuration for Common.Logging from configuration section 'common/logging'."}

Inner Exception:
{"An error occurred creating the configuration section handler for common/logging: Type Common.Logging.NLog.NLogLoggerFactoryAdapter, Common.Logging.NLog20, Version=2.2.0.0, Culture=neutral, PublicKeyToken=af08829b84f0328e does not implement Common.Logging.ILoggerFactoryAdapter\r\nParameter name: factoryAdapterType\r\nActual value was Common.Logging.NLog.NLogLoggerFactoryAdapter. (D:\\Development\\Code\\DotNet\\vs2013\\exe\\CommandLine\\PSVImporter\\FidessaPSVImport.Test\\bin\\Debug\\FidessaPSVImport.Test.dll.config line 17)"}

What am I missing? This shouldn't be this hard to get working.

Venetian answered 6/5, 2014 at 20:9 Comment(3)
Too much pain for too little gain. Created my own simple abstraction. Goodby Common.Logging.Venetian
So I noticed that my nlog configSection had NLog20 instead of NLog, fixed that, no dice. Also, the factory property said inline so I removed the NLog.config file and put the nlog section into the appconfig. Still no luck.Venetian
Late to the party, but for anyone else landing here: The <arg key="configType" value="INLINE" /> entry is only if your NLog configuration is in the same file! If your NLog configuration is in a separate file (like NLog.config), then you need to specify <arg key="configType" value="FILE" /> and also specify the filename. See the docsRimrock
V
3

Okay, so after all the fixes above I had to also update the Common.Logging package to v2.2.0.0 and then update the binding redirects manually. This is really a sub-optimal deployment of the Common.Logging.NLog20 nuget package. You shouldn't have to do this.

Venetian answered 6/5, 2014 at 21:37 Comment(4)
I did everything you suggested and I'm still getting the same errorRelive
Unfortunately I'm not an nLog/Common.Logging guru so everything above is all I have to offer. All I can suggest is to double check to make sure your config file has no typing errors in it. I'll post all my versions in another answer for you and a fragment of my config. It works for me so it should work for you.Venetian
The only other thing I can think of is permission problems (as in you don't have access to your app.config file). But if you are getting this error in debugging, I don't see how that could happen.Venetian
This worked for me. Common Logging is in a state of ruin. Now I'm taking a dependency on NLog, because the log4net story doesn't work. Dependency hell... this is insane! @BitFiddler Thanks for the share.Ruppert
V
3

Common.Logging.NLog20 - Version 2.2.0.0

Common.Logging - version 2.2.0.0

NLog - Version 2.1.0.0

Config looks like:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <sectionGroup name="common">
            <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
        </sectionGroup>
        <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
    </configSections>
    <common>
        <logging>
            <factoryAdapter type="Common.Logging.NLog.NLogLoggerFactoryAdapter, Common.Logging.NLog20">
                <arg key="configType" value="INLINE" />
            </factoryAdapter>
        </logging>
    </common>
    <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          internalLogFile="nlog.ERRORS.txt" internalLogLevel="Error">

        <!-- 
          See http://nlog-project.org/wiki/Configuration_file 
          for information on customizing logging rules and outputs.
        -->
        <targets>
            <!-- add your targets here -->
            <target xsi:type="File" name="log" keepFileOpen="true"
                    fileName="${basedir}/log_${date:format=yyyyMMdd}.txt"
                    layout="${longdate} ${level:uppercase=true:padding=5} - ${logger:shortName=true} - ${message} ${exception:format=tostring}" />
            <target name="log_errors_memory" xsi:type="Memory"
                    layout="${longdate} ${level:uppercase=true:padding=5} - ${logger:shortName=true} - ${message} ${exception:format=tostring}" />
            <target name="log_all_memory" xsi:type="Memory"
                    layout="${longdate} ${level:uppercase=true:padding=5} - ${logger:shortName=true} - ${message} ${exception:format=tostring}" />
        </targets>

        <rules>
            <!-- add your logging rules here -->
            <logger name="*" minlevel="Trace" writeTo="log" />
            <logger name="*" minlevel="Trace" writeTo="log_all_memory" />
            <logger name="*" minlevel="Error" writeTo="log_errors_memory" />
        </rules>
    </nlog>
   </value>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="Common.Logging" publicKeyToken="af08829b84f0328e" culture="neutral" />
                <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
            </dependentAssembly>
            <dependentAssembly>
                <assemblyIdentity name="NLog" publicKeyToken="5120e14c03d0593c" culture="neutral" />
                <bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
</configuration>
Venetian answered 15/5, 2014 at 18:56 Comment(0)
S
1

Here's an underhanded approach that will save you a lot of hassle. The adapter that ships with Common.Logging.NLogXX, NLogLoggerFactoryAdapter, does nothing special but setup up NLog for you. This is something that most people can do on their own.

In other words, if you've already setup NLog all you need to do is hookup Common.Logging to NLog. This can be done by writing a simple factory that will create NLog Loggers like this:

public class MyAdapter : AbstractCachingLoggerFactoryAdapter
{
    protected override ILog CreateLogger(string name)
    {
        return (ILog)typeof(NLogLogger).GetConstructor(
            BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(NLog.Logger) }, null)
            .Invoke(new object[] { NLog.LogManager.GetLogger(name) });
    }
}

public static void ConfigureLogging()
{
    Common.Logging.LogManager.Adapter = new MyAdapter();
}
Sushi answered 5/7, 2017 at 23:32 Comment(0)
P
0

Latest NLog works without Common.Logging. In my case I just had to do following to avoid error "Failed obtaining configuration for Common.Logging from configuration section 'common/logging'"

Uninstall-Package Common.Logging
Uninstall-Package Common.Logging.Core
Install-Package NLog.Config

And then clear app.config from unnecessary configuration & use nlog.config instead. Like described here: http://nlog-project.org/download/

After that I had to refactor a bit code, but it works almost the same way as common.logging

LogManager.GetLogger(GetType().ToString()).Info("demo")
Pass answered 27/3, 2017 at 15:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.