我是否需要在每个窗口中配置Log4Net,或者有没有办法在基类中执行一次?

时间:2012-04-06 08:02:10

标签: c# wpf log4net

我见过的任何例子都是这样的:

ILog log = log4net.LogManager.GetLogger(typeof(MainWindow));

我不喜欢在整个地方复制/粘贴代码的想法基本上是相同的。

理想情况下,我可以在某个基类中配置记录器,并按如下方式配置Log4Net:

public ILog log = log4net.LogManager.GetLogger(typeof(MyWindowBase));

并让所有窗口继承。我可以看到的问题是MainWindow被定义为

public partial class MainWindow : Window {}

因此它已经从Window继承。

我想到了以下几点:

public partial class MyBase : Window
{
    // configure Log4Net here
}

public partial class MainWindow : MyBase
{
    // use Log4Net here
}

但这不起作用。我收到以下错误:

  

'WpfApplication3.MainWindow'的部分声明不得指定不同的基类

所以我想知道有没有一个很好的方法可以做到这一点,不需要在每个窗口中配置Log4Net?

编辑以澄清问题不在于创建基类,问题是我想知道配置Log4Net的最佳方法而无需添加此

ILog log = log4net.LogManager.GetLogger(typeof(/* Window Type */));

每个班级。

3 个答案:

答案 0 :(得分:2)

配置log4net记录器非常常见,如下所示:

class MyClass
{
    private static ILog log = log4net.LogManager.GetLogger(typeof(MyClass)); 
    ...
}

这将创建一个与该类同名的记录器,如果您希望能够根据记录器名称有选择地启用记录,这将非常方便。

请注意使用静态字段,以便实例化记录器的开销只产生一次,而不是每次实例化类。

当然,能够有选择地启用日志记录的灵活性是有代价的:您必须在每个进行日志记录的类中都有类似的声明。

除非您愿意放弃选择性启用日志记录的能力,否则我没有看到任何解决方法,在这种情况下,您可以通过单个全局记录器路由所有日志记录请求,例如:

public static class LoggingHelper
{
    public static ILog GlobalLogger
    {
        get { return _globalLogger; }
    }
    private static ILog _globalLogger = log4net.LogManager.GetLogger("Global"); 
}

您还可以组合使用这些方法:例如,您可以在记录异常时使用全局记录器(您不太可能选择性地禁用异常记录),并在某些类中使用特定于类的记录器进行调试日志记录(您可能希望有选择地启用/禁用)。

回应评论:

  

有选择地启用日志记录有什么好处?

恕我直言,主要好处是你需要instrumentation。您可以通过在您想要检测的代码库的各个部分中大量使用调试级别日志记录语句来完成此操作。因为这样的日志记录往往很冗长,所以能够有选择地只启用要检查的那些位是很好的,例如在进行故障排除时。

答案 1 :(得分:0)

我使用静态类

public static class lgr
{
#region "log4Net"
private static bool _isInfoEnabled = false;
private static bool _isWarnEnabled = false;
private static bool _isDebugEnabled = false;
private static ILog _logger;
public static ILog Logger {
    get {
        if ((_logger == null)) {
            _logger = LogManager.GetLogger("root");
            _isInfoEnabled = _logger.IsInfoEnabled;
            _isWarnEnabled = _logger.IsWarnEnabled;
            _isDebugEnabled = _logger.IsDebugEnabled;
        }
        return _logger;
    }
    set {
        if ((value == null)) {
            _logger = LogManager.GetLogger(Reflection.MethodBase.GetCurrentMethod.DeclaringType);
        } else {
            _logger = value;
        }
    }
}

public static string LoggerName {
    get { return Logger.Logger.Name; }
    set {
        if (value == null || value == string.Empty) {
            Logger = null;
        } else {
            Logger = LogManager.GetLogger(value);
        }
    }
}

public enum LogType
{
    Debug,
    Info,
    Warn,
    Error_,
    Fatal
}
public static void WriteLogError(string _message, Exception ex)
{
    if (Logger.IsErrorEnabled) {
        Logger.Error(_message, ex);
    }
}

public static void WriteLogInfo(string _message)
{
    if (_isInfoEnabled) {
        Logger.Info(_message);
    }
}

public static void WriteLogWarn(string _message)
{
    if (_isWarnEnabled) {
        Logger.Warn(_message);
    }
}
#endregion

}

然后我在应用程序的任何地方使用它

if (Logger.IsInfoEnabled()) {
    Logger.Info("Processing...");
}

WriteLogInfo(string.Format("Close time:{0}", _closeDateTime));

答案 2 :(得分:0)

不确定它是否完全解决了您的疑虑,但您可以使用:

ILog log = log4net.LogManager.GetLogger(
               System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

然后至少这种方式代码在每个实例中都是相同的,而不是必须使用:

ILog log = log4net.LogManager.GetLogger(typeof(/* Window Type */));