When System.Diagnostics.Trace to routed to send its output to the Common.Logging infrastructure using the CommonLoggingTraceListener:
app.config
<?xml version='1.0' encoding='utf-8'?>
<configuration>
<configSections>
<sectionGroup name="common">
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
</sectionGroup>
</configSections>
<common>
<logging>
<factoryAdapter type="Common.Logging.Simple.ConsoleOutLoggerFactoryAdapter, Common.Logging">
<arg key="level" value="ALL" />
<arg key="showLogName" value="true" />
<arg key="showDataTime" value="true" />
<arg key="dateTimeFormat" value="yyyy/MM/dd HH:mm:ss:fff" />
</factoryAdapter>
</logging>
</common>
<system.diagnostics>
<sharedListeners>
<add name="Diagnostics"
type="Common.Logging.Simple.CommonLoggingTraceListener, Common.Logging"
initializeData="Name=My.Namespace.Program; DefaultTraceEventType=Information; LoggerNameFormat={listenerName}">
<filter type="System.Diagnostics.EventTypeFilter" initializeData="Information"/>
</add>
</sharedListeners>
<trace>
<listeners>
<add name="Diagnostics" />
</listeners>
</trace>
</system.diagnostics>
</configuration>
an exception is thrown when trying making calls to Diagnostics.Trace:
Program.cs
static class Program
{
static int Main(string[] args)
{
var logger = LogManager.GetCurrentClassLogger();
Trace.Write("test message");
}
}
Exception details:
System.ArgumentNullException was unhandled
Message="Key cannot be null.\r\nParameter name: key"
Source="mscorlib"
ParamName="key"
StackTrace:
at System.Collections.Hashtable.get_Item(Object key)
at Common.Logging.Factory.AbstractCachingLoggerFactoryAdapter.GetLoggerInternal(String name)
at Common.Logging.Factory.AbstractCachingLoggerFactoryAdapter.GetLogger(String name)
at Common.Logging.LogManager.GetLogger(String name)
at Common.Logging.Simple.CommonLoggingTraceListener.Log(TraceEventType eventType, String source, Int32 id, String format, Object[] args)
at Common.Logging.Simple.CommonLoggingTraceListener.Write(String message)
at System.Diagnostics.TraceInternal.Write(String message)
at My.Namespace.Program.Main(String[] args) in Program.cs:line 20
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
The exception occurs when you call Trace.Write without a "cateogry" param. The following will work:
Program.cs
static class Program
{
static int Main(string[] args)
{
var logger = LogManager.GetCurrentClassLogger();
Trace.Write("test message", "test category");
}
}
The source of the problem is CommonLoggingTraceListener.Log, line 178.
If the "source" param is null, the proper logger name will not be created, causing us to send a null param to the GetLogger method:
ILog log = LogManager.GetLogger(source);
The fix is, instead of:
178 if (!string.IsNullOrEmpty(source))
179 {
180 source = this.LoggerNameFormat.Replace("{listenerName}", this.Name).Replace("{sourceName}", source);
181 }
we do:
source = this.LoggerNameFormat.Replace("{listenerName}", this.Name);
if (!string.IsNullOrEmpty(source))
{
source = source.Replace("{sourceName}", source);
}
View and moderate all "bugs Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Bugs"
View and moderate all "bugs Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Bugs"
View and moderate all "bugs Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Bugs"
Another alternative solution might be to not pass null into the Log method from it's usages:
CommonLoggingTraceListener.cs
267 /// <summary>
268 /// Writes message to logger provided by <see cref="LogManager.GetLogger(string)"/>.
269 /// </summary>
270 public override void Write(string message)
271 {
272 if (((this.Filter == null) || this.Filter.ShouldTrace(null, this.Name, this.DefaultTraceEventType, 0, null, null, null, null)))
273 {
274 Log(this.DefaultTraceEventType, null, 0, message);
275 }
276 }
Instead of the null param on line 274 we can do something like "uncategorized".
Thanks so much for reporting this!
fixed by simple converting a <null> source to string.Empty before formatting the loggername
View and moderate all "bugs Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Bugs"
Hi Mark, Erich,
Thank you for the quick fix!
I now use CommonLogging in all my projects, and I love it. Thank you so much for the community contribution!
Sorry for the late response. For some reason I didn't get notification on any updates on this.
Best regards,
Martin