views:

251

answers:

2

I'm using Enterprise Library 3.1 and want to programmatically access the Logging Block (runtime, object model) specifically its Trace Listeners and Sources.

For example, I want to access the Filename property of a trace listener object so I can know where the log file is located on disk.

Update: Looking for answers that use the runtime object model, not by parsing the XML configuration.

A: 

Apparently some needed info is privately encapsulated in a LogWriterStructureHolder instance (its field is named structureHolder) on the Enterprise Library Logger.Writer instance (of Type LogWriter).
So I'm effectively looking for: Logger.Writer.structureHolder (but that field is private).

I used reflection to pull it out....

These are the significant namespaces:

using System.Reflection;
using Microsoft.Practices.EnterpriseLibrary.Logging;

This is reflection code to pull out the needed private data:

// Get the private field.
FieldInfo fiLogStructHolder 
    = typeof(LogWriter).GetField("structureHolder", BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic);

// Obtain field value to get the private data.
LogWriterStructureHolder structureHolder 
    = (LogWriterStructureHolder)fiLogStructHolder.GetValue(Logger.Writer);

// Access the value's .TraceSources property of Type Dictionary<string, LogSource>.
// The string is the name of the category from configuration. 
int numSources = structureHolder.TraceSources.Count;

// Furthermore, access the listeners of any logging source by specifying:
int numListeners = structureHolder.TraceSources[0].Listeners.Count
                                             // ^-- Note: Picked first source for example.

If anybody can find a non-private entry point for this same data please post it in an answer. Thanks.

Kudos to .NET Reflector for facilitating this answer.

John K
A: 

You can access the logging configuration programmatically using the object model (used for configuration).

To get the specific data for the trace listener you should look at TraceListenerData (and the specific subclasses).

This example shows how to read in the configuration and then get the TraceListeners:

// Open config file
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = @"MyApp.exe.config";

Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

// Get EL log settings
LoggingSettings log = config.GetSection("loggingConfiguration") as LoggingSettings;

// Get TraceListener info
foreach(TraceListenerData listener in log.TraceListeners)
{
    // Check for listener types you care about
    if (listener is RollingFlatFileTraceListenerData)
    {
        RollingFlatFileTraceListenerData data = listener as RollingFlatFileTraceListenerData;
        Console.WriteLine(string.Format("Found RollingFlatFileLIstener with Name={0}, FileName={1}, Header={2}, Footer={3}, RollSizeKB={4}, TimeStampPattern={5},RollFileExistsBehavior={6}, RollInterval={7}, TraceOutputOptions={8}, Formatter={9}, Filter={10}",
            data.Name, data.FileName, data.Header, data.Footer, data.RollSizeKB, 
            data.TimeStampPattern, data.RollFileExistsBehavior, data.RollInterval,
            data.TraceOutputOptions, data.Formatter, data.Filter);
    }
    else // other trace listener types e.g. FlatFileTraceListenerData 
    {
    }
}
Tuzo
I like this much better than my runtime/reflection attempt. Thanks.
John K