我正在尝试使用 System.Diagnostics.XmlWriterTraceListener 登录到本地文件。我首先创建一个源并向其中添加一个新的 XmlWriterTraceListener,如下所示:
public class Logger
{
const string LOG_ERR_FMT = "<message><![CDATA[{0}]]></message>{2}";
TraceSource tSource = new TraceSource(
"MyApp",
SourceLevels.Verbose | SourceLevels.ActivityTracing
);
public Logger() {
tSource.Listeners.Add(
new XmlWriterTraceListener("C:\\app_path\\app_tracelog.svclog", "LocalListener")
);
}
public static Logger defLogger = new Logger();
public static Logger Default {
get {return defLogger; }
set { if (value != null) defLogger = value; }
}
public void LogError(string msg, string extraXmlData) {
tSource.TraceEvent(TraceEventType.Error, 0, LOG_ERR_FMT, logMsg, extraXmlData);
}
}
我在上面的示例中简化了日志格式。实际LogError
方法采用一个Exception
对象并将一些关于它的 xml 序列化数据插入到消息中,但这不需要显示我的问题是什么。
无论如何,我的应用程序的任何其他部分现在都可以使用简单的一行将错误记录到“app_tracelog.svclog”文件中,哦,说...
Logger.Default.LogError(
"Error parsing response from web service \"someservice.com\".",
"<RequestBody><![CDATA[" + responseBody + "]]></RequestBody>"
);
一切都很好,直到我打开 app_tracelog.svclog。首先,当我尝试使用 Microsoft 服务跟踪查看器打开它时,该程序的行为就像它是空的,并给我一条消息“没有从文件加载跟踪”。
其次,我用旧的 Notepad++ 打开文件,发现我的应用确实记录到了它。我全选并告诉 XmlTools 对其进行美化,该工具告诉我它不能这样做,因为 XML 中有错误。
所以,我开始手动格式化它。一开始一切顺利,直到我收到我记录的实际应用程序消息。在这里,我发现这个 STUPID @#$ 类通过用编码的 XML/HTML 实体替换括号等,搞砸了我所有的嵌套 XML!
我所有的 '<' 都变成了“<”,我所有的 '> 都变成了“>”,等等......所以应该看起来像这样的日志消息:
<message><![CDATA[Error parsing response from web service "someservice.com".]]></message><RequestBody...
现在看起来像:
<message><![CDATA[Error parsing response from web service "someservice.com".]]></message><RequestBody...
所以最大的问题是:我如何强制 XmlWriterTraceListener 在我登录时停止丢弃我的消息?当我输入特殊的 XML 字符时,我知道我在做什么,而且它认为它知道得更好!--OR-是否有另一个侦听器类可以按照我想要的方式记录到本地 XML 文件?