c# - 从 Log4net 迁移到 .net Core 日志记录
问题描述
我想将现有代码从 .NET 4.7.2/log4net 迁移到最新的 .NET Core 版本(目前是 2.2,到 9 月应该是 3.0)和“默认”日志记录。
我们有很多行代码来获取类的 log4net Logger 实例,MyClass
例如:
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>>();
到目前为止,我发现的是http://www.binaryintellect.net/articles/17ee0ba2-99bb-47f0-ab18-f4fc32f476f8.aspx的一个例子,他们使用了 HttpContext.RequestServices:
INotificationHelper helper = (INotificationHelper) HttpContext.RequestServices.GetService(typeof(INotificationHelper));
我的代码也在控制台应用程序中运行,因此在这些情况下我没有 HttpContext。知道如何使用 .NET Core 解决这个问题吗?(最好没有任何第 3 方库)。请注意,我必须迁移的不仅仅是一个类,它可能多达 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");
}
}
}
}
推荐阅读
- php - 如何在我的 2 个 sql 表之间建立链接?
- python - 包含一些用于测试的数据是一个好习惯吗?
- python - 给出有效载荷中的参数列表
- javascript - 根据数据库数据的存在添加条件
- c# - 使用 C# ASP NET 为项目创建报告的 ITextPdf 7.1.13 库
- java - 如何将 2020-08-17 02:18:34+0000 转换为 Oracle DATE 类型
- scroll - SWT动态调整复合滚动的大小
- sapui5 - 具有stretchcontentheight 的IconTabBar 使我的标题在SAPUI5 中消失
- python-3.x - 是否可以继承 wx.grid.Grid 并使用我自己的元类?
- .net-core - .Net core 5.0 控制台应用程序引用在 .Net framework4.7.2 中构建的模型