带DI Simple Injector的log4net [英] log4net with DI Simple Injector

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

问题描述

我正在尝试使用简单注入器(+集成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="..\Performance\PricingManager" />
  <param name="AppendToFile" value="true" />
  <param name="RollingStyle" value="Date" />
  <param name="DatePattern" value="_yyyy-MM-dd.lo\g" />
  <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< T> 实现。

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

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

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.

可以帮助解决的一件事是挂在 LogLog上启动时发生log4net的.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 Simple Injector的log4net的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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