本文介绍了用于仅显示程序集名称的 serilog 格式 SourceContext的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我将我的项目配置为使用 Serilog 使用依赖注入进行日志记录.我在类构造函数中使用以下架构:I configured my project to use Serilog for logging using dependecy injection.I use the following schema in the classes constructor:namespace FlickPopper.API.Controllers { public class ValuesController : Controller { private ILogger<ValuesController> _logger; public MyClass(ILogger<ValuesController> logger) { _logger = logger; } }}通过这种方式,serilog创建了对Log.ForContextIn this way, serilog creates the logger calling to Log.ForContext<classname>我的设置是: "Serilog": { "WriteTo": [ { "Name": "RollingFile", "Args": { "pathFormat": "Logs\log-{Date}.txt", "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] {Message}{NewLine}{Exception}" } } ], "Enrich": [ "FromLogContext" ] }所以,日志看起来是这样的:So, the logs seems like this:2018-01-26 22:20:08 [INF] [FlickPopper.API.Controllers.ValuesController] Get all values有什么方法可以格式化 SourceContext 属性以仅在日志中显示程序集名称,像这样吗?It's any way to format the SourceContext property to show only the assembly name in the logs, somthing like this?2018-01-26 22:20:08 [INF] [FlickPopper.API] Get all values推荐答案当你使用注入的 ILogger 时,在底层 Serilog 记录器是由 SerilogLoggerProvider 实现了 ILoggerProvider界面.这个接口只有一个方法:When you use injected ILogger<T>, under the hood Serilog logger is created by SerilogLoggerProvider that implements ILoggerProvider interface. This interface has the only method:public interface ILoggerProvider : IDisposable{ ILogger CreateLogger(string categoryName);}传递的 categoryName 用作消息格式中 {SourceContext} 属性的值.并且 ASP.NET Core 将其作为完全限定名称传递(例如 FlickPopper.API.Controllers.ValuesController).The passed categoryName is used as value for {SourceContext} property in message format. And ASP.NET Core passes it as fully-qualified name (e.g. FlickPopper.API.Controllers.ValuesController).因此,不应在 Serilog 代码或配置中修复此字符串值,而应在 ASP.NET Core 日志记录基础结构中进行修复.So this string value should be fixed not in Serilog code or configuration, but in ASP.NET Core logging infrastructure.首先负责创建该值的类是 Logger 类.Logger 的实例在您将 ILogger 注入您的类时被实例化.这是源代码它的构造函数:The responsible class for creation of that value in first place is Logger<T> class. Instances of Logger<T> are instantiated when you inject ILogger<T> into your classes. Here is source code of its constructor:public class Logger<T> : ILogger<T>{ public Logger(ILoggerFactory factory) { if (factory == null) { throw new ArgumentNullException(nameof(factory)); } _logger = factory.CreateLogger(TypeNameHelper.GetTypeDisplayName(typeof(T))); } // ...}对 TypeNameHelper.GetTypeDisplayName(typeof(T)) 的调用返回完全限定的名称,然后传递给 ILoggerFactory 并最终传递给 SerilogLoggerProvider.That call to TypeNameHelper.GetTypeDisplayName(typeof(T)) returns fully-qualified name that then is passed to ILoggerFactory and eventually to SerilogLoggerProvider.因此,如果您想更改该行为并调整传递给 ILoggerFactory 的 categoryName,您应该拥有自己的 ILogger 实现> 对 ILoggerFactory.CreateLogger() 进行必要的调用.这并不难,因为 Logger 类非常瘦并且基于 Microsoft.Extensions.Logging.Logger 实现.这是一个 Logger 副本的类,除了一行生成记录器类别名称:So if you want to change that behavior and adjust the categoryName passed to ILoggerFactory, you should have your own implementation of ILogger<T> that makes required call to ILoggerFactory.CreateLogger(). It's not that difficult, because Logger<T> class is very thin and is based on Microsoft.Extensions.Logging.Logger implementation. Here is the class that is a copy of Logger<T> except for one line producing logger category name:public class LoggerEx<T> : ILogger<T>{ private readonly ILogger _logger; public LoggerEx(ILoggerFactory factory) { if (factory == null) { throw new ArgumentNullException(nameof(factory)); } _logger = factory.CreateLogger(typeof(T).Assembly.GetName().Name); } IDisposable ILogger.BeginScope<TState>(TState state) { return _logger.BeginScope(state); } bool ILogger.IsEnabled(LogLevel logLevel) { return _logger.IsEnabled(logLevel); } void ILogger.Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) { _logger.Log(logLevel, eventId, state, exception, formatter); }}您还应该在服务注册中将 ILogger 的标准实现替换为以下实现:You should also replace the standard implementation of ILogger<T> with this one in your services registration:services.AddSingleton(typeof(ILogger), typeof(LoggerEx));现在 LoggerEx 的实例将被注入控制器并且 {SourceContext} 将有一个你构建的值:Now the instances of LoggerEx<T> will be injected to the controllers and {SourceContext} will have a value you built:2018-01-27 09:54:21 [INF] [TestProject.TestApplication] 你好! 2018-01-27 09:54:21 [INF] [TestProject.TestApplication] Hello! 这篇关于用于仅显示程序集名称的 serilog 格式 SourceContext的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
07-23 15:38
查看更多