2013-09-27 75 views

回答

1

使用一個額外的事件和火災catch塊這一事件,並與級別和關鍵字傳遞異常消息作爲參數傳遞給事件

[Event(1, Message = "Application Falure: {0}", Level = EventLevel.Error, Keywords = Keywords.Diagnostic)] 
public void Failure(string message) 
{ 
    if (this.IsEnabled()) 
    { 
     this.WriteEvent(1, message); 
    } 
} 

播放控制,如果你想記錄這一切的時間與否。

+0

因爲你不能對EventSource使用強類型異常,所以我最好只是這樣調用它:EventSource.Log.Failure(MyException.ToString())? – jaffa

+0

這可以。 – magicandre1981

1

ETW不是.NET特有的,因此不會有任何強類型的.NET特定API來記錄.net異常。你會改爲創建自己的強類型API。這是語義記錄和語義記錄應用程序塊的思想。

+0

因此在一天結束時爲了使用ETW只能使用原始數據類型,字符串和數字(​​以字符串的形式)?純粹將Exception序列化爲一個足夠好的字符串?或者是否有非模式的應用程序追蹤異常? – BozoJoe

+1

ETW是一種二進制有效載荷,支持您定義的結構。 http://msdn.microsoft.com/en-us/library/windows/desktop/aa382774(v=vs.85).aspx 只是,當你走這條路線,你必須寫一個自定義的解碼器。在.NET的情況下,.NET團隊已經提供了一個明確的定義。 但是,像本機代碼中的許多事情一樣,有多種方法可以實現。 C++異常? SEH例外?等等。例外的最感興趣的部分是由ETW標準化的callstack(以及它的EIPs,以獲得行號),以及它的步行者。除此之外的任何信息都是您的電話。 – mjsabby

17

CLR運行時提供程序在啓用時會記錄所有CLR異常(第一次機會以及可能最終導致應用程序中斷的異常)。

這是一個完全「結構化」的事件與調用堆棧(如果你想要他們)。事實上,你可以寫使用TraceEvent NuGet包監視應用程序(安裝,包裝Microsoft.Diagnostics.Tracing.TraceEvent

我貼上監管碼我經常使用。把它放在一個控制檯應用程序中,調用Run方法,並從任何進程中拋出一些託管異常,它將打印信息和它們的調用堆棧。

注意:您需要引用的NuGet包,然後引用其程序集,然後編譯此代碼。

class TraceLogMonitor 
{ 
    static TextWriter Out = AllSamples.Out; 

    public static void Run() 
    { 
     var monitoringTimeSec = 10; 
     TraceEventSession session = null; 

     Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs cancelArgs) => 
     { 
      if (session != null) 
       session.Dispose(); 
      cancelArgs.Cancel = true; 
     }; 

     var exceptionGeneationTask = Task.Factory.StartNew(delegate 
     { 
      Thread.Sleep(3000); 
      ThrowException(); 
     }); 

     Timer timer = null; 

     using (session = new TraceEventSession("TraceLogSession")) 
     { 
      Out.WriteLine("Enabling Image load, Process and Thread events. These are needed to look up native method names."); 
      session.EnableKernelProvider(

       KernelTraceEventParser.Keywords.ImageLoad | 
       KernelTraceEventParser.Keywords.Process, 
       KernelTraceEventParser.Keywords.None 
       ); 

      Out.WriteLine("Enabling CLR Exception and Load events (and stack for those events)"); 

      session.EnableProvider(
       ClrTraceEventParser.ProviderGuid, 
       TraceEventLevel.Informational, 
       (ulong)(ClrTraceEventParser.Keywords.Jit |    
       ClrTraceEventParser.Keywords.JittedMethodILToNativeMap | 
       ClrTraceEventParser.Keywords.Loader |     
       ClrTraceEventParser.Keywords.Exception |    
       ClrTraceEventParser.Keywords.Stack));     

      Out.WriteLine("Enabling CLR Events to 'catch up' on JIT compiled code in running processes."); 
      session.EnableProvider(ClrRundownTraceEventParser.ProviderGuid, TraceEventLevel.Informational, 
       (ulong)(ClrTraceEventParser.Keywords.Jit |   
       ClrTraceEventParser.Keywords.JittedMethodILToNativeMap | 
       ClrTraceEventParser.Keywords.Loader |    
       ClrTraceEventParser.Keywords.StartEnumeration));  

      TextWriter SymbolLookupMessages = new StringWriter(); 

      var symbolPath = new SymbolPath(SymbolPath.SymbolPathFromEnvironment).Add(SymbolPath.MicrosoftSymbolServerPath); 
      SymbolReader symbolReader = new SymbolReader(SymbolLookupMessages, symbolPath.ToString()); 

      Out.WriteLine("Open a real time TraceLog session (which understands how to decode stacks)."); 
      using (TraceLogEventSource traceLogSource = TraceLog.CreateFromTraceEventSession(session)) 
      { 
       Action<TraceEvent> PrintEvent = ((TraceEvent data) => Print(data, symbolReader)); 

       traceLogSource.Clr.ExceptionStart += PrintEvent; 
       traceLogSource.Clr.LoaderModuleLoad += PrintEvent; 

       traceLogSource.Kernel.PerfInfoSample += ((SampledProfileTraceData data) => Print(data, symbolReader)); 

       Out.WriteLine("Waiting {0} sec for Events. Run managed code to see data. ", monitoringTimeSec); 
       Out.WriteLine("Keep in mind there is a several second buffering delay"); 

       timer = new Timer(delegate(object state) 
       { 
        Out.WriteLine("Stopped Monitoring after {0} sec", monitoringTimeSec); 
        if (session != null) 
         session.Dispose(); 
        session = null; 
       }, null, monitoringTimeSec * 1000, Timeout.Infinite); 

       traceLogSource.Process(); 
      } 
     } 
     Out.WriteLine("Finished"); 
     if (timer != null) 
      timer.Dispose(); 
    } 

    static void Print(TraceEvent data, SymbolReader symbolReader) 
    { 
     if (data.Opcode == TraceEventOpcode.DataCollectionStart) 
      return; 

     if (data is ExceptionTraceData && ((ExceptionTraceData) data).ExceptionType.Length == 0) 
      return; 

     Out.WriteLine("EVENT: {0}", data.ToString()); 
     var callStack = data.CallStack(); 
     if (callStack != null) 
     { 
      ResolveNativeCode(callStack, symbolReader); 
      Out.WriteLine("CALLSTACK: {0}", callStack.ToString()); 
     } 
    } 

    static private void ResolveNativeCode(TraceCallStack callStack, SymbolReader symbolReader) 
    { 
     while (callStack != null) 
     { 
      var codeAddress = callStack.CodeAddress; 
      if (codeAddress.Method == null) 
      { 
       var moduleFile = codeAddress.ModuleFile; 
       if (moduleFile == null) 
        Trace.WriteLine(string.Format("Could not find module for Address 0x{0:x}", codeAddress.Address)); 
       else 
        codeAddress.CodeAddresses.LookupSymbolsForModule(symbolReader, moduleFile); 
      } 
      callStack = callStack.Caller; 
     } 
    } 

    [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)] 
    private static void ThrowException() 
    { 
     ThrowException1(); 
    } 

    [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)] 
    private static void ThrowException1() 
    { 
     Out.WriteLine("Causing an exception to happen so a CLR Exception Start event will be generated."); 
     try 
     { 
      throw new Exception("This is a test exception thrown to generate a CLR event"); 
     } 
     catch (Exception) { } 
    } 
} 
相關問題