Get pathes of a category

Topics: Logging Application Block
Oct 4, 2012 at 4:49 PM

Hi,

Is there any way to create a function in my application that, by a given catecory - returns the pathes of the listeners attached with this category?

For example, if I have a category named "errors", and it is attached to a listener with file name d:\err.log, the function will return the path (the one that is written in the app.config)

Thanks,

Reut.

Oct 5, 2012 at 1:07 AM

Yes, you can definitely do that by using the Configuration classes.  The code would look something like this:

IEnumerable<string> GetFilePaths(string categoryName)
{
    IConfigurationSource configSource = ConfigurationSourceFactory.Create();
    var logSettings = configSource.GetSection(LoggingSettings.SectionName) as LoggingSettings;

    var category = logSettings.TraceSources
                        .SingleOrDefault(traceSource => 
                            string.Compare(traceSource.Name, categoryName, StringComparison.Ordinal) == 0);

    if (category != null)
    {
        foreach (var traceListenerReference in category.TraceListeners)
        {
            var traceListeners = logSettings.TraceListeners
                                    .Where(t => string.Compare(
                                        t.Name, traceListenerReference.Name, StringComparison.Ordinal) == 0);

            foreach (var traceListener in traceListeners)
            {
                string fileName = null; 
                if (traceListener is FlatFileTraceListenerData)
                {
                    fileName = ((FlatFileTraceListenerData)traceListener).FileName;
                }
                else if (traceListener is RollingFlatFileTraceListenerData)
                {
                    fileName = ((RollingFlatFileTraceListenerData)traceListener).FileName;
                }
                else if (traceListener is XmlTraceListenerData)
                {
                    fileName = ((XmlTraceListenerData)traceListener).FileName;
                }

                if (fileName != null)
                {
                    yield return new FileInfo(fileName).FullName;
                }

                // In this case reflection is more elegant since we can avoid casting assuming that
                // FileName is what we will be looking for
                //
                //PropertyInfo fileNameProperty = traceListener.GetType().GetProperty("FileName");
                //if (fileNameProperty != null)
                //{
                //    string fileName = fileNameProperty.GetValue(traceListener, null) as string;
                //    yield return new FileInfo(fileName).FullName;
                //}
            }                    
        }
    }
}

This will return an IEnumerable<string> containing the absolute path of the fileNames in the configuration file.  Multiple results can be returned because a category can have multiple trace listeners associated with it.  I threw in the reflection approach as well since you can avoid all that ugly casting.  :)

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com 

Oct 5, 2012 at 10:32 AM

Hi,

I didn't really understand where do I need to write this finction, and how do I call it from my application.

Lets take for example the Samples.TraceListeners in which there is a custom xmlTraceListener and a custom rollingFlatFileTraceListener.

First, where do I need to write this function - in which class?

Second, how do I call this function from my Program.cs class?

Thanks!!

Reut.

Oct 5, 2012 at 10:57 AM

I think I understood it...

I  wrote this function as a static function in RollingFlatFileTraceListener.cs and called it from Program.cs.

Is it right?

And, do I need to write this function in every traceListener (having a file path of course)?

Thanks,

Reut.

Oct 5, 2012 at 3:03 PM

You can call/write that function anywhere in your application you want to.  Trace listeners themselves don't need this function since they know what file they are writing to (in a way).  e.g. When the FlatFileTraceListenerData class is creating a FlatFileTraceListener it passes the FileName to the constructor.   But the method is not logically associated with a trace listener so I wouldn't put it on a trace listener.  A helper utility class seems to make sense to me.

What problem are you trying to solve?

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com 

Oct 6, 2012 at 12:05 AM

I am trying to get the pathes from my application.

I understand now that it was wrong to write this function in the trace listener class.

I have a wrapper class (a helper utility class) and the function needs to be there..

Thanks a lot

Reut