You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何重新发送Serilog.Sinks.Elasticsearch生成的失败消息文件

重新发送Serilog.Sinks.Elasticsearch生成的invalid-*.json失败日志文件

前提确认

  • Elasticsearch集群已恢复正常(分片缺失问题已解决)
  • 明确invalid-*.json文件的存储路径(通常是Serilog配置中FailureSink指定的目录,默认在应用根目录的子文件夹内)

方法1:编写控制台程序批量重发

这是最灵活可控的方式,通过代码读取文件并直接调用Elasticsearch API发送:

  1. 新建控制台项目,安装Elastic.Clients.Elasticsearch官方客户端包
  2. 编写核心逻辑:
    • 遍历目标目录下所有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手动导入:

  1. 合并日志文件为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": "另一日志内容", ...}
    
  2. 使用curl命令发送:
    curl -X POST "http://你的ES地址:9200/_bulk" -H "Content-Type: application/json" --data-binary @./合并后的bulk文件.json
    
  3. 导入成功后清理原始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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 20:46:19