4

我目前正在从事的项目使用 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似乎包含传递给构造函数的所有设置
  • 在文件底部露营的RollingFlatFileTraceListenerDataRollingTraceListenerAssembler : TraceListenerAsssembler似乎是工厂的类
  • 还有另一个类SystemDiagnosticsTraceListenerNode : TraceListenerNode似乎使Data该类可呈现给配置应用程序

我的问题是:如何CustomTraceListener使用可配置参数创建一个path

4

5 回答 5

6

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

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

string logFileName= Attributes["fileName"]
于 2009-10-13T06:43:35.400 回答
1

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

于 2009-09-10T00:38:10.950 回答
1

问题是典型的微软..(在此处添加您自己的形容词)..

1)当您添加自定义跟踪侦听器时,添加的“原始”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 的人生活在泡沫中。里克斯。

于 2009-10-08T20:04:08.403 回答
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;

    }
于 2009-09-11T21:57:23.397 回答
0

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

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

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

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

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

虽然 Entriprise Library 配置编辑器无法识别这一点,并且没有尽可能整洁,但只要只有一个参数,它就可以工作。

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

于 2010-01-26T10:38:07.120 回答