2010-01-12 58 views
7

我需要一個Log4net包裝 - 在大型應用程序中暴露給許多不同的組件。我顯然希望在記錄時保留類和方法的名稱,但我會避免將類型等傳遞給我的包裝。使用包裝器時,如何保留Log4Net的日誌類和方法名?

我看過this question,這與我的非常相似,但沒有幫助。

我已經看到了它在this other question完成通過類似以下的SMT:

MethodBase methodBase = new StackTrace().GetFrame(1).GetMethod(); 
this.log.Debug(methodBase.Name + " : " + message); 

這因爲它不使用外的開箱log4net的功能是不理想的。

我想知道人們在做切線之前如何做這件事,並想出一些非常複雜的東西。任何指針(鏈接/資源/樣本)讚賞!

回答

2

我通常添加這個東西......(這是我需要的所有功能)

MethodBase.GetCurrentMethod().Name 

你總是可以創建一個log4net的包裝,把你需要的任何PARAMS(如MethodBase)?

+1

謝謝 - 我想避免傳遞類型和methodName。 – JohnIdol 2010-01-15 12:21:43

4

Log4net允許你像這個%方法那樣訪問方法名。這不是最快的操作,但如果你需要調試一些東西,你可能會很好地使用它。我相信你的問題是,如果你使用包裝,log4net將不會輸出正確的方法名稱。

要解決這個問題,你必須看看log4net如何編寫ILog實現。這基本上是內部log4net記錄器的一個包裝,因此同樣的問題也適用於ILog實現。我做了基本如下:

// define a field such as this 
private static readonly Type ThisDeclaringType = typeof(MyLogWrapper); 

// in constructor. Note: I use the internal Logger! 
this.Logger = LogManager.GetLogger(name).Logger; 

// I created a WriteLog method that calls the internal logger like this 
// you will need to translate to the internal log levels 
// message and ex are the items I want to log (ex can be null) 
this.Logger.Log(MyLogWrapper.ThisDeclaringType, log4netLevel, message, ex); 

顯然有一些事情要做呢,但提到的要點。

3

創建包裝類,像這樣...

public static class LogFourNet 
    { 
     // Define a static logger variable so that it references the 
     private static readonly ILog Log = LogManager.GetLogger(typeof(LogFourNet)); 

     static LogFourNet() 
     { 
      XmlConfigurator.Configure(
        new FileInfo(AppDomain.CurrentDomain.BaseDirectory + "log4net.config")); 
      Log.Info("Log4net is configured."); 
     } 

     public static void Info(object currentObj, string msg, [CallerLineNumber] int lineNumber = 0, 
      [CallerFilePath] string caller = "", [CallerMemberName] string memberName = "") 
     { 
      Log.Info("[" + currentObj.GetType().Namespace + "." + 
        Path.GetFileNameWithoutExtension(caller) + "." + memberName + ":" + lineNumber + "] - " + msg); 
     } 

     public static void Debug(object currentObj, string msg, [CallerLineNumber] int lineNumber = 0, 
      [CallerFilePath] string caller = "", [CallerMemberName] string memberName = "") 
     { 
      Log.Debug("[" + currentObj.GetType().Namespace + "." + 
         Path.GetFileNameWithoutExtension(caller) + "." + memberName + ":" + lineNumber + "] - " + msg); 
     } 

     public static void Error(object currentObj, string msg, [CallerLineNumber] int lineNumber = 0, 
      [CallerFilePath] string caller = "", [CallerMemberName] string memberName = "") 
     { 
      Log.Error("[" + currentObj.GetType().Namespace + "." + 
         Path.GetFileNameWithoutExtension(caller) + "." + memberName + ":" + lineNumber + "] - " + msg); 
     } 
    } 

配置以下列方式你log4net.config文件...

<configuration> 
    <configSections> 
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" /> 
    </configSections> 
    <log4net> 
    <appender name="FileAppender" type="log4net.Appender.FileAppender"> 
     <file value="logfile.log" /> 
     <appendToFile value="true" /> 
     <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%d [%t] %-5p - %m%n" /> 
     </layout> 
    </appender> 
    <root> 
     <!--LogLevel: OFF, FATAL, ERROR, WARN, INFO, DEBUG, ALL --> 
     <level value="ALL" /> 
     <appender-ref ref="FileAppender" /> 
    </root> 
    </log4net> 
</configuration> 

現在只需使用上述這些方法...

// need to pass this(current obj) as we want to log full class name 
LogFourNet.Debug(this, "started something from wrapper"); 

output: 
------- 
2017-02-04 15:38:37,549 [1] DEBUG [WebAPI_DI.Startup.Configuration:25] - started something from wrapper 
相關問題