我正在尝试使用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 Service Trace Viewer打开它时,该程序的行为就像它是空的,并给我一条消息“没有从文件加载的跟踪。”
其次,我用旧的Notepad ++打开文件,发现我的应用程序DID INDEED登录到它。我选择all并告诉XmlTools将它搞砸了,该工具告诉我它不能这样做,因为XML中存在错误。
所以,我手动开始格式化。一开始一切顺利,直到我得到我记录的实际应用程序消息。在这里,我发现这个STUPID @#$类通过用编码的XML / HTML实体替换括号等来搞砸我所有的嵌套XML!
我的所有'&lt;'已成为“&amp; lt;”,所有我的'&gt;'已成为“&amp; gt;”等...所以应该看起来像日志消息:< / p>
<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字符时我正在做什么,它认为它知道更好! - 或 - 是否有另一个侦听器类将以我想要的方式登录到本地XML文件?