我目前正在开发的项目使用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}}?
答案 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配置编辑器无法识别它并且不尽如人意,但只要只有一个参数,它就可以工作。
如果有人知道如何正确地做到这一点,请发布并告诉我们 - 当然不应该这么困难。