[英]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.