具有企业应用程序块的自定义跟踪侦听器

时间:2009-02-09 22:38:39

标签: c# logging enterprise-library

我目前正在开发的项目使用Enterprise Libraries V3.1框架进行日志记录。

我需要获取生成的日志文件并将其存档在特定点。内置的跟踪侦听器似乎使文件在记录事件之间保持打开状态。我已经设置了一个自定义跟踪侦听器,它将附加到文件并关闭它,以便文件始终可以移动。

它看起来像这样(为清晰起见,减去错误处理):

[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());
        }
    }
}

这很好用,但我更倾向于以某种方式作为参数传递路径,而不是硬编码。

为了好玩,我尝试将它添加到构造函数中,看看会发生什么:

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

当我这样做时,我收到一条错误信息,暗示我做错了什么:

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.

从现在开始,我的调查非常多,与死胡同相反,无限概率问题。

我在内置RollingTraceListener

的源代码中找到了这个翻版
  • 有一个类RollingFlatFileTraceListenerData : TraceListenerData,它似乎包含传递给构造函数的所有设置
  • RollingFlatFileTraceListenerData文件底部的RollingTraceListenerAssembler : TraceListenerAsssembler类是SystemDiagnosticsTraceListenerNode : TraceListenerNode,它似乎是一个工厂
  • 还有另一个类Data似乎使CustomTraceListener类可以呈现给配置应用程序

我的问题是:如何使用path的可配置参数创建{{1}}?

5 个答案:

答案 0 :(得分:6)

CustomTraceListener派生自TraceListener,它有一个名为Attributes的StringDictionary。

这将包含TraceListener配置行中的所有属性,并且可以通过名称获取,例如。

string logFileName= Attributes["fileName"]

答案 1 :(得分:1)

我怀疑也许企业应用程序阻止虽然(可能)很棒,看起来不必要地复杂化,最终比这种定制的价值更麻烦。

答案 2 :(得分:1)

问题是典型的微软..(在这里添加你自己的形容词)..

1)添加自定义跟踪侦听器时,添加的“raw”app.config语句为:

   name="Custom Trace Listener" initializeData="" formatter="Text Formatter" />

2)注意'initializeData' - 这就是神秘的错误消息正在调用'InitData'。

3)所以它说的是你需要一个接受初始化数据的构造函数 - 用vb说法:

  sub new (byval initstuff as string)

4)或删除'initializeData =“”'并使用默认构造函数:

  sub new()

我怀疑P& P的人生活在泡沫中。 riix。

答案 3 :(得分:0)

值得一提的是我如何实现它。在我的this.buildCurrPath()中,我可以从配置文件中读取,或者在这种情况下,我只是获得了Web应用程序的“启动板”。但它对我来说很好。我还没有把它放到任何生产代码中,但它应该很快就会出来。

[ConfigurationElementType(typeof(CustomTraceListenerData))]
public class CustomListener: CustomTraceListener
{

    #region Fields (3) 
    private int logSize;
    StreamWriter sw;
    #endregion Fields 

    #region Constructors (1) 

    public CustomListener ():base()
    {
        string startPath = this.buildCurrPath();
        sw = new StreamWriter(startPath + "\\Logs\\test.log");
        sw.AutoFlush = true;

    }

答案 4 :(得分:0)

我刚遇到同样的问题(Enterprise Library v4.1除外)。

我找到的解决方案是删除默认构造函数,并且只有一个带有文件名字符串参数的构造函数,即。

public AlwaysClosedTextFileTraceListener (string pathParameter)   
{   
    logFilePath = pathParameter;   
} 

然后在app.config中将您的路径放在initializeData参数

<add ... initializeData="C:\Logs\myLog.log" />

虽然Entriprise Library配置编辑器无法识别它并且不尽如人意,但只要只有一个参数,它就可以工作。

如果有人知道如何正确地做到这一点,请发布并告诉我们 - 当然不应该这么困难。