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

如何将Rust程序崩溃事后诊断输出转为结构化日志

Rust Panic日志合并为单条结构化JSON的外部解决方案(无需修改代码)

一、先明确:Rust编译器没法直接改panic输出格式

Rust默认的panic回溯信息是逐行输出到stderr的,编译器没有提供配置项能直接把整个panic内容改成单条JSON格式,所以只能靠日志收集层来做合并处理。

二、用DataDog Vector实现聚合(推荐,因为你已经在用)

Vector本身支持日志的分组和合并,刚好可以用来把panic的多行日志打包成单条结构化JSON,具体配置思路如下:

配置步骤

  1. 识别panic日志的特征
    panic的输出有固定规律:

    • 第一行是错误内容(比如index out of bounds: ...)
    • 接下来是stack backtrace:开头的行
    • 然后是缩进的回溯条目(以多个空格开头)
    • 最后可能有note:开头的提示行
      这些行都属于同一次panic,需要被聚合到一起。
  2. Vector配置示例
    下面是完整的配置片段,包含日志收集、分组合并、转结构化JSON、发送到DataDog的流程:

    # 从应用的stderr日志文件收集日志
    [sources.app_stderr]
    type = "file"
    path = "/var/log/your-app/stderr.log"
    include_newlines = false
    
    # 把属于同一次panic的行分组
    [transforms.group_panic_logs]
    type = "group"
    inputs = ["app_stderr"]
    # 按主机+进程ID分组,避免不同进程的panic混在一起
    key_fields = ["host", "process_id"]
    # 设置超时,10秒内的相关行都算同一次panic
    timeout_secs = 10
    # 匹配所有panic相关的行
    condition = '''
      starts_with(.message, "index out of bounds:") || 
      starts_with(.message, "stack backtrace:") || 
      starts_with(.message, "   ") || 
      starts_with(.message, "note:")
    '''
    
    # 把分组后的多行日志合并成单条
    [transforms.merge_panic_content]
    type = "reduce"
    inputs = ["group_panic_logs"]
    # 用换行符拼接所有行的内容
    merge_strategies.message = "concat_newline"
    # 保留原始的关键标识字段
    identity_fields = ["host", "process_id", "timestamp"]
    
    # 转成结构化JSON格式
    [transforms.to_structured]
    type = "remap"
    inputs = ["merge_panic_content"]
    source = '''
      . = {
        "level": "ERROR",
        "event_type": "panic",
        "message": .message,
        "timestamp": .timestamp,
        "host": .host,
        "process_id": .process_id
      }
    '''
    
    # 发送到DataDog
    [sinks.datadog_output]
    type = "datadog_logs"
    inputs = ["to_structured"]
    api_key = "${DD_API_KEY}"
    site = "datadoghq.com"
    
  3. 注意事项

    • 调整condition里的匹配规则,覆盖你实际遇到的panic开头内容,比如其他类型的panic错误前缀
    • timeout_secs不要设太长(避免日志延迟)也不要太短(确保收集完整个回溯)
    • 如果日志里没有process_id字段,可以通过Vector的add_fields补全,或者只用host分组(多进程环境需谨慎)

三、备选:用脚本预处理日志

如果Vector的配置满足不了需求,也可以用简单脚本先合并panic日志,再传给Vector。比如用awk写个预处理脚本:

BEGIN { in_panic = 0 }

# 匹配panic相关行
/^index out of bounds:/ || /^stack backtrace:/ || /^   / || /^note:/ {
    if (!in_panic) {
        panic_msg = $0
        in_panic = 1
    } else {
        panic_msg = panic_msg "\n" $0
    }
    next
}

# 结束panic收集,输出结构化JSON
in_panic {
    printf "{\"level\":\"ERROR\",\"event_type\":\"panic\",\"message\":\"%s\"}\n", panic_msg
    in_panic = 0
}

# 输出正常日志
{ print }

使用时把应用的stderr通过脚本管道到Vector:

./your-app 2>&1 | awk -f panic-merge.awk | vector --config vector.toml

内容的提问来源于stack exchange,提问作者Wolfgang Kuehn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 08:07:42