Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Trace Listener with the Enterprise Application Blocks

The project I'm currently working on uses Enterprise Libraries V3.1 framework for logging.

I need to take the log file that's generated and archive it off at specific points. The built in Trace Listeners seem to keep the file open in-between logging events. I've set up a custom Trace Listener which will append to a file and close it, so that the file is always shiftable.

It looks like this (minus error handling for clarity):

[ConfigurationElementType(typeof(CustomTraceListenerData))]
public class AlwaysClosedTextFileTraceListener : CustomTraceListener
{
    private string logFilePath;

    public AlwaysClosedTextFileTraceListener ()
    {
        logFilePath = @"hardcodedpath\log.txt";
    }

    public override void Write(string message)
    {
        using (StreamWriter logFile = File.AppendText(logFilePath))
        {
            logFile.Write(message);
            logFile.Flush();
            logFile.Close();
        }
    }

    public override void WriteLine(string message)
    {
        using (StreamWriter logFile = File.AppendText(logFilePath))
        {
            logFile.WriteLine(message);
            logFile.Flush();
        }
    }

    public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, object data)
    {
        if (data is LogEntry && this.Formatter != null)
        {
            WriteLine(this.Formatter.Format(data as LogEntry));
        }
        else
        {
            WriteLine(data.ToString());
        }
    }
}

This works fine, but I'd much rather be passing in the path as a parameter somehow, rather than hardcoding it.

For fun, I tried adding it to the constructor, to see what happens:

    public LogFolderTraceListener(string logFilePath)
    {
        this.logFilePath = logFilePath;
    }

When I do this, I get returned an error message hinting towards what I'm doing wrong:

System.InvalidOperationException : The type 'AlwaysClosedTextFileTraceListener' specified for custom trace listener named 'MyLogFile' does not a default constructor, which is required when no InitData is specified in the configuration.

From here on in, my investigations have very much come to, the opposite of dead ends, infinite probability problems.

I have found this thumbing through the source code for the inbuilt RollingTraceListener

  • There is a class RollingFlatFileTraceListenerData : TraceListenerData which seems to contain all the settings passed into the constructor
  • Camped out at the bottom of the file for RollingFlatFileTraceListenerData is the class RollingTraceListenerAssembler : TraceListenerAsssembler which seems to be a factory
  • There is another class SystemDiagnosticsTraceListenerNode : TraceListenerNode which seems to make the Data class presentable to the configuration application

My question is this: how do I create a CustomTraceListener with a configurable parameter of path?

like image 226
Don Vince Avatar asked Mar 02 '23 00:03

Don Vince


2 Answers

The CustomTraceListener derives from TraceListener, this has a StringDictionary called Attributes.

This will contain all the attributes in the configuration line for your TraceListener and can be gotten out by name, eg.

string logFileName= Attributes["fileName"]
like image 119
squig Avatar answered Apr 20 '23 01:04

squig


I suspect that perhaps the Enterprise Application Blocks although (probably) wonderful, seem unnecessarily complicated and ultimately more trouble than their worth for this kind of customisation.

like image 39
Don Vince Avatar answered Apr 19 '23 23:04

Don Vince