2

我試圖使用事件源(Microsoft.Diagnostics.EventFlow.Inputs.EventSource)來創建一個由事件流(Microsoft.Diagnostic.EventFlow)處理的事件和其輸出傳遞給Application Insights(Microsoft.Diagnostics.EventFlow.Outputs.ApplicationInsights)進行分析。EventSource中使用System.Exception對象

事件流庫似乎要求我將完整的System.Exception對象傳遞給事件流,以便在Application Insights中將它成功分類爲異常事件。

這裏是我使用事件流爲我的異常過濾器:

{ 
     "type": "metadata", 
     "metadata": "exception", 
     "include": "EventId == 21", 
     "exceptionProperty": "shark" 
    } 

這裏是我的方法,我在哪裏目前產生的事件,我想與事件流處理。目前這確實出現在應用程序洞察中,但是我相信我在運行時在輸出窗口中看到下面的消息時實施得很差。

Event方法的參數與WriteEvent方法的參數不匹配。這可能會導致事件顯示不正確。

private const int TestExceptionEventId = 21; 
    [NonEvent] 
    public void TestException(string operationType, Exception ex) 
    { 
     string shark = ex.ToString(); 
     TestException(operationType, shark); 
     WriteEvent(TestExceptionEventId, operationType, ex); 
    } 

    [Event(TestExceptionEventId, Level = EventLevel.Error, Message = "{0} - {1}, {2}", Keywords = Keywords.Exception)] 
    public void TestException(string operationType, string shark) 
    { 

    } 

這裏就是記錄事件被觸發的方法:

//EXCEPTION 
//id = 21 
try 
{ 
    int value = 1/int.Parse("0"); 
} 
catch (DivideByZeroException exception) 
{ 
    //id = 21 
    _eventSource.TestException("hello", exception); 
}` 

誰能提供正確的方法比較清楚實現這一點,什麼是通過一個系統的正確方法。通過事件流和在應用程序見解上的異常對象。

很多謝謝。

回答

4

這裏有兩個單獨的問題。一個是你得到的錯誤,另一個是異常元數據的EventFlow配置。我會解決這兩個問題。

錯誤

裝飾有該[Event]屬性的方法是,應該調用WriteEvent之一。例如:

private const int TestExceptionEventId = 21; 

[NonEvent] 
public void TestException(string operationType, Exception ex) 
{ 
    string shark = ex.ToString(); 
    TestException(operationType, shark); 
} 

[Event(TestExceptionEventId, Level = EventLevel.Error, Message = "{0} - {1}", Keywords = Keywords.Exception)] 
public void TestException(string operationType, string shark) 
{ 
    WriteEvent(TestExceptionEventId, operationType, shark); 
} 

注意:您的原始郵件屬性的值爲Message = "{0} - {1}, {2}",但你的方法(串operationType和字符串鯊魚)只提供2個參數。因此錯誤。這就是爲什麼我將其更改爲Message = "{0} - {1}"

有一些具體的規則,以使其工作。從docs

當您實現在EventSource派生類中標識爲ETW事件的方法時。你必須調用基類WriteEvent方法傳遞事件ID和相同的參數實現的方法

EventFlow配置

就出在這裏的最大問題。 EventSource類不允許您使用WriteEvent來編寫非基元。這包括一個Exception。從docs

如果事件有附加數據,這些應該作爲參數傳遞。目前只有原始類型,日期時間和字符串被允許記錄在事件中。

上有GitHub庫,列出您的可能性的issue

我覺得你有幾種選擇。

一個是使用EventSource.Write方法https://msdn.microsoft.com/en-us/library/system.diagnostics.tracing.eventsource.write(v=vs.110).aspx如果您使用的是.NET Core,這應該很好,但我會誠實 - 我沒有測試過它。不幸的是,使用完整框架時,框架中存在一個錯誤,它會阻止EventFlow正確讀取事件級別,因此如果您使用完整(桌面)框架,則不推薦使用這種方法。

第二個選擇是使用不同的日誌記錄庫(例如Serilog),它允許您將任意對象傳遞到EventFlow中。

另一種選擇是使用自定義EventFlow輸入。這應該不像AI的自定義輸出那樣麻煩。我想你甚至可以將它與你的EventSource集成,例如通過使EventSource實現IObservable並使用[NonEvent]方法來引發攜帶異常對象的事件。這樣你將只有一個日誌API,你的EventSource,供應用程序使用。

我的2美分

我的建議(我落得這樣做):忘記的EventSource和使用其他日誌庫。關於使用EventSource最好的部分是它具有結構化日誌功能。我結束了使用SeriLog,這也是如此。它確實支持寫入日誌的非原始類型。 EventFlow supports SeriLog也作爲輸入,或者您可以配置將數據發送到Application Insights的SeriLog的Application Insights (AI) sink

如果你決定去那個選項,你可以看看my implementation

相關問題