如何重新发送Serilog.Sinks.Elasticsearch生成的失败消息文件
重新发送Serilog.Sinks.Elasticsearch生成的invalid-*.json失败日志文件
前提确认
- Elasticsearch集群已恢复正常(分片缺失问题已解决)
- 明确
invalid-*.json文件的存储路径(通常是Serilog配置中FailureSink指定的目录,默认在应用根目录的子文件夹内)
方法1:编写控制台程序批量重发
这是最灵活可控的方式,通过代码读取文件并直接调用Elasticsearch API发送:
- 新建控制台项目,安装
Elastic.Clients.Elasticsearch官方客户端包 - 编写核心逻辑:
- 遍历目标目录下所有
invalid-*.json文件 - 读取文件内容,按原始JSON格式发送到对应索引(索引名需与原Serilog配置一致,比如按日期分片的
logs-yyyy-MM-dd) - 发送成功后删除或备份源文件,避免重复发送
- 遍历目标目录下所有
示例代码片段:
using Elastic.Clients.Elasticsearch; using System.IO; var esSettings = new ElasticsearchClientSettings(new Uri("http://你的ES地址:9200")); var esClient = new ElasticsearchClient(esSettings); var invalidLogsDir = @"C:\你的应用路径\Logs\Invalid"; // 替换为实际路径 foreach (var filePath in Directory.EnumerateFiles(invalidLogsDir, "invalid-*.json")) { try { var logJson = await File.ReadAllTextAsync(filePath); // 可从日志内容的@timestamp字段提取日期,动态生成索引名 var indexName = "logs-" + DateTime.Now.ToString("yyyy-MM-dd"); var response = await esClient.IndexAsync(logJson, i => i.Index(indexName)); if (response.IsSuccess()) { File.Delete(filePath); Console.WriteLine($"处理完成:{filePath}"); } else { Console.WriteLine($"发送失败:{filePath},错误:{response.DebugInformation}"); } } catch (Exception ex) { Console.WriteLine($"文件处理异常:{filePath},异常信息:{ex.Message}"); } }
方法2:手动批量导入(小文件量场景)
如果文件数量不多,可借助Elasticsearch的bulk API手动导入:
- 合并日志文件为bulk格式:每个日志行前添加索引指定行,示例如下:
{"index": {"_index": "logs-2024-05-20"}} {"@timestamp": "2024-05-20T12:30:00", "message": "示例日志内容", ...} {"index": {"_index": "logs-2024-05-20"}} {"@timestamp": "2024-05-20T12:31:00", "message": "另一日志内容", ...} - 使用curl命令发送:
curl -X POST "http://你的ES地址:9200/_bulk" -H "Content-Type: application/json" --data-binary @./合并后的bulk文件.json - 导入成功后清理原始invalid文件
方法3:检查Serilog自动重试配置(仅针对新失败日志)
注意:此配置仅对启用后产生的新失败日志生效,无法处理已生成的历史invalid文件。若要启用实时失败日志重试,可在Serilog配置中添加:
.WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri("http://你的ES地址:9200")) { FailureSink = new FileSink("./logs/invalid-{Date}.json", new JsonFormatter(), null), RetryFailedDocuments = true, RetryAttempts = 3 // 重试次数 })
注意事项
- 发送前务必确认ES集群状态稳定,避免再次生成失败文件
- 索引名必须与原日志配置一致,否则日志会写入错误索引
- 批量处理大文件时建议分批次发送,避免压垮ES集群
- 处理前可备份invalid文件,防止数据丢失
内容的提问来源于stack exchange,提问作者Karsten
相关产品推荐
相关产品推荐

