2016-06-07 36 views
0

有一個webforms應用程序的類包含很多方法。我想以一種靈活而簡單的方式保存被調用方法的日誌。 我想知道哪種方法終於被稱作以及其他一些附加信息,如:什麼日誌系統用於C#中的方法?

  • 輸入值和
  • 結果值
  • 崩潰異常(如果有崩潰)

目前,我正在使用log4net進行文件系統日誌記錄,例如:

using log4net; 
private static readonly ILog Log1 = LogManager.GetLogger("Log1"); 

public int DoSomething(int itemId = 0) 
{ 
    Log1.DebugFormat("[DoSomething] - Doing Something on item {0} Started", itemId); 

    try 
    { 
     //something.. 
    } 
    catch (Exception ex) 
    { 
     Log1.Debug("[DoSomething] - Something Failed", ex); 
    } 

    Log1.DebugFormat("[DoSomething] - Doing Something on item {0} Finished", itemId); 

    return 0; 
} 

如何在不用每次寫入每個方法中的這些代碼塊的情況下實現這一點?有更好的自動方法嗎? 每種情況下的性能成本如何?

另一種方法會很棒!

+2

解決此問題的常用方法是使用AOP(Aspect Oriented Programming)。 PostSharp(https://www.postsharp.net/)是這個範例的一個實例,但也有其他的例子。 – Evk

+0

這似乎是一種方法。你曾經使用postsharp @Evk? –

+0

是的,我一直使用它(我有付費版本,但免費版本應該足以實現你想要的)。 – Evk

回答

1

下面的代碼應該給你一個出發點。這是一個使用控制檯而不是log4net的示例,但我認爲擴展它以使用任何您需要的內容是微不足道的。

首先安裝PostSharp nuget包。然後定義新的方面:

[Serializable] 
public sealed class TraceAttribute : OnMethodBoundaryAspect 
{   
    private readonly string _argumentsFormat;   
    [NonSerialized] 
    private string _methodName;   

    public TraceAttribute() { 

    } 

    public TraceAttribute(string argumentsFormat) { 
     _argumentsFormat = argumentsFormat; 
    } 

    public override void RuntimeInitialize(MethodBase method) { 
     _methodName = method.Name; 
    } 

    public override void OnEntry(MethodExecutionArgs args) { 
     string msg = $"[{_methodName}]: entered"; 
     if (!String.IsNullOrWhiteSpace(_argumentsFormat)) { 
      msg += String.Format(". Arguments:" + _argumentsFormat, args.Arguments.ToArray()); 
     } 
     Console.WriteLine(msg); 
    } 

    // Invoked at runtime after the target method is invoked (in a finally block). 
    public override void OnExit(MethodExecutionArgs args) { 
     string msg = $"[{_methodName}]: exited"; 
     if (!String.IsNullOrWhiteSpace(_argumentsFormat)) { 
      msg += String.Format(". Arguments: " + _argumentsFormat, args.Arguments.ToArray());     
     } 
     Console.WriteLine(msg); 
    } 

    public override void OnException(MethodExecutionArgs args) { 
     string msg = $"[{_methodName}]: exception"; 
     if (!String.IsNullOrWhiteSpace(_argumentsFormat)) 
     { 
      msg += String.Format(". Arguments: " + _argumentsFormat, args.Arguments.ToArray());     
     } 
     msg += ". Details: " + args.Exception.ToString(); 
     Console.WriteLine(msg); 
    } 
} 

我們基本上做到這裏繼承MethodBoundaryAspect並確定輸入的目標的方法時,應執行什麼代碼,退出,而當異常被拋出。像這樣使用它:

public class Program { 
    static void Main(string[] args) { 
     TestStuff(1); 
     TestStuff(2); 
     TestStuff(3); 
     Console.ReadKey(); 
    } 

    [Trace("itemId: {0}")] 
    static void TestStuff(int itemId) { 
     Console.WriteLine("Inside TestStuff: " + itemId); 
     if (itemId == 3) 
      throw new Exception("Test exception"); 
    } 
} 

您也可以將該屬性應用於整個類。在這種情況下 - 該類中的所有方法都將被跟蹤。

+0

我會試一試@Evk,我會回來 –