C# 当异常消息包含不可打印的字符时,TraceSource.TraceeEvent()无法记录日志
我有一个对C# 当异常消息包含不可打印的字符时,TraceSource.TraceeEvent()无法记录日志,c#,logging,unicode,azure,azure-diagnostics,C#,Logging,Unicode,Azure,Azure Diagnostics,我有一个对TraceSource.TraceEvent()的调用,该调用有时不会写入Azure诊断日志 public class WorkerRole : RoleEntryPoint { private TraceSource trace = new TraceSource( "ImportService", SourceLevels.Information); public override void Run() { ...
TraceSource.TraceEvent()
的调用,该调用有时不会写入Azure诊断日志
public class WorkerRole : RoleEntryPoint
{
private TraceSource trace = new TraceSource(
"ImportService", SourceLevels.Information);
public override void Run()
{
...
try
{
...
}
catch (Exception ex)
{
bool hasMsg = !string.IsNullOrEmpty(ex.Message);
trace.TraceEvent(TraceEventType.Error, 0,
"ex has message: " + hasMsg.ToString()); // this gets logged
trace.TraceEvent(TraceEventType.Error, 0,
"Inner exception message: " + ex.Message); // this does not
}
}
}
在某些情况下,由于我无法读取异常消息,所以无法判断是哪个,第二个调用在WADLogsTable中找不到。是否有某些字符是不允许的,TraceSource
或DiagnosticMonitor
为了进一步缩小范围,所讨论的异常实际上是异常的InnerException
:“XML文档(72,-499)中有一个错误”。导致异常的XML包含无效的字符实体,例如代码>。是否异常消息包含一些字符实体,而TraceSource
无法记录它们
编辑:我终于能够在我的开发环境中重新编程,因此我能够在调试器中检查异常。不会记录的异常是XmlException
:
'',十六进制值0x11,是无效字符。第72行,位置-499
引号之间是不可打印的字符-它在调试器中显示为黑色三角形。所以,这让我相信我的怀疑是正确的——一些日志机制不喜欢不可打印的字符。那么,哪一块?或者,更重要的是,由于跟踪时需要开始清理所有字符串,我应该查找哪些字符来删除
是否有一些内置函数可以清理字符串,删除不可打印的字符?很有趣。看起来您需要对异常字符串进行HTML编码。这会将引号转换为例如“
,将ASCII非打印字符转换为;
,或类似字符
因此:
应该很好用
令人沮丧的是,HttpUtility
位于System.Web中,您需要添加对System.Web.dll的引用才能执行此操作。帮助我找到了解决方案。为了方便起见,我添加了两种扩展方法:
public static string RemoveControlChars(this string s)
{
return Regex.Replace(s, @"(?![\r\n])\p{Cc}", "");
}
public static void TraceEvent(this TraceSource trace,
TraceEventType eventType, MyEvtEnum eventId, string message)
{
trace.TraceEvent(eventType, (int)eventId, message.RemoveControlChars());
}
我喜欢不必每次调用TraceEvent
时都将MyEvtEnum
转换为int
的额外好处,这会增加一个自然过载,因此感觉这是一个双赢的结果
我不得不这么做,这让我很烦恼。诊断系统的主要用途之一是记录异常。这样的诊断系统应该能够处理异常消息可能包含的任何字符串。我也会丢失换行符,这令人沮丧。Edit:丢失换行符是RemoveCo的副作用ntrolChars()
。我没有意识到\r
和\n
包含在“控制字符”中。我已更新了正则表达式,以不替换\r
和\n
字符
我不喜欢接受我自己的答案,因此如果您有其他解决方案或我的改进,请发布,如果更好,我会接受。谢谢Jeremy。这不是一个糟糕的答案,但不完全是我想要的。我只想处理控制字符,HTML不一定是我想要的目标编码。足够公平,但跟踪源是否不喜欢像和“以同样的方式”这样的非引用XML实体?这看起来很整洁。是的,我完全同意,这不应该发生。我想有一种方法可以替换控制字符,而不使用换行符。
public static string RemoveControlChars(this string s)
{
return Regex.Replace(s, @"(?![\r\n])\p{Cc}", "");
}
public static void TraceEvent(this TraceSource trace,
TraceEventType eventType, MyEvtEnum eventId, string message)
{
trace.TraceEvent(eventType, (int)eventId, message.RemoveControlChars());
}