从 Log4net 迁移到 .net Core Logging



我想将现有代码从.NET 4.7.2/log4net迁移到最新的.NET Core版本(当前为2.2,到9月应该是3.0(和"默认"日志记录。

我们有很多行代码来获取类MyClass的log4net Logger实例,例如:

private static ILog _logger = LogManager.GetLogger(typeof(MyClass));

并像_logger.Info("Some message");一样使用记录器

我找到的大多数示例和文档都在类构造函数中使用依赖注入,例如:

public class AboutModel : PageModel
{
    private readonly ILogger _logger;
    public AboutModel(ILogger<AboutModel> logger)
    {
        _logger = logger;
    }

记录器是这样使用的:

_logger.LogInformation("Message displayed: {Message}", Message);

对我来说,迁移的最大问题是它是由构造函数中的 DI 传递的,这可能很好,就像在 MVC 控制器的例子中一样,但在我遇到的其他几个类中存在问题,因为破坏了构造函数的签名。

我正在寻找一个不会破坏构造函数签名的实现(例如 Xamarin 中的 DI,这将使迁移过程更容易( - 类似于:

private static ILogger _logger = DependencyService.Get<ILogger<MyClass>>();

到目前为止,我发现的是在他们使用HttpContext.RequestServices的 http://www.binaryintellect.net/articles/17ee0ba2-99bb-47f0-ab18-f4fc32f476f8.aspx 的例子:

INotificationHelper helper = (INotificationHelper) HttpContext.RequestServices.GetService(typeof(INotificationHelper));

我的代码也在控制台应用程序中运行,因此在这些情况下我没有 HttpContext。知道如何用.NET Core解决这个问题吗?(最好没有任何第三方库(。请注意,我不仅要迁移一个类,最多可能有 1000 个类。

我知道你说最好没有第三方库,但我认为你会发现这个非常有用。它是Microsoft.Extensions.Logging.Log4net.AspNetCore。 下面是如何使用它的示例

using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging;
using System.IO;
using System.Reflection;
namespace TryLog4net
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }
        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
            .ConfigureLogging((hostingContext, logging) =>
            {
                var assembly = Assembly.GetAssembly(typeof(Program));
                var pathToConfig = Path.Combine(
                          hostingContext.HostingEnvironment.ContentRootPath
                        , "log4net.config");
                 var logManager = new AppLogManager(pathToConfig, assembly);
                logging.AddLog4Net(new Log4NetProviderOptions
                {
                    ExternalConfigurationSetup = true
                });
            })
            .UseStartup<Startup>();
    }
}

在项目的根目录中放置您的 log4net.config 文件。 一个例子是

<?xml version="1.0" encoding="utf-8" ?>
<log4net>
  <appender name="DebugAppender" type="log4net.Appender.DebugAppender" >
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
    </layout>
  </appender>
  <root>
    <level value="ALL"/>
    <appender-ref ref="DebugAppender" />
  </root>
</log4net>

这是一种无需按照要求使用依赖注入即可获取记录器的方法。

using log4net;
using System;
using System.IO;
using System.Reflection;
namespace TryLog4net
{
    public class AppLogManager 
    {
        private static AppLogManager _logManager = null;
        private AppLogManager()
        {    
        }    
        public AppLogManager(string fullConfigFilePath, Assembly assembly)
        {
            var logRepo = log4net.LogManager.GetRepository(assembly);
            log4net.Config.XmlConfigurator.Configure(logRepo, new FileInfo(fullConfigFilePath));
            _logManager = new AppLogManager();
        }
        public static ILog GetLogger<T>()
        {
            return _logManager.GetLogger(typeof(T));
        }
        public ILog GetLogger(Type type)
        {
            var log = log4net.LogManager.GetLogger(type);
            return log;
        }
    }
    public static class GenericLoggingExtensions
    {
        public static ILog Log<T>(this T thing)
        {
            var log = AppLogManager.GetLogger<T>();
            return log;
        }
    }
}

下面是一个非常简单的示例启动文件,用于创建日志消息。

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
namespace TryLog4net
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        { 
        }
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.Run(async (context) =>
            {
                var testClass = new TestClass();
                testClass.LogSomething();
                await context.Response.WriteAsync("Hello World!");
            }); 
        }
        public class TestClass
        {
            public void LogSomething()
            {
                var logger = this.Log();
                logger.Info("my message");              
            }
        }
    }
}

相关内容

  • 没有找到相关文章

最新更新