使用Serilog对接Elasticsearch遇mapper_parsing_exception求解决方案
解决Serilog对接Elasticsearch时的mapper_parsing_exception错误
错误原因
日志模板中使用{@Request}标记结构化对象字段,但当Request值为null时,Serilog会将其序列化为null值存入Elasticsearch。而你的logs索引映射中,fields.Request被定义为对象类型,Elasticsearch不允许向对象类型字段存入null这类“具体值”,因此触发mapper_parsing_exception异常。
解决方法
1. 配置Serilog序列化时忽略null值
Serilog默认依赖Newtonsoft.Json进行序列化,可通过自定义ElasticsearchJsonFormatter配置忽略null属性,避免向Elasticsearch发送null对象字段。
示例代码:
var loggerConfig = new LoggerConfiguration() .WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri("http://your-es-instance:9200")) { CustomFormatter = new ElasticsearchJsonFormatter( new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }) }); Log.Logger = loggerConfig.CreateLogger();
如果使用Serilog.AspNetCore等集成包,可在全局配置中统一设置:
Log.Logger = new LoggerConfiguration() .Enrich.FromLogContext() .WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri("http://your-es-instance:9200")) { CustomFormatter = new ElasticsearchJsonFormatter( serializerSettings: new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore } ) }) .CreateLogger();
2. 修改Elasticsearch索引映射
直接调整logs索引的映射规则,确保fields.Request字段可接受null值。执行以下Elasticsearch API请求:
PUT /logs/_mapping { "properties": { "fields": { "properties": { "Request": { "type": "object", "dynamic": false } } } } }
注:对象类型本身支持接受null值,若之前映射有
required: true约束,需一并移除。
3. 日志输出时条件判断null值
在代码层面判断Request是否为null,仅当非null时才输出结构化对象字段:
// 方式1:条件模板 Log.Information( Request != null ? "HttpClient Request: {RequestName} {@Request}" : "HttpClient Request: {RequestName}", RequestName, Request ); // 方式2:分支判断 if (Request != null) { Log.Information("HttpClient Request: {RequestName} {@Request}", RequestName, Request); } else { Log.Information("HttpClient Request: {RequestName}", RequestName); }
内容的提问来源于stack exchange,提问作者Mehrdad
相关产品推荐
相关产品推荐

