这个坑值得记一笔。自建 Langfuse 3.x,用 OTLP HTTP exporter 上报,endpoint 写成 https://lf.example.com/api/public/otel/v1/traces,日志一直报 OTLP export failed 404。
刚开始盯着「反向代理丢掉了 Authorization 头」,折腾了半个多小时,排掉了。
真正麻烦的地方在于,几个原因的现象几乎一样。endpoint 不需要再拼 v1/traces;缺少 Basic Auth 的 key 对;误用了 gRPC 的 4317 端口。
动手时先用 curl 探测正确的上报路径
curl -s -o /dev/null -w '%{http_code}' -X POST https://lf.example.com/api/public/otel/v1/traces
随后把 endpoint 改成不带子路径的基地址
python -c "print('OTEL_EXPORTER_OTLP_ENDPOINT=https://lf.example.com/api/public/otel')"
补上 Basic Auth 头再发一次
python -c "print('Authorization: Basic base64(pk:sk)')"
剩下的就是在 Langfuse 里确认 trace 是否出现
python check_traces.py --since 10m
我习惯把每一步的执行时间和结果记在一边,后面复盘省事。
改之前我把相关日志按时间截了一段存着,事后对时间线用得上。
中途换过一次思路,把范围缩到最小的那一层,反而快了。
中间停过一次,把已经改的东西回滚干净,再重新来一遍。
别只看报错消失,验证要多做一步。exporter 不再报 404,Langfuse 里能看到新的 trace,span 数量和本地一致。
提醒一点。OTLP 的路径拼接规则由 exporter 决定,配置里通常只写基地址,多写一段就会 404,鉴权头也要单独确认。报错文案容易误导,真正的原因往往在相邻那一层的日志里。
