写点什么

.NET6 新东西 --Logging Source Generator

作者:喵叔
  • 2021 年 12 月 31 日
  • 本文字数:1639 字

    阅读完需:约 5 分钟

Logging source generator 是.NET6 加入的新功能,它以 Source Generator 为基础来实现的,具有更好的性能以及灵活性,这在注重性能的项目中是一个非常好的功能,但是因为它要用到 C# 9 中的 partial method(分部方法),因此如果要使用它就必须是 C#9 及以上版本。下面我们来看看如何使用 Logging source generator。

简单的例子

一般来说类库里的日志模块会使用静态方法,将日志的各种操作放在一个静态类中,比如下面的代码:


public static void MiaoShuLog(this ILogger logger, string miaoshuLog) => logger.Log(    LogLevel.Information,    new EventId(1, "喵叔Log"),    requestLog);
复制代码


日志代码这么编写后就可以很方便地进行 EventId 的管理,避免了 EventId 重复导致的冲突,但是使用了 Logging Source Generator 之后代码可以更简单:


[LoggerMessage(LogLevel = LogLevel.Information, EventId=1, EventName= "喵叔Log", Message = "{miaoshuLog}")]public static void MiaoShuLog(this ILogger logger, string miaoshuLog);
复制代码

官方示例代码

下面的代码是微软官方提供的一些案列代码:


[LoggerMessage(Level = LogLevel.Information, EventId = 0, Message = "Logging generator sample begin")]public static partial void TestBegin(this ILogger logger);
[LoggerMessage(Level = LogLevel.Information, EventId = 1, Message = "Logging generator sample end", SkipEnabledCheck = true)]public static partial void TestEnd(this ILogger logger);
[LoggerMessage(EventId = 2, Message = "Logging generator sample user {userName}")]public static partial void TestWithArgument(this ILogger logger, LogLevel logLevel, string userName);
// warning SYSLIB1015: Argument 'host' is not referenced from the logging message[LoggerMessage(EventId = 3)]public static partial void TestWithEmptyMessage(this ILogger logger, LogLevel logLevel, string host);
[LoggerMessage( EventId = 9, Level = LogLevel.Trace, Message = "Fixed message", EventName = "CustomEventName")]public static partial void LogWithCustomEventName(this ILogger logger);
复制代码


在上面的代码中静态方法作为扩展方法使用,当然你也可以不作为扩展方法来使用,我们可以根据自己需要和习惯来选择。下面的代码是调用上面定义的 Log 方法,同样代码也是来自于微软官方:


var loggerFactory = LoggerFactory.Create(builder => builder.AddJsonConsole(options =>        {            options.JsonWriterOptions = new JsonWriterOptions()            {                Indented = true,                Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping            };        }));var logger = loggerFactory.CreateLogger<LoggingGeneratorSample>();logger.TestBegin();logger.TestWithArgument(LogLevel.Warning, Environment.UserName);logger.TestWithEmptyMessage(LogLevel.Information, Environment.MachineName);logger.TestEnd();
复制代码

实例使用示例

除了作为静态方法使用外也可以作为实例方法去使用,实际项目中不关注 EventId 的日志记录比较多,下面就是这样的一个例子:


new InstanceLoggingGenerator(logger).LoggingTest();internal partial class InstanceLoggingGenerator{    private readonly ILogger _logger;    public InstanceLoggingGenerator(ILogger logger)    {        _logger = logger;    }    [LoggerMessage(EventId = 0, EventName = "Test", Level = LogLevel.Information, Message = "Instance logging generator test")]    public partial void LoggingTest();}
复制代码


在上面代码中,实例方法使用可以不传 ILogger 实例,它会自动从类型中寻找 ILogger 类型的字段,可以想一下如果类型中有多个 ILogger 字段会怎么样?如果没有的话又会怎么样呢?你可以去试试。

用户头像

喵叔

关注

还未添加个人签名 2020.01.14 加入

还未添加个人简介

评论

发布
暂无评论
.NET6新东西--Logging Source Generator