.Net Core 3.1 将 Serilog 与 Microsoft.Extensions.Logger 结合使用
.Net Core 3.1 Using Serilog with Microsoft.Extensions.Logger
在这个应用程序中,我引入并设置了 Serilog,它适用于异常情况,我想将 Microsoft 的 Logger 与 Serilog 一起使用,但我似乎无法弄清楚如何在没有它的情况下将其 DI 到服务中dotnet build
.
期间出错
我不确定让 ILogger 使用 Serilog 实例缺少什么?
dotnet build
错误:
[13:56:21 FTL] Host terminated unexpectedly
System.AggregateException: Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Unable to resolve service for type 'Microsoft.Extensions.Logging.ILogger' while attempting to activate 'App.Services.MyService'.)
服务中的依赖注入:
using Microsoft.Extensions.Logging;
public class MyService : BaseService
{
private readonly ILogger _logger;
public MyService(
ILogger logger)
: base(context, httpContext)
{
_logger = logger;
}
// ... Removed for brevity
}
实施
public static int Main(string[] args)
{
CreateLogger();
try
{
Log.Information("Starting web host");
CreateHostBuilder(args)
.Build()
.Run();
return 0;
}
catch (Exception ex)
{
Log.Fatal(ex, "Host terminated unexpectedly");
return 1;
}
finally
{
// Ensure buffered logs are written to their target sink
Log.CloseAndFlush();
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>())
.UseSerilog();
private static void CreateLogger()
{
string path = PrimeConstants.LOG_FILE_PATH;
try
{
if (isDevelopment())
{
Directory.CreateDirectory(path);
}
}
catch (Exception e)
{
Console.WriteLine("Creating the logging directory failed: {0}", e.ToString());
}
var name = Assembly.GetExecutingAssembly().GetName();
var outputTemplate = "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}";
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.MinimumLevel.Override("Microsoft.Hosting.Lifetime", LogEventLevel.Information)
.MinimumLevel.Override("System", LogEventLevel.Warning)
.Enrich.FromLogContext()
.Enrich.WithMachineName()
.Enrich.WithProperty("Assembly", $"{name.Name}")
.Enrich.WithProperty("Version", $"{name.Version}")
.WriteTo.Console(
outputTemplate: outputTemplate,
theme: AnsiConsoleTheme.Code)
.WriteTo.Async(a => a.File(
$@"{path}/prime.log",
outputTemplate: outputTemplate,
rollingInterval: RollingInterval.Day,
shared: true))
.WriteTo.Async(a => a.File(
new JsonFormatter(),
$@"{path}/prime.json",
rollingInterval: RollingInterval.Day))
.CreateLogger();
}
ILogger
不可用于 DI。您可以使用以下方法之一:
注入ILogger<TCategoryName>
:
public class MyService : BaseService
{
private readonly ILogger _logger;
public MyService(ILogger<MyService> logger)
: base(context, httpContext)
{
_logger = logger;
}
// ...
}
注入ILoggerFactory
并使用它的CreateLogger
方法:
public class MyService : BaseService
{
private readonly ILogger _logger;
public MyService(ILoggerFactory loggerFactory)
: base(context, httpContext)
{
_logger = loggerFactory.CreateLogger("<YOUR_CATEGORY_NAME>");
}
// ...
}
我推荐选项 #1,除非您想完全控制日志类别。请参阅 docs 以了解有关其含义的更多信息:
That category is included with each log message created by that instance of ILogger
.
在这个应用程序中,我引入并设置了 Serilog,它适用于异常情况,我想将 Microsoft 的 Logger 与 Serilog 一起使用,但我似乎无法弄清楚如何在没有它的情况下将其 DI 到服务中dotnet build
.
我不确定让 ILogger 使用 Serilog 实例缺少什么?
dotnet build
错误:
[13:56:21 FTL] Host terminated unexpectedly
System.AggregateException: Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Unable to resolve service for type 'Microsoft.Extensions.Logging.ILogger' while attempting to activate 'App.Services.MyService'.)
服务中的依赖注入:
using Microsoft.Extensions.Logging;
public class MyService : BaseService
{
private readonly ILogger _logger;
public MyService(
ILogger logger)
: base(context, httpContext)
{
_logger = logger;
}
// ... Removed for brevity
}
实施
public static int Main(string[] args)
{
CreateLogger();
try
{
Log.Information("Starting web host");
CreateHostBuilder(args)
.Build()
.Run();
return 0;
}
catch (Exception ex)
{
Log.Fatal(ex, "Host terminated unexpectedly");
return 1;
}
finally
{
// Ensure buffered logs are written to their target sink
Log.CloseAndFlush();
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>())
.UseSerilog();
private static void CreateLogger()
{
string path = PrimeConstants.LOG_FILE_PATH;
try
{
if (isDevelopment())
{
Directory.CreateDirectory(path);
}
}
catch (Exception e)
{
Console.WriteLine("Creating the logging directory failed: {0}", e.ToString());
}
var name = Assembly.GetExecutingAssembly().GetName();
var outputTemplate = "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}";
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.MinimumLevel.Override("Microsoft.Hosting.Lifetime", LogEventLevel.Information)
.MinimumLevel.Override("System", LogEventLevel.Warning)
.Enrich.FromLogContext()
.Enrich.WithMachineName()
.Enrich.WithProperty("Assembly", $"{name.Name}")
.Enrich.WithProperty("Version", $"{name.Version}")
.WriteTo.Console(
outputTemplate: outputTemplate,
theme: AnsiConsoleTheme.Code)
.WriteTo.Async(a => a.File(
$@"{path}/prime.log",
outputTemplate: outputTemplate,
rollingInterval: RollingInterval.Day,
shared: true))
.WriteTo.Async(a => a.File(
new JsonFormatter(),
$@"{path}/prime.json",
rollingInterval: RollingInterval.Day))
.CreateLogger();
}
ILogger
不可用于 DI。您可以使用以下方法之一:
注入
ILogger<TCategoryName>
:public class MyService : BaseService { private readonly ILogger _logger; public MyService(ILogger<MyService> logger) : base(context, httpContext) { _logger = logger; } // ... }
注入
ILoggerFactory
并使用它的CreateLogger
方法:public class MyService : BaseService { private readonly ILogger _logger; public MyService(ILoggerFactory loggerFactory) : base(context, httpContext) { _logger = loggerFactory.CreateLogger("<YOUR_CATEGORY_NAME>"); } // ... }
我推荐选项 #1,除非您想完全控制日志类别。请参阅 docs 以了解有关其含义的更多信息:
That category is included with each log message created by that instance of
ILogger
.