2011-09-30 65 views
3

我有一個TraceSource.TraceEvent()的調用,有時不寫入Azure診斷日誌。當Exception消息包含不可打印的字符時,TraceSource.TraceEvent()無法記錄

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找到。是否有某些字符是不允許的,通過TraceSourceDiagnosticMonitor

爲了進一步縮小範圍,異常問題實際上是異常的InnerException:「XML文檔(72,-499)中存在錯誤」。導致異常的XML包含無效的字符實體,例如。難道是異常消息包含這些字符實體中的一部分,並且TraceSource未能記錄它們?

編輯:我終於可以在我的開發環境中重現這一點,所以我能夠在調試器中檢查異常。不會記錄的例外是XmlException

'',十六進制值0x11,是一個無效字符。 72行,位置-499。

在引號之間是不可打印的字符 - 它在調試器中顯示爲黑色三角形。所以,這讓我相信我的懷疑是正確的 - 某些日誌記錄機制不喜歡不可打印的字符。那麼,哪一塊?或者更重要的是,因爲看起來我需要在跟蹤時開始清理所有的字符串,我應該找哪些字符去除?

是否有一些內置函數可以清理字符串,刪除不可打印的字符?

回答

1

The answer to another question幫助我找出解決方案。我加了幾個擴展方法爲方便:

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,它增加了一個自然的過載時間投MyEvtEnumint額外的好處,所以這感覺就像一個雙贏。

困擾我,我必須這樣做。診斷系統的主要用途之一是記錄異常。這樣的診斷系統應該能夠處理異常消息可能包含的任何字符串。 我也失去了換行符,令人沮喪。編輯:丟失換行符是RemoveControlChars()的副作用。我沒有意識到\r\n被包含爲「控制字符」。我更新了我的正則表達式,以便不替換\r\n個字符。

我不喜歡接受我自己的答案,所以如果您有替代解決方案或對我的改進,請發佈,如果它更好,我會接受它。

+0

看起來很整齊,是的,我完全同意,這不應該發生,我懷疑你有一種方法可以替換控制字符並僅保留換行符。 –

1

有趣。它看起來像你需要HTML編碼異常字符串。這會將引號轉換爲"和您的ASCII非打印字符或類似。

所以:

trace.TraceEvent(TraceEventType.Error, 0, 
     "ex has message: " + HttpUtility.HtmlEncode(hasMsg.ToString())); 
    trace.TraceEvent(TraceEventType.Error, 0, 
     "Inner exception message: " + HttpUtility.HtmlEncode(ex.Message)); 

應該只是罰款。

令人沮喪的是,HttpUtility是在System.Web中,您需要添加一個對System.Web.dll的引用才能實現此目的。

+0

謝謝傑里米。這不是一個不好的答案,但不是我正在尋找的。我只想處理控制字符,而HTML不一定是我想要的目標編碼。 – gilly3

+0

不夠公平,但跟蹤源不喜歡非引用的XML實體,例如< and >,並且「以同樣的方式? –

相關問題