带有 DI 简单注入器的 log4net [英] log4net with DI Simple Injector

查看:20
本文介绍了带有 DI 简单注入器的 log4net的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Simple Injector(+ 集成 MVC)v 2.5.2.对于 MVC 4 应用程序,我还需要跟踪/记录性能(执行)(通过 log4net 模块).当前实现(在运行期间)在指定路径中创建 log4net 文件,但没有将任何文本行写入其中(当我调试它时,一切都没有错误到 _logger.Info("message") ).

I am trying to use Simple Injector ( + integration MVC) v 2.5.2. for an MVC 4 Application and I need to track/log performance (execution) as well(by log4net module). Current implementation (during runtime) creates log4net file in specified path but did not write any line of text into it (when I debug it everything went with no error to the end of _logger.Info("message") ).

是否有人尝试将 Simple Injector DI 用于 log4net?

Does anyone try to use Simple Injector DI for log4net?

我注册 log4net 模块的方式是:

The way how I've registered log4net module is:

public static class LoggingModule
{
    public static void RegisterServices(Container container)
    {
        string log4NetConfigFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log4net.config");
        log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(log4NetConfigFile));
        var logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        container.RegisterSingle(logger);

    }
}

在 Global.asax 中

And in Global.asax

LoggingModule.RegisterServices(container);

Log4net 的配置文件是这样的(我觉得没有什么问题):

Log4net configuration file looks like so (I dont think there is any problem):

<log4net>
  <appender name="PerformanceLogFile" type="log4net.Appender.RollingFileAppender" >
  <param name="File" value="..PerformancePricingManager" />
  <param name="AppendToFile" value="true" />
  <param name="RollingStyle" value="Date" />
  <param name="DatePattern" value="_yyyy-MM-dd.log" />
  <param name="MaxSizeRollBackups" value="10" />
  <param name="StaticLogFileName" value="false" />
  <layout type="log4net.Layout.PatternLayout">
    <param name="ConversionPattern" value="%m%n"/>
  </layout>
  <filter type="log4net.Filter.LevelRangeFilter">
    <param name="LevelMin" value="INFO" />
    <param name="LevelMax" value="FATAL" />
  </filter>
  </appender>
  <logger name="SoftTech.PricingEngine.PricingService.PerformanceStatisticLoggerWithAPI">
    <level value="ALL" />
    <appender-ref ref="PerformanceLogFile" />
  </logger>
</log4net>

并打开/关闭我一直在使用的日志记录:

And to turn on/off logging I've been using:

private static void RegisterIPerformanceStatisticLogger(Container container)
    {
        if (ShouldLogPerformance())
        {
            container.Register<IPerformanceStatisticLogger, PerformanceStatisticLogger>(WebLifestyle); 
        }
        else
        {
            // do nothing
            container.Register<IPerformanceStatisticLogger, DisabledPerformanceStatisticLogger>(WebLifestyle); 
        }
    }

和 PerformanceStatisticLogger 或 DisablePerformanceStatisticLogger 集

And PerformanceStatisticLogger or DisablePerformanceStatisticLogger sets

IsLoggingEnabled = true; // | false
IsAPITraceEnabled = false; // | true

我做错了什么?在我看来是注射方式的问题.感谢您的建议

What I am doing wrong? Seems to me the problem of the way of injection. Thanks for any advice

推荐答案

在配置 log4net 时,Simple Injector 没有什么特别之处.例如,您可以按如下方式注册 ILog:

There's nothing special about Simple Injector when it comes to configuring log4net. For instance, you can register ILog as follows:

container.RegisterSingleton<ILog>(LogManager.GetLogger(typeof(object)));

显然,这为整个应用程序注册了一个记录器.如果您想为每个类注入不同的记录器,则必须定义自己的适配器实现:

Obviously this registered a single logger for the complete application. In case you want to inject a different logger per class, you will have to define your own adapter implementation:

public sealed class Log4NetAdapter<T> : LogImpl
{
    public Log4NetAdapter() : base(LogManager.GetLogger(typeof(T)).Logger) { }
}

您可以按如下方式注册此适配器:

You can register this adapter as follows:

container.RegisterConditional(typeof(ILog),
    c => typeof(Log4NetAdapter<>).MakeGenericType(c.Consumer.ImplementationType),
    Lifestyle.Singleton,
    c => true);

这确保了每个消费者都有自己的 Log4NetAdapter 实现.

This ensures that each consumer gets its own Log4NetAdapter<T> implementation.

请注意,尽管 IMO 最好防止应用程序代码依赖于 3rd 方库抽象.我认为定义您自己的记录器抽象要好得多.

Do note though that IMO it's much better to prevent application code to take a dependency on 3rd party library abstractions. I think it's much better to define you own logger abstraction.

我对 log4net 的经验是,当 log4net 不记录任何内容时,说明您的 log4net 配置有问题.我讨厌 log4net 的一点是,当你错误配置它时,它永远不会抛出任何异常.它只是吞下并继续,这使得使用 log4net 比它应该的痛苦得多.

My experience with log4net is that when log4net doesn't log anything, there's something wrong with your log4net configuration. What I hate about log4net is that it never throws any exceptions when you misconfigured it. It just swallows and continues, which makes working with log4net much more painful than it should be.

可以提供帮助的一件事是在启动时挂钩 log4net 的 LogLog.LogReceived 事件.这允许您检查是否有任何错误.例如,这是我在以前的项目中使用的代码:

One thing that can help is hooking onto the LogLog.LogReceived event of log4net at startup. This allows you to check if there are any errors. For instance this is the code I used in a previous project:

LogLog.LogReceived += (s, e) =>
{
    if (e.LogLog.Prefix.Contains("ERROR"))
    {
        throw new ConfigurationErrorsException(e.LogLog.Message,
            e.LogLog.Exception);
    }
};

这可确保您的应用程序在 log4net 配置错误时直接停止并出现明显异常.

This makes sure your application directly stops with a clear exception when log4net is misconfigured.

这篇关于带有 DI 简单注入器的 log4net的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆