12

有没有办法使用 log4net 登录并使用 LogLevel 作为参数?

也就是说,而不是写

Log.Debug("Something went wrong");

我想写这样的东西:

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

2 回答 2

13

根据此处的 log4net 文档(查看下方log4net.Core.ILogger),您可以在 ILogger 界面上使用 Log 方法。

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 等于传入的类型(上述 Log 调用中的类型)。当它找到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);
于 2012-09-24T15:41:39.797 回答
8

扩展@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);
于 2014-05-12T05:47:04.997 回答