默认在 dotnet 里面框架提供了 Microsoft.Extensions.Logging 可以和依赖注入做日志框架,而有些业务,如需要自己定制日志行为,此时就需要定制日志 当初写一个类继承 ILogger inheritdoc /> public void Dispose() { } /// <inheritdoc /> public ILogger { return new CCloudConsoleLogger(); } class CCloudConsoleLogger : ILogger builder.ClearProviders(); builder.AddProvider(new CCloudConsoleLogProvider()); }); 现在所有拿到的 ILogger return new CCloudConsoleLogger(categoryName); } class CCloudConsoleLogger : ILogger
如果日志记录方法定义未显式包含 ILogger 类型的参数,则包含日志记录方法的类型必须有一个(且只有一个)类型为 ILogger 的字段。 ILogger 将用作日志消息的目标。 解决方法 确保包含日志记录方法的类型包含 ILogger 类型的字段,或者在日志记录方法签名中包含 ILogger 类型的参数。 禁止显示警告 建议尽量使用解决方法之一。
如果日志记录方法定义未显式包含 ILogger 类型的参数,则包含日志记录方法的类型必须有一个(且只有一个)类型为 ILogger 的字段,该字段将用作日志消息的目标。 解决方法 确保包含日志记录方法的类型仅包含类型为 ILogger 的单个字段。 禁止显示警告 建议尽量使用解决方法之一。
使用 LoggerMessageAttribute 进行注释的方法的参数之一必须是 ILogger 类型或实现 ILogger 的类型。 解决方法 确保所有日志记录方法的参数的类型是 ILogger,或者是实现 ILogger 的类型。 禁止显示警告 建议尽量使用解决方法之一。
当然更常用的是在其它类中通过构造函数注入,使用 DI 中的 ILogger 对象(TCategoryName 类别字符串是任意的,但约定将使用类名称,在日志中能知道是哪个类输出的)。 public class TestLog { private readonly ILogger _logger; public TestLog(ILogger<TestLog builder.AddConsole(); builder.SetMinimumLevel(LogLevel.Debug); }); ILogger
(void); 161 virtual ~ILogger(void); 162 private: 163 ILogger(const ILogger&); 164 ILogger 对象 251 EXTERN_C LOGGER_API ILogger* ILogger_Create(); 252 // 销毁 ILogger 对象 253 EXTERN_C LOGGER_API void 调用 ILogger_Create() 导出函数创建 ILogger 对象 2. 调用 ILogger->Init(...) 初始化日志组件 3. 调用 ILogger_Destroy() 导出函数销毁 ILogger 对象 2、CStaticLogger:ILogger 包装器(智能指针)—— 用于静态加载 Logger DLL 1 对象 79 ILogger* ILogger_Create() 80 {return m_fnILoggerCreate();} 81 // 销毁 ILogger
2.2.2 核心模块--日志 ILogger 的使用 日志的 ID 日志的分类 日志的级别 LoggerProvider 日志的最佳实践 .NET Core 和 ASP.NET Core 中的日志记录: view=aspnetcore-5.0 ILogger 的使用 在 Get 方法中添加日志 WeatherForecastController.cs private readonly ILogger<WeatherForecastController > _logger; public WeatherForecastController(ILogger<WeatherForecastController> logger) { _logger <WeatherForecastController> _logger; private readonly ILogger _myLogger; public WeatherForecastController </param> /// <returns></returns> ILogger CreateLogger(string categoryName); } }
ILogger接口中定义了如下三个方法Log、IsEnabled和BeginScope。 除了ILogger这个基本的接口,日志模型中还定义了如下一个泛型的ILogger <TCategoryName>接口,它派生与ILogger接口并将泛型参数的类型名称作为由它写入的日志消息的类型。 1: public interface ILogger<out TCategoryName> : ILogger 2: {} Logger<TCategoryName>实现了ILogger <TCategoryName factory) ; 4: 5: IDisposable ILogger.BeginScope<TState>(TState state; 6: void ILogger.Log 1: public class ConsoleLogger : ILogger 2: { 3: private IList<ILogger> loggers; 4: public
简单的例子 一般来说类库里的日志模块会使用静态方法,将日志的各种操作放在一个静态类中,比如下面的代码: public static void MiaoShuLog(this ILogger logger EventId = 0, Message = "Logging generator sample begin")] public static partial void TestBegin(this ILogger = "Logging generator sample end", SkipEnabledCheck = true)] public static partial void TestEnd(this ILogger _logger; public InstanceLoggingGenerator(ILogger logger) { _logger = logger; } 实例,它会自动从类型中寻找ILogger类型的字段,可以想一下如果类型中有多个ILogger 字段会怎么样?
2.2.2 核心模块--日志 ILogger 的使用 日志的 ID 日志的分类 日志的级别 LoggerProvider 日志的最佳实践 .NET Core 和 ASP.NET Core 中的日志记录: view=aspnetcore-5.0 ILogger 的使用 在 Get 方法中添加日志 WeatherForecastController.cs private readonly ILogger<WeatherForecastController > _logger; public WeatherForecastController(ILogger<WeatherForecastController> logger) { _logger <WeatherForecastController> _logger; private readonly ILogger _myLogger; public WeatherForecastController </param> /// <returns></returns> ILogger CreateLogger(string categoryName); } } 日志的设计模式
一提到日志记录,大家就会想到log4net,如果提到.NET中的日志记录,一定会想到ILogger,这个ILogger是.NET中常用的提供的日志记录的方式,下面的代码是.NET Core WebAPI 项目初始化的代码,其中就使用了ILogger来提供日志记录: private readonly ILogger<WeatherForecastController> _logger; public WeatherForecastController 与ILogger记录器和它的扩展方法相比,LoggerMessage更具性能优势。 首先ILogger记录器扩展方法需要将值类型转换到object中,但是LoggerMessage使用了带有强类型参数的静态方法以及扩展方法来避免这个问题。 并且ILogger记录器及其扩展方法在每次写入日志时都必须先去分析消息模板,但是LoggerMessage在已定义消息模板的情况下,只需分析一次模板即可。
类和一个ConsoleLogger类,它们都实现了ILogger接口:public class FileLogger implements ILogger { public void log(String (String message) { // 将日志输出到控制台中 }}这样,我们就可以通过ILogger接口来定义Logger类的依赖关系,而不需要依赖于具体实现。 以下是一个使用构造函数注入的示例:public class Service { private ILogger logger; public Service(ILogger logger) 接口,而ILogger的具体实现通过构造函数注入到Service类中。 这样,我们就可以在运行时动态地传递ILogger的具体实现,而不需要在Service类中硬编码依赖关系。
我们通过调用ILogger的Log方法针对每个有效的日志等级分发了六个日志事件,事件的ID分别被设置成1~6的整数。 ILoggerFactory工厂的CreateLogger方法来创建对应的ILogger对象,实际上我们还可以调用泛型的CreateLogger<T>方法创建一个ILogger<T>对象来完成相同的工作 ", level)); Console.Read(); [S803]注入Ilogger<T>对象 除了利用ILoggerFactory工厂来创建泛型的ILogger<Program>对象之外,我们还具有更简洁的方式 换句话说,ILogger<T>实际上是可以作为依赖服务注入到消费它的类型中。 图2 对TraceSource和EventSource的日志输出 [S805]针对等级的日志过滤 对于使用ILogger或者ILogger<T>对象分发的日志事件,并不能保证都会进入最终的输出渠道,因为注册的
1.2 基于简单工厂的代码实现 M公司的程序猿按照结构图,写下了核心代码LoggerFactory的CreateLogger方法: // 简单工厂方法 public static ILogger 3.2 重构代码 (1)抽象产品:ILogger接口 public interface ILogger { void WriteLog(); } (2)具体产品 :FileLogger和DatabaseLogger类 public class FileLogger : ILogger { public void WriteLog( CreateLogger() { // 连接数据库,代码省略 // 创建数据库日志记录器对象 ILogger logger logger = this.CreateLogger(); logger.WriteLog(); } public abstract ILogger
例如: var logger = serviceProvider.GetService<ILogger<Program>>(); logger.LogDebug($"系统初始化完成..."); 在Asp.Net Core应用中记录日志 由于在IWebHostBuilder.CreateDefaultBuilder()方法中,系统已经帮我们初始化了日志组件,因此我们可以直接使用ILogger<T>进行注入。 controller]")] [ApiController] public class WelcomeController : ControllerBase { private readonly ILogger <WelcomeController> logger; public WelcomeController(ILogger<WelcomeController> logger) { 当我们使用ILogger<T>创建日志对象时,日志类别默认为泛型T的类名。
"UserName": "zhangsan" } } 代码: public class HomeController : Controller { private readonly ILogger HomeController> _logger; private readonly IConfiguration _configuration; public HomeController(ILogger 例: public class HomeController : Controller { private readonly ILogger<HomeController> _logger; private UserService _userService; public HomeController(ILogger<HomeController> logger, UserService }); 使用也是一样的: public class HomeController : Controller { private readonly ILogger
并且释放是在Dispose上 internal class TimedHostedService : IHostedService, IDisposable { private readonly ILogger _logger; private Timer _timer; public TimedHostedService(ILogger<TimedHostedService> logger 下面的例子中,一个ILogger被注入到了service中: internal interface IScopedProcessingService { void DoWork(); } internal class ScopedProcessingService : IScopedProcessingService { private readonly ILogger _logger; public ScopedProcessingService(ILogger<ScopedProcessingService> logger) { _logger = logger
Microsoft.Extensions.Logging.Abstractions 有三个主要接口: ILogger 用于输出日志 ILoggerFactory 获取日志接口,并保存日志提供器。 其定义如下: public interface ILoggerFactory : IDisposable { ILogger CreateLogger(string categoryName); 其定义如下: public interface ILoggerProvider : IDisposable { ILogger CreateLogger(string categoryName) ; } ILogger ILogger 接口提供了将日志记录到基础存储的方法,其定义如下: public interface ILogger { void Log<TState>(LogLevel 总结一下,如果要使用一个日志框架,需要实现 ILogger 、ILoggerFactory 、ILoggerProvider 。
如果哪天日志组件不再用NLog了,那么这个地方的代码就得改,而使用ILogger接口的代码就不需要动。 改造过滤器 方法和在Controller中使用依赖注入完全一样,我们使用构造函数注入ILogger<DeleteSubscriptionCache>类型。 于是代码变成了这样: public class DeleteSubscriptionCache : ActionFilterAttribute { protected readonly ILogger <DeleteSubscriptionCache> Logger; public DeleteSubscriptionCache(ILogger<DeleteSubscriptionCache> DeleteSubscriptionCache))] [Route("manage/edit")] public IActionResult Edit(PostEditModel model) 运行时发现ILogger
@page "/injectPage" @rendermode InteractiveAuto @inject ILogger<InjectPage> logger