2012-09-24 49 views
7

有沒有辦法用log4net登錄並使用LogLevel作爲參數?用log4net記錄日誌級別作爲參數

也就是說,不是寫作

Log.Debug("Something went wrong"); 

我想編寫這樣的事:

Log("Something went wrong", LogLevel.Debug); 
+0

那麼你可以擴展的類,但我susopect你需要講的是你爲什麼要做出這種改變。 –

+0

這主要是爲了方便。我有一個應用程序,可以作爲Windows服務或控制檯應用程序運行。作爲控制檯應用程序運行時,應將日誌打印到屏幕上而不是文件中。由於已經實現了日誌記錄的方法,因此將loglevel作爲參數。我知道我可能可以使用控制檯appender作爲log4net,但我不知道如何決定在編譯期間使用哪些appender。 – olif

回答

8

根據log4net的文檔here(看log4net.Core.ILogger下),你可以使用日誌方法在ILogger接口上。

private static ILog logger = 
    LogManager.GetLogger(
    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 

logger.Logger.Log(logger.GetType(),LogLevel.Debug,"Something went wrong", ex); 

對於log4net,Type參數用於確定記錄代碼和應用程​​序代碼之間的調用堆棧中的邊界。如果您啓用了方法名稱記錄,log4net將導航調用堆棧,直到堆棧中MethodInfo的DeclaringType等於傳入的Type(上述Log調用中的Type)。當它發現DeclaringType時,調用堆棧中的下一個方法是實際的調用方法(應用程序代碼)。

您還可以使用採用LoggingEvent結構的超載。

該文檔還指出,Log方法旨在被包裝器使用。我不知道這是否應該被視爲「信息性」信息或強烈建議不要直接使用它。

如果要通過Log方法進行所有日誌記錄調用,可以更改記錄器的代碼,使其可以像這樣(因此可以消除每次Log調用時使用Logger屬性):

private static ILogger logger = 
    LogManager.GetLogger(
    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType).Logger; 

logger.Log(logger.GetType(),LogLevel.Debug,"Something went wrong", ex); 
6

上@ wageoghe的答案擴展,我已經寫了下面的擴展方法:

public static bool Log(this ILog log, Level level, string message, Exception exception = null) 
{ 
    var logger = log.Logger; 
    if (logger.IsEnabledFor(level)) 
    { 
     logger.Log(logger.GetType(), level, message, exception); 
     return true; 
    } 

    return false; 
} 

public static bool LogFormat(this ILog log, Level level, string messageFormat, params object[] messageArguments) 
{ 
    var logger = log.Logger; 
    if (logger.IsEnabledFor(level)) 
    { 
     var message = string.Format(messageFormat, messageArguments); 
     logger.Log(logger.GetType(), level, message, exception: null); 

     return true; 
    } 

    return false; 
}  

這允許你撥打電話如:

Log.Log(Level.Debug, "Something went wrong", myException); 

或格式化消息:

Log.Log(Level.Info, "Request took {0:0} seconds", duration.TotalSeconds); 
+0

這正是我所需要的,我需要在一個層次上進行常規登錄,但有時也會超出層面,以便我可以根據需要將日誌文件轉儲到日誌文件中。 –

+0

這很好,但爲了更靈活,第一個方法應該接受'object message'而不是'string message'。 – Miral