日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

.NET 6新特性试用 | 自动生成高性能日志记录代码

發布時間:2023/12/4 asp.net 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .NET 6新特性试用 | 自动生成高性能日志记录代码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

要想記錄日志,常用的方式是訪問ILogger實例提供的日志記錄方法:

private?readonly?ILogger<WeatherForecastController>?_logger;public?WeatherForecastController(ILogger<WeatherForecastController>?logger) {_logger?=?logger; }[HttpGet(Name?=?"GetWeatherForecast")] public?IEnumerable<WeatherForecast>?Get() {?var?result?=??Enumerable.Range(1,?5).Select(index?=>?new?WeatherForecast{TemperatureC?=?Random.Shared.Next(-20,?55),}).ToArray();_logger.LogInformation("LogInformation:?{0}",?JsonSerializer.Serialize(result));return?result; }

其實,.NET下還有一個高性能日志記錄類LoggerMessage[1]

與ILogger記錄器擴展方法(例如LogInformation和LogDebug)相比,LoggerMessage具有以下性能優勢:

  • 記錄器擴展方法需要將值類型(例如 int)“裝箱”(轉換)到 object中。LoggerMessage模式使用帶強類型參數的靜態Action字段和擴展方法來避免裝箱。

  • 記錄器擴展方法每次寫入日志消息時必須分析消息模板(命名的格式字符串)。如果已定義消息,那么LoggerMessage只需分析一次模板即可。

示例代碼如下:

private?static?readonly?Action<ILogger,?IEnumerable<WeatherForecast>,?Exception?>?_logWeatherForecast?=LoggerMessage.Define<IEnumerable<WeatherForecast>>(logLevel:?LogLevel.Information,eventId:?0,formatString:?"LoggerMessage:?{aa}");//使用 _logWeatherForecast(_logger,?result,?null);

雖然使用LoggerMessage可以為我們提供更好的性能,但是,需要手工編寫大量的LoggerMessage.Define代碼;而且formatString消息模板中的參數占位符并沒有任何控制(例如{aa}),很可能導致傳遞錯誤參數。

而在.NET 6中,可以使用Source Generator幫助我們自動生成高性能日志記錄代碼。

Demo

你需要創建一個partial方法,然后在其頭部聲明LoggerMessageAttribute。

示例代碼如下:

[LoggerMessage(0,?LogLevel.Information,?"LoggerMessageAttribute:?{weatherForecasts}")] partial?void?LogWeatherForecast(IEnumerable<WeatherForecast>?weatherForecasts);//使用 LogWeatherForecast(result);

查看自動生成的代碼,其實是Source Generator幫我們編寫了LoggerMessage.Define代碼:

partial?class?WeatherForecastController? {[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators",?"6.0.5.2210")]private?static?readonly?global::System.Action<global::Microsoft.Extensions.Logging.ILogger,?global::System.Collections.Generic.IEnumerable<global::WebApplication1.WeatherForecast>,?global::System.Exception?>?__LogWeatherForecastCallback?=global::Microsoft.Extensions.Logging.LoggerMessage.Define<global::System.Collections.Generic.IEnumerable<global::WebApplication1.WeatherForecast>>(global::Microsoft.Extensions.Logging.LogLevel.Information,?new?global::Microsoft.Extensions.Logging.EventId(0,?nameof(LogWeatherForecast)),?"LoggerMessageAttribute:?{weatherForecasts}",?new?global::Microsoft.Extensions.Logging.LogDefineOptions()?{?SkipEnabledCheck?=?true?});?[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators",?"6.0.5.2210")]partial?void?LogWeatherForecast(global::System.Collections.Generic.IEnumerable<global::WebApplication1.WeatherForecast>?weatherForecasts){if?(_logger.IsEnabled(global::Microsoft.Extensions.Logging.LogLevel.Information)){__LogWeatherForecastCallback(_logger,?weatherForecasts,?null);}} }

LogWeatherForecast方法直接使用了Controller中聲明的_logger對象,并不需要我們傳入;而且寫入日志前判斷了_logger.IsEnabled避免不必要的日志寫入操作,對性能有進一步提高。

更為重要的是,它不會允許傳入錯誤的參數:

結論

使用LoggerMessageAttribute可以提高日志記錄性能,但它也有其缺點:

  • 使用partial方法聲明必須將類也定義成partial。

  • 日志使用了參數對象的ToString()方法,對于復雜類型,不能在方法中傳入序列化對象LogWeatherForecast(JsonSerializer.Serialize(result)),因為會始終執行影響性能,可以通過定義成record class或自定義ToString()方法變通解決:

參考資料

[1]

LoggerMessage: https://docs.microsoft.com/zh-cn/dotnet/core/extensions/high-performance-logging

如果你覺得這篇文章對你有所啟發,請關注我的個人公眾號”My IO“

總結

以上是生活随笔為你收集整理的.NET 6新特性试用 | 自动生成高性能日志记录代码的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。