views:

822

answers:

2

Without getting into the discussion of the merits or otherwise of the EntLib logging block, is there any way that I can change it's configuration at runtime?

For example, I have the block configured to log General events to a flat file, and Critical events to the event log.
Is there any way to change it to log General events to the console, etc, without restarting my application?

Clarification: I am writing a long-running server application. I would like to be able to temporarily increase the verbosity/output of various logging groups for diagnostic/troubleshooting purposes without restarting the application. Restarting is not an option as it would mean "site down" in production.

+1  A: 

I know you can open the ConfigurationFileMap and change configuration for the logger. I am not sure, however, if this will solve the problem in a way that you would desire, as saving the configuration file resets the application and you would have to set it back to default. This is a lot of work to simply hook up a console.

As the logging block uses a provider model, you should be able to attach to it at runtime, but I am not sure how to do this. You have the full source for the EntLib, however, so running through the code stack to figure this out should not be a major chore. You do not even have to reflect back through the code to hack at it.

I assume your goal is to watch an application in real time?

Gregory A Beamer
updated question - I'm writing a 24/7 server app and would like to "bump up" the logging in various areas for troubleshooting purposes without restarting
Orion Edwards
That would not happen with config rewrite, as it would restart. Not a huge deal, if you are using SQL for state server, but it can munge up people in the middle of a request. I would look at the code base or consider building a logging windows service, as you can attach there.
Gregory A Beamer
+1  A: 

It’s actually pretty easy to achieve, just follow these steps:

Place the Enterprise Library configuration in a separate file

<configuration>
  <configSections>
    <section name="enterpriseLibrary.ConfigurationSource" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ConfigurationSourceSection, Microsoft.Practices.EnterpriseLibrary.Common, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  </configSections>
  <enterpriseLibrary.ConfigurationSource selectedSource="EntLib Config">
    <sources>
      <add name="EntLig Config" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.FileConfigurationSource, Microsoft.Practices.EnterpriseLibrary.Common, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
          filePath="EntLib.config" />
    </sources>
  </enterpriseLibrary.ConfigurationSource>
</configuration>

Add a logging filter. You can use log entry priorities or categories to filter the log entries, so in your code you should set the priority or category accordingly. For example, you want to give very important messages and low priority number, like 1, and more verbose message could be 10.

<configuration>
  ...
  <loggingConfiguration name="Logging Application Block" tracingEnabled="true"
    defaultCategory="General" logWarningsWhenNoCategoriesMatch="true">
    ...
    <logFilters>
      <add minimumPriority="1" maximumPriority="10" type="Microsoft.Practices.EnterpriseLibrary.Logging.Filters.PriorityFilter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        name="Priority Filter" />
    ...
  </loggingConfiguration>
</configuration>

Any changes made to Enterprise Library configuration at runtime is ignored – except changes made to the Logging Application Block. See this post on MSDN: Updating Configuration Settings at Run-time

I implemented a simple helper method to toggle the filter values: When I want more verbose messages, I allow those entries to be registered by increasing the maximum priority value. Likewise, when I only want exceptions or other very important messages to be logged, I set the priority range to 0 to 1.

var path = System.IO.Path.Combine(Environment.CurrentDirectory, "EntLib.config");
var xd = XDocument.Load(path);

var x = (from z in xd.Root.Elements("loggingConfiguration").Elements("logFilters").Elements() where (z.Attribute("name").Value == "Priority Filter") select z).SingleOrDefault();
x.Attribute("minimumPriority").Value = 1; // Change this value...
x.Attribute("maximumPriority").Value = 5; // ... and this one to specify the range you want to log.

xd.Save(path);

This will change the Enterprise Library Logging functionality without reloading your service as the web.config is never touched. Only drawback is that it is required you use soem kind of convention of prioritizing/categorizing the log entries.

Jakob Gade