Ste*_*BEG 6 c# backgroundworker serilog asp.net-core asp.net-core-webapi
我使用 dotnet worker 服务(.net 5),我集成了 serilog 以及丰富器和接收器。但由于某种原因,我在文件日志中看不到任何输出。
这是我的 appsettings.json
{
"ConnectionStrings": {
"DefaultConnection": "Server=.;Database=eeee;Trusted_Connection=True;MultipleActiveResultSets=true"
},
"WorkerOptions": {
"Batch": 5
},
"Serilog": {
"Using": [],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
},
"Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId" ],
"WriteTo": [
{ "Name": "Console" },
{
"Name": "File",
"Args": {
"path": "E:\\Logs\\log_.txt",
"outputTemplate": "{Timestamp:o} {Message}{NewLine:1}{Exception:1}",
"rollingInterval": "Day",
"retainedFileCountLimit": 7
}
},
{
"Name": "File",
"Args": {
"path": "E:\\Logs\\log_.json",
"formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog",
"outputTemplate": "{Timestamp:o} {Message}{NewLine:1}{Exception:1}",
"rollingInterval": "Day",
"retainedFileCountLimit": 7
}
}
]
}
}
Run Code Online (Sandbox Code Playgroud)
记录器注册:
public class Program
{
public static void Main(string[] args)
{
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.CreateLogger();
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
optionsBuilder.UseSqlServer(configuration.GetConnectionString("DefaultConnection"));
services.AddScoped<ApplicationDbContext>(s => new ApplicationDbContext(optionsBuilder.Options));
services.AddHostedService<Worker>();
});
}
Run Code Online (Sandbox Code Playgroud)
这是一个实现:
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly IConfiguration _config;
public Worker(ILogger<Worker> logger, IServiceScopeFactory serviceScopeFactory, IConfiguration config)
{
_config = config;
_logger = logger;
_serviceScopeFactory = serviceScopeFactory;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Worker picked up {0} requests for dispatch at at: {time}", generatedRequests.Count(), DateTimeOffset.Now);
}
Run Code Online (Sandbox Code Playgroud)
当我通过 Kestrel 运行工作程序时,我可以在控制台日志中看到,但在 .txt 文件或 .json 文件中看不到
更新#1 我尝试使用下面的答案,但在部署工作人员时仍然遇到问题,我没有看到任何日志。当我通过 service.exe 文件运行它或只是执行 debugg (Kestrel) 时,会生成日志文件。
这是更新的 application.json:
"Serilog": {
"Using": [],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
},
"Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId" ],
"WriteTo": [
{ "Name": "Console" },
{
"Name": "File",
"Args": {
"path": ".\\Logs\\log_.txt",
"outputTemplate": "{Timestamp:o} {Message}{NewLine:1}{Exception:1}",
"rollingInterval": "Day",
"retainedFileCountLimit": 7
}
},
{
"Name": "File",
"Args": {
"path": ".\\Logs\\log_.json",
"formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog",
"outputTemplate": "{Timestamp:o} {Message}{NewLine:1}{Exception:1}",
"rollingInterval": "Day",
"retainedFileCountLimit": 7
}
}
]
}
Run Code Online (Sandbox Code Playgroud)
这是 Program.cs
public class Program
{
public static void Main(string[] args)
{
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.CreateLogger();
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureServices((hostContext, services) =>
{
var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
optionsBuilder.UseSqlServer(hostContext.Configuration.GetConnectionString("DefaultConnection"));
services.AddScoped<ApplicationDbContext>(s => new ApplicationDbContext(optionsBuilder.Options));
services.AddHostedService<Worker>();
})
.UseSerilog(); // no args
}
Run Code Online (Sandbox Code Playgroud)
UPDATE#2 我更新了 Program 类,如下所示:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureServices((hostContext, services) =>
{
var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
optionsBuilder.UseSqlServer(hostContext.Configuration.GetConnectionString("DefaultConnection"));
services.AddScoped<ApplicationDbContext>(s => new ApplicationDbContext(optionsBuilder.Options));
services.AddHostedService<Worker>();
})
.UseSerilog((hostContext, services, logger) => {
logger.ReadFrom.Configuration(hostContext.Configuration);
});
}
}
Run Code Online (Sandbox Code Playgroud)
我还在 appsettings.json 中添加了简单的内容:
"Serilog": {
"Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
},
"Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId" ],
"WriteTo": [
{ "Name": "Console" },
{
"Name": "File",
"Args": { "path": "Logs/log.txt" }
},
//{
// "Name": "File",
// "Args": {
// "path": ".\\Logs\\log_.txt",
// "outputTemplate": "{Timestamp:o} {Message}{NewLine:1}{Exception:1}",
// "rollingInterval": "Day",
// "retainedFileCountLimit": 7
// }
//},
{
"Name": "File",
"Args": {
"path": ".\\Logs\\log_.json",
"formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog",
"outputTemplate": "{Timestamp:o} {Message}{NewLine:1}{Exception:1}",
"rollingInterval": "Day",
"retainedFileCountLimit": 7
}
}
]
}
Run Code Online (Sandbox Code Playgroud)
这是当我启动 .exe 文件时正在工作的 _logger 的调用(控制台)
using Microsoft.Extensions.Logging;
...
private readonly ILogger<Worker> _logger;
...
_logger.LogInformation("Worker picked up {0} requests for dispatch at: {time}", generatedRequests.Count(), DateTimeOffset.Now);
Run Code Online (Sandbox Code Playgroud)
UPDATE#3
我只是设置了日志记录的绝对路径c:\\Logs\log.txt
,它部分工作 - 它创建了一个 txt 文件,但文件是空的。这是新的 appsettings.json:
{
"ConnectionStrings": {
"DefaultConnection": "Server=.;Database=svcProcessor_dev;Trusted_Connection=True;MultipleActiveResultSets=true"
},
"WorkerOptions": {
"Batch": 10,
"Delay": 5000,
"MaxAttempts": 3
},
"Serilog": {
"Using": ["Serilog.Sinks.Console", "Serilog.Sinks.File"],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
},
"Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId" ],
"WriteTo": [
{ "Name": "Console" },
{
"Name": "File",
"Args": { "path": "C:\\Logs\\log.txt" }
}
//{
// "Name": "File",
// "Args": {
// "path": "C:\\Logs\\log_.txt",
// "outputTemplate": "{Timestamp:o} {Message}{NewLine:1}{Exception:1}",
// "rollingInterval": "Day",
// "retainedFileCountLimit": 7
// }
//}
//{
// "Name": "File",
// "Args": {
// "path": "C:\\Logs\\log_.json",
// "formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog",
// "outputTemplate": "{Timestamp:o} {Message}{NewLine:1}{Exception:1}",
// "rollingInterval": "Day",
// "retainedFileCountLimit": 7
// }
//}
]
}
}
Run Code Online (Sandbox Code Playgroud)
更新#4
这是我的工人工人示例的最小示例
您没有添加基础设施来将 Serilog 转换Logger
为Microsoft.Extensions.Logging.ILogger
. 就目前情况而言,您只是在创建 Serilog Logger,但并未实际使用它。您在控制台中看到的实际上是来自内置 Microsoft 记录器的日志,而不是来自 Serilog 的日志。
幸运的是,Serilog 有一个从其记录器到 Microsoft 记录器接口的适配器以及各种帮助程序包,具体取决于您的使用场景。您使用的是通用主机,因此首先将Serilog.Extensions.Hosting
包添加到您的项目中。然后调用UseSerilog
扩展方法。传递给此方法的委托接收一个实例,HostBuilderContext
您可以从中检索当前的实例IConfiguration
以及IServiceProvider
用于LoggingConfiguration
配置记录器的实例:
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
/* elided */
})
.UseSerilog((hostContext, services, logger) => {
logger.ReadFrom.Configuration(hostContext.Configuration);
});
Run Code Online (Sandbox Code Playgroud)
请注意,不再需要设置属性Log.Logger
并LoggerConfiguration
直接从Main
. 该UseSerilog
方法将自动设置静态记录器——尽管您不需要它,但ILogger<>
无论如何您都会通过它进行记录。
或者,您可以按照当前的方式配置记录器(直接在 中Main
)。如果您走这条路线,您将UseSerilog
在不带任何参数的情况下进行调用。这将依次使用静态记录器的当前配置。
public static void Main(string[] args)
{
var config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
Log.Logger = new LoggingConfiguration()
.ReadFromConfiguration(config)
.CreateLogger();
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
/* elided */
})
.UseSerilog(); // no args
Run Code Online (Sandbox Code Playgroud)
我个人不喜欢这个选项,尤其是在使用时ReadFrom.Configuration
因为它需要您构建额外的配置对象。我更喜欢使用传入回调的配置,因为它将与主机使用的所有其他配置相匹配。
您aspnet-core
在问题中标记了您的问题并引用了“Kestrel”。然而,您演示的代码显示了一个非常基本的通用主机,而不是一个 Web 应用程序。如果这确实是一个 Web 应用程序,那么您应该添加该Serilog.AspNetCore
包。该包隐式引用 Serilog.Extensions.Hosting
并包含一些其他的片段,以便在 Web 应用程序中使用。
归档时间: |
|
查看次数: |
11421 次 |
最近记录: |