Enterprise Library Logging Application Block: using special sources

Topics: Building and extending application blocks, Logging Application Block
Jun 7, 2010 at 1:14 PM
Edited Jun 8, 2010 at 9:40 AM

Hello all,

I have configured my logging application block as follows, using Enterprise Libaray 4.1 (in app.config):

 

<loggingConfiguration name="Logging Application Block" tracingEnabled="true" defaultCategory="General" logWarningsWhenNoCategoriesMatch="true">
 <logFilters>
 <add
  name="LogEnabled Filter"
  type="Microsoft.Practices.EnterpriseLibrary.Logging.Filters.LogEnabledFilter, Microsoft.Practices.EnterpriseLibrary.Logging"
  enabled="true"
  />
 </logFilters> 
 <listeners>

 <add
  name="Rolling Flat File Trace Listener Debug"
  fileName="Logs/Debug.log"
  header="------HEADER-------"
  footer=""
  formatter="Text Formatter"
  rollFileExistsBehavior="Overwrite"
  rollInterval="Day"
  rollSizeKB="10000"
  timeStampPattern="yyyy-MM-dd"
  listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.RollingFlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
  traceOutputOptions="None"
  filter="Verbose"
  type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollingFlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
  />

 <add
  name="Rolling Flat File Trace Listener Unprocessed"
  fileName="Logs/Unprocessed.log"
  header="-------------"
  footer=""
  formatter="Text Formatter"
  rollFileExistsBehavior="Overwrite"
  rollInterval="Day"
  rollSizeKB="10000"
  timeStampPattern="yyyy-MM-dd"
  listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.RollingFlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
  traceOutputOptions="None"
  filter="Verbose"
  type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollingFlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
  />

 <add
  fileName="Logs/RawLogHistory/RawLogHistory.log"
  name="Rolling Flat File Trace Listener Full History"
  header=""
  footer=""
  formatter="Text Formatter"
  rollFileExistsBehavior="Overwrite"
  rollInterval="Day"
  rollSizeKB="10000"
  timeStampPattern="yyyy-MM-dd"
  listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.RollingFlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
  traceOutputOptions="None"
  filter="Verbose"
  type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollingFlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
  />

</listeners>
 <formatters>
 <add
  name="Text Formatter"
  template=" {severity} [{timestamp}] {message}"
  type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
  />
 </formatters>

 <categorySources>

 <add switchValue="All" name="General">
  <listeners>
  <add name="Rolling Flat File Trace Listener Debug"/>
  </listeners>
 </add>

 <add switchValue="All" name="Debug">
  <listeners>
  <add name="Rolling Flat File Trace Listener Debug"/>
  </listeners>
 </add>

 <add switchValue="All" name="Exception">
  <listeners>
  <add name="Rolling Flat File Trace Listener Debug"/>
  </listeners>
 </add>
  </listeners>
 </add>

 </categorySources>

 <specialSources>

 <allEvents switchValue="All" name="All Events"/>

 <notProcessed switchValue="All" name="Unprocessed Category"/>
  <listeners>
  <add name="Rolling Flat File Trace Listener Unprocessed"/>
  </listeners>
 </notProcessed>

 <errors switchValue="Information" name="Logging Errors &amp; Warnings">
  <listeners>
  <add name="Rolling Flat File Trace Listener Debug"/>
  </listeners>
 </errors>

 </specialSources>

</loggingConfiguration>


Everything works fine.

The only issue i have, is with the "Unprocessed Category" special source.

Reading the documentation from msdn for EntLib L.A.B., i undestood that when you try and log to a Category that is not specified, that LogEntry is directed to the Unprocessed Category source.

In the above example though, if i log a Verbose message, and define the category in the LogEntry to be let's say "Undefined" (which is not specified in the configuration), i loose that LogEntry completely. Ideally, when the application attempts to log, it should do the following steps:
-Get the LogEntry and pass it through the logfilters.
-If it passes through the logfilters, find the category that the logentry specifies, and pass it to the listeners in that category
(in our current case, category is "Undefined")
-If you can't find the category specified in the LogEntry,go to the "Unprocessed Category" special source and log it to the listeners specified in there.

BUT: !!Last step is never executed. I do not get the log in my flat file!!
NOTES: -I have double checked, and the filters for both
the listeners and the categories are not blocking the LogEntry because of the level of message (verbose, information, etc...)
-The other special sources ("All Events" and "Logging Errors & Warnings") work fine.


Any suggestions on why this is the case?

Any hints would be appreciated.



Regards,

Shtel
Jun 8, 2010 at 2:56 AM

Hi,

Is the configuration posted the actual config that you are using in your app?

This scenario works fine on my end so I tried to copy your config and tested it from here and it also works fine (note that I've done some minor modification in the config since some tags are not well formed like no logFilters end tag, remove extra listeners that are not yet configured and etc..)

I'm assuming your still running your app in debug mode right? Because if you already running a deployed app you may also want to check if the specific user running the App has a write permission in the folder you are writing your log files to.

Honestly, I'm not really sure what could be the problem here, one thing I think we can do to help is to look into your actual or sample app. You can send it through our mailbox (entlib.support@avanade.com) and we'll see what we can find.

Gino Terrado
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Jun 8, 2010 at 10:04 AM

Hi Gino,

This is a part of the whole conig that i use in my app... (and poor copy pasting resulted in the missing end tags and undefined listeners :p)

 

I found the solution though! 
Apparently, when you have listeners for "allEvents" special source as well as the "notProcessed" special source, 
a LogEntry with an undefined category will not go to both! It will be written in the "allEvents" source listeners ONLY

You remove the listeners for "allEvents", and VOILA! LogEntry is sent to "notProcessed".

I don't know if this is a bug or not, but from my point of view, it is, since "allEvents" should not block LogEntries from being routed to the correct Category or special source.

Try this senario and tell me what you think:

-Add a flat file trace listener in the "allEvents" special source.

-Add another flat file trace listener in the "notProcessed" special source

-Send a LogEntry to EntLib which has an undefined category destination.

RESULT: That LogEntry is only written in the "allEvents" special source.

Regards,

Shtel

 

Jun 8, 2010 at 10:44 AM

Shtel, you are correct. This is indeed the behavior of the special sources category which I believe is by design and not a bug.

You can't barely find any specific info regarding this in the documentation but if you take a look at the source code the LogWriter class has this notes regarding that

    /// If the "all events" special log source is configured, the log entry will be traced through the log source regardles of other categories 
    /// that might have matched.
    /// If the "all events" special log source is not configured and the "unprocessed categories" special log source is configured,
    /// and the category specified in the logEntry being logged is not defined, then the logEntry will be logged to the "unprocessed categories"
    /// special log source.
    /// If both the "all events" and "unprocessed categories" special log sources are not configured and the property LogWarningsWhenNoCategoriesMatch
    /// is set to true, then the logEntry is logged to the "logging errors and warnings" special log source.

Hope this make sense.

Gino Terrado
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

 
Jun 8, 2010 at 11:13 AM

Heh, i had to find out about this the hard way...

Thanks for the help Gino!