在ASP.NET Core应用程序中,我有一个appsettings.json
配置文件,它使用JSON数组来配置一组设置.
如何使用环境变量覆盖其中一个数组对象的设置?
背景
我使用serilog在ASP.NET核心应用,并使用Serilog.Settings.Configuration,允许它使用进行配置appsettings.json
.
配置是这样的:
{
"Serilog": {
"Using": ["Serilog.Sinks.Literate"],
"MinimumLevel": "Debug",
"WriteTo": [
{ "Name": "File", "Args": { "path": "%TEMP%\\Logs\\serilog-configuration-sample.txt" } }
],
"Enrich": ["FromLogContext", "WithMachineName", "WithThreadId"],
"Properties": {
"Application": "Sample"
}
}
}
Run Code Online (Sandbox Code Playgroud)
部署时,我想覆盖一些设置,例如MinimumLevel,以及日志文件的路径.我首选的选项是在我部署到Azure应用服务时通过环境变量执行此操作,因此我将通过Azure管理门户使用应用程序设置(这些实现为环境变量).
我可以通过添加名称为的环境变量和应用程序名称来轻松设置MinimumLevel.Serilog:MinimumLevel
Serilog:Properties:Application
使用数组指定设置的格式是什么?
由于最近引入了 Program.cs 启动代码的新结构,该文档让我有点困惑。
在官方提供的Serilog.AspNetCore
示例和示例Serilog.Sentry
中,他们使用.UseSerilog()
了WebHostBuilder
. 我找不到这个方法。
这是我尝试过的:
using Serilog;
var builder = WebApplication.CreateBuilder(args);
// adding services...
builder.Logging.AddSerilog(); // <- is this even necessary?
var app = builder.Build();
app.UseSerilogRequestLogging();
// configure request pipeline
app.Run();
Run Code Online (Sandbox Code Playgroud)
但是如何/在哪里配置接收器,例如调试、控制台、哨兵……?我觉得文档有点过时,或者我只是有点盲目。
在 serilog-aspnetcore 版本 5.0.0 中,该UseSerilog()
扩展已被弃用* IWebHostBuilder
。但是,我仍在使用 aIWebHostBuilder
和 aStartup
类(aspnetcore 6),并且IWebHostBuilder
并未弃用。
由于弃用意味着将来会被删除,我应该如何利用 Serilog 继续前进?
* 参考: https://github.com/serilog/serilog-aspnetcore/releases/tag/v5.0.0
IWebHostBuilder
在平台上将扩展标记为已过时IHostBuilder
我们开始将Serilog与Elasticsearch结合使用,这是一种非常有效的方式来存储结构日志数据(之后使用像Kibana这样的工具可视化它们).但是,我看到了不直接将日志数据写入后端的优势,而是配置了一个日志代理,例如Logstash,可以负责为日志消息添加标签,选择索引等.使用此设置,应用程序将不需要具备知识日志数据分发.
Logstash位于中间,问题是Serilog接收器最好使用,因此Logstash可以导入其数据,而无需应用高级和CPU密集型过滤器.我已经看到Redis被提到是Logstash的好伴侣,但是Serilog没有Redis接收器.对于Serilog接收的任何建议哪些数据可以通过Logstash轻松传输到Elasticsearch索引?
甚至有一种方法首先使用Elasticsearch sink,然后在一些安排和应用额外标签之后再次将其环回到Elasticsearch.
Serilog有一种方便的对象解构方法,如下例所示:
logger.Debug(exception, "This is an {Exception} text", exception);
logger.Debug(exception, "This is an {@Exception} structure", exception);
Run Code Online (Sandbox Code Playgroud)
第一行导致记录器将异常记录为纯文本(通过调用ToString()),第二行使记录器将异常属性写为单独的字段.但是这个重载呢:
logger.Debug(exception, "This is an exception", exception);
Run Code Online (Sandbox Code Playgroud)
这个作为第一个参数使用异常,它总是写成一个字符串.我想要做的是以结构化的方式启用日志记录异常.是否可以配置Serilog来实现这一目标?
UPDATE.我想这个问题会导致记录异常的另一个方面:如何确保使用异常属性来丰富消息(因此它们以结构化的方式记录到富散问件,如Elasticsearch),而无需将所有异常属性写入呈现的文本消息(所以纯文本记录器没有大量的异常细节).
我希望我的应用程序能够记录到文件,所以我开始寻找比默认的 .NET Core 2.2 日志框架更多的东西。我看到 Serilog 可能会完成这项工作。但是,我找不到任何关于如何使用依赖注入在 .NET Core 控制台应用程序中设置 Serilog 的文档。我看到的只是 ASP.NET 材料,这可能不是我需要的。
我开始自己做。我安装了(Nuget):
我创建了一个扩展ServiceCollection
public static void AddLogging(this IServiceCollection services, Microsoft.Extensions.Logging.LogLevel logLevel)
{
var serilogLogger = new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.File("log.txt")
.CreateLogger();
services.AddLogging(builder =>
{
builder.SetMinimumLevel(logLevel);
builder.AddSerilog(logger: serilogLogger, dispose: true);
});
}
Run Code Online (Sandbox Code Playgroud)
但是,日志记录有效:
dispose
应该true
。通常,我希望 NET Core 的依赖注入框架来处理服务的处理。我有一个.NET Core 2.0应用程序,我成功地使用Serilog进行日志记录.现在,我想将一些数据库性能统计信息记录到一个单独的接收器(它们不用于调试,这基本上是应用程序中所有其他日志记录的目的,因此我希望将它们分开)并认为这可以完成通过创建数据库统计记录器Log.ForContext<MyClass>()
.
我不知道我应该如何配置Serilog 使用我的appsettings.json将我的"调试日志"记录到一个接收器并将我的数据库统计信息记录到另一个接收器?我希望可以这样做:
"Serilog": {
"WriteTo": [
{
"Name": "RollingFile",
"pathFormat": "logs/Log-{Date}.log",
"Filter": {
"ByExcluding": "FromSource(MyClass)"
}
},
{
"Name": "RollingFile",
"pathFormat": "logs/DBStat-{Date}.log",
"Filter": {
"ByIncludingOnly": "FromSource(MyClass)"
}
}
]
}
Run Code Online (Sandbox Code Playgroud)
"Filter"
配置的各个部分对我来说是纯粹的猜测.这是可以使用我的配置文件管理器还是我需要在我的Startup.cs
文件中的代码中执行此操作?
编辑:我已经使用C#API工作但仍想使用JSON配置解决它:
Log.Logger = new LoggerConfiguration()
.WriteTo.Logger(lc => lc
.Filter.ByExcluding(Matching.FromSource<MyClass>())
.WriteTo.LiterateConsole())
.WriteTo.Logger(lc => lc
.Filter.ByExcluding(Matching.FromSource<MyClass>())
.WriteTo.RollingFile("logs/DebugLog-{Date}.log"))
.WriteTo.Logger(lc => lc
.Filter.ByIncludingOnly(Matching.FromSource<MyClass>())
.WriteTo.RollingFile("logs/DBStats-{Date}.log", outputTemplate: "{Message}{NewLine}"))
.CreateLogger();
Run Code Online (Sandbox Code Playgroud) 我有一个 Azure 函数,它使用 Serilog 通过Serilog AppInsights 接收器 v3.1写入 AppInsights 。
中的代码Startup.cs
看起来像这样
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(config)
.CreateLogger();
Run Code Online (Sandbox Code Playgroud)
和appsettings.json
"Serilog": {
"Using": [
"Serilog.Sinks.ApplicationInsights"
],
"WriteTo": [
{
"Name": "ApplicationInsights",
"Args": {
"instrumentationKey": "...",
"restrictedToMinimumLevel": "Verbose",
"telemetryConverter": "Serilog.Sinks.ApplicationInsights.Sinks.ApplicationInsights.TelemetryConverters.TraceTelemetryConverter, Serilog.Sinks.ApplicationInsights"
}
}
],
...
Run Code Online (Sandbox Code Playgroud)
它可以愉快地将应用程序日志写入AppInsights。
最新的 Github文档提到了遥测配置活动的弃用以及仪器密钥的未来删除支持,因此我想将该库升级到版本 4.0。
但是,当我将接收器升级到 v4.0 时,出现以下异常:
请帮忙。
我已经使用 Host 创建了一个 .NET Core 3.1 项目,IoC 容器IServiceCollection
使用ILogger<T>
来自Microsoft.Extensions.Logging
. 我现在需要实现更高级的日志记录并决定使用 Serilog。
我认为从 .NET 内置记录器切换到 Serilog 会轻而易举。但令我惊讶的是,Serilog 正在使用它自己的ILogger
界面——太糟糕了!所以现在我需要更新所有地方以使用 Serilog ILogger
,或者使用 .NET CoreILogger<T>
接口实现 Serilog 。
我的问题是 - 真的不可能将 Serilog 与 ILogger 接口一起使用Microsoft.Extensions.Logging
吗?会聪明很多!
我正在使用Serilog进行日志记录,并且无法弄清楚如何将日志事件分离到不同的文件.例如,我想将错误记录到error_log-ddmmyyyy.txt,并将警告记录到warn_log-ddmmyyyy.txt.
这是我的记录器配置:
Log.Logger = new LoggerConfiguration()
.WriteTo.Logger(lc =>
lc.Filter.ByIncludingOnly(Matching.WithProperty("Level", "Warning"))
.WriteTo.RollingFile(
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Logs\warn_log-{Date}.txt"),
outputTemplate: OutputTemplate))
.WriteTo.Logger(lc =>
lc.Filter.ByIncludingOnly(Matching.WithProperty("Level", "Error"))
.WriteTo.RollingFile(
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Logs\error_log-{Date}.txt"),
outputTemplate: OutputTemplate))
.CreateLogger();
Run Code Online (Sandbox Code Playgroud)
它仅在我在日志消息中指定{Level}属性时才有效.
我试图使用:
Matching.WithProperty<LogEventLevel>("Level", l => l == LogEventLevel.Warning)
Run Code Online (Sandbox Code Playgroud)
但它也没有用.