I'm trying to use the Common Infrastructure Libraries for .NET (Common.Logging) with Enterprise Library 4.1's Logging Application Block. According to the docs, this is supported.
The problem I'm encountering is that when I try to log something, like so (in this example I'm in an ASP.NET MVC application):
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
ILog log = LogManager.GetCurrentClassLogger();
log.Info("Hello world!");
return View();
}
Instead of getting the log message, I'm getting an error in my event log:
Message: There is no explicit mapping for the categories 'TestApp.Controllers.HomeController'.
Well, there doesn't seem to be any option in Common.Logging to set the default category, and I can't figure out how to configure the LoggingConfiguration to accept any category, even if it isn't defined.
Here's a snippet of my LoggingConfiguration:
<loggingConfiguration name="Logging Application Block" tracingEnabled="true"
defaultCategory="General" logWarningsWhenNoCategoriesMatch="true">
...
<categorySources>
<add switchValue="All" name="General">
<listeners>
<add name="Formatted EventLog TraceListener" />
<add name="Email TraceListener" />
</listeners>
</add>
</categorySources>
<specialSources>
<allEvents switchValue="All" name="All Events" />
<notProcessed switchValue="All" name="Unprocessed Category" />
<errors switchValue="All" name="Logging Errors & Warnings">
<listeners>
<add name="Formatted EventLog TraceListener" />
</listeners>
</errors>
</specialSources>
</loggingConfiguration>
I've tried setting logWarningsWhenNoCategoriesMatch
to false, but that just silences the warning -- it doesn't make the logging work.
I've also tried getting rid of the <notProcessed switchValue="All" .../>
special source, but that doesn't seem to have any effect either.
Anyone know if there's a way to get this to work? Thanks!
The 'notProcessed' special source will match any entries that do not match a category source - so you can use that to catch them. There's more information here: https://entlib.codeplex.com/discussions/215189
<notProcessed switchValue="All" name="Unprocessed Category"/>
<listeners>
<add name="Rolling Flat File Trace Listener Unprocessed"/>
</listeners>
</notProcessed>
When you call LogManager.GetCurrentClassLogger()
Common.Logging is going to use the type of your calling class as the category:
public static ILog GetCurrentClassLogger()
{
StackFrame frame = new StackFrame(1, false);
return Adapter.GetLogger(frame.GetMethod().DeclaringType);
}
If you want to use this approach (although the recommendation is not to use this method excessively since it inspects the StackFrame) then, yes, you will need to create a category for every class that you are logging from. This would recreate a kind of hierarchical loggers that are used in Log4Net. But this approach is not ideal since it is not maintainable.
You should be able to get around this by using the LogManager.GetLogger(string name)
overload instead of GetCurrentClassLogger
. It looks like the name that is passed in will be used as the category for logging in Enterprise Library. So you could define category name as a constant and pass that in to the GetLogger
method and have your entire application use one Enterprise Library category.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With