繁体   English   中英

从 Log4net 迁移到 .net Core 日志记录

[英]Migrating to .net Core Logging from Log4net

我想将现有代码从 .NET 4.7.2/log4net 迁移到最新的 .NET Core 版本(目前是 2.2,九月份应该是 3.0)和“默认”日志记录。

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

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

并使用像_logger.Info("Some message");这样的记录器_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>>();

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

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

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

我知道你说最好没有 3rd 方库,但我认为你会发现这个非常有用。 它是 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");              
            }
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM