ASP.NET Web API正常路径日志无法在Kibana中显示的问题排查
问题:ASP.NET Web API正常流程日志无法显示在Kibana中
我正在学习将日志、指标和追踪数据发送至Elastic平台,使用ASP.NET Web API创建了ApiOne和ApiTwo两个演示应用,采用ElasticAPM与Serilog包实现相关功能。以下是两个项目的通用配置(仅变量不同):
program.cs:
builder.Services.AddAllElasticApm(); Log.Logger = new LoggerConfiguration() .ReadFrom.Configuration(builder.Configuration) .Enrich.WithElasticApmCorrelationInfo() .WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri("http://localhost:9200")) { CustomFormatter = new EcsTextFormatter() }) .CreateLogger(); builder.Services.AddSerilog();
appsettings.json:
{ "ElasticApm": { "ServiceName": "ApiOne", "ServerUrl": "http://localhost:8200", "SecretToken": "Secret", "TransactionSampleRate": 1.0, "Environment": "Development" }, "Serilog": { "Using": [ "Serilog.Sinks.Console"], "MinimumLevel": "Information", "WriteTo": [ { "Name": "Console" } ], "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ], "Properties": { "Application": "ApiOne" } } }
目前仅当发生异常时,日志才会在Kibana中显示,正常流程下的自定义日志(使用ILogger)无法展示。例如以下TestController中的日志从未出现在Kibana中:
[ApiController] [Route("[controller]")] public class TestController(ILogger<TestController> logger) : ControllerBase { private static int _reqNum = 0; [HttpGet("number")] public Task<IActionResult> GetNumber() { var incrementedVal = Interlocked.Increment(ref _reqNum); logger.LogInformation("Test Log Text"); return Task.FromResult(Ok(new {Number = Random.Shared.Next(0, 30)}) as IActionResult); } }
问题原因分析
- Serilog未被设置为ASP.NET Core默认日志提供者:仅调用
builder.Services.AddSerilog()不足以替换默认日志系统,导致ILogger的日志未被Serilog捕获,无法发送到Elasticsearch。 - 缺少核心集成包:未安装
Serilog.AspNetCore的情况下,ASP.NET Core日志系统无法与Serilog联动,自定义日志会走默认流程,不会输出到Elasticsearch。 - Kibana索引模式不匹配:Serilog写入的日志索引与ElasticAPM的异常日志索引(如
apm-*)不同,若未创建对应索引模式,即使日志已写入Elasticsearch,也无法在Kibana中查看。 - 日志级别过滤限制:若未配置
Logging节点,或Default级别高于Information,自定义的LogInformation日志会被系统过滤。
解决方案步骤
1. 安装必要NuGet包
确保项目已安装以下依赖:
Install-Package Serilog.AspNetCore Install-Package Serilog.Sinks.Elasticsearch Install-Package Serilog.Enrichers.ElasticApm Install-Package Elastic.Apm.NetCoreAll
2. 修正Program.cs配置
调整代码顺序,将Serilog设为默认日志提供者:
// 1. 先配置Serilog Log.Logger = new LoggerConfiguration() .ReadFrom.Configuration(builder.Configuration) .Enrich.WithElasticApmCorrelationInfo() .WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri("http://localhost:9200")) { CustomFormatter = new EcsTextFormatter(), // 自定义索引格式,方便Kibana识别 IndexFormat = "logs-{ServiceName}-{0:yyyy.MM.dd}" }) .CreateLogger(); // 2. 将Serilog设置为默认日志提供者 builder.Host.UseSerilog(); // 3. 添加Elastic APM支持 builder.Services.AddAllElasticApm(); // 构建应用并启用请求日志(可选) var app = builder.Build(); app.UseSerilogRequestLogging();
3. 完善appsettings.json配置
添加Logging节点确保Information级日志不被过滤:
{ "ElasticApm": { "ServiceName": "ApiOne", "ServerUrl": "http://localhost:8200", "SecretToken": "Secret", "TransactionSampleRate": 1.0, "Environment": "Development" }, "Serilog": { "Using": ["Serilog.Sinks.Console"], "MinimumLevel": "Information", "WriteTo": [{"Name": "Console"}], "Enrich": ["FromLogContext", "WithMachineName", "WithThreadId"], "Properties": {"Application": "ApiOne"} }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } } }
4. 在Kibana中创建对应索引模式
- 登录Kibana,进入Stack Management > Index Patterns
- 点击Create index pattern
- 输入索引匹配规则(如
logs-apione-*,对应步骤2中设置的IndexFormat) - 完成创建后,即可在Discover页面查看正常流程日志
5. 验证配置
启动API项目,调用/Test/number接口:
- 通过
GET /_cat/indices接口检查Elasticsearch是否生成对应索引 - 在Kibana的Discover页面选择新创建的索引模式,筛选日志级别为
info,即可看到自定义的Test Log Text日志
内容的提问来源于stack exchange,提问作者user19291301
相关产品推荐
相关产品推荐

