🐛 tunnel diag: Docker log collection deadlocks when the container's stderr log exceeds 64 KiB

未关闭 适合新手
#1,783 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

@akasakariko 已经在做这个了。

开始于 2026年10月30日。

  • #1784 来自 @akasakariko —— 未关闭

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
76/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
docker, go, kubernetes
领域
devops, tooling

调研方向

从 diagnostic/log_collector_utils.go 开始,检查 PipeCommandOutputToFile,然后查看 log_collector_host.go 和 log_collector_kubernetes.go 中的主机和 Kubernetes 收集器如何使用它。使用 stderr 超过 65,536 字节的 Docker 日志复现问题,并验证两个流都能在不超时的情况下被收集;之后确认共享诊断作业已完成。

由索引模型根据 Issue 内容生成。

描述

Version: cloudflared 2026.9.3 (the same code is on master today), cloudflared tunnel diag --metrics localhost:<port> --diag-container-id <container>, Linux.

What happens: "log information" fails with error waiting from command 'docker logs --tail 10000 --since <t> <container>': signal: killed after 45 s. Because every job shares the one 45 s context in RunDiagnostic, the jobs after it (raw network information, network information, cli configuration, configuration) also fail with context deadline exceeded.

Cause: diagnostic/log_collector_utils.go, PipeCommandOutputToFile, opens both StdoutPipe and StderrPipe, then io.Copys stdout to EOF before it starts reading stderr. cloudflared writes its log to stderr, so docker logs replays it on stderr. Once more than the pipe buffer (64 KiB on Linux) is pending on stderr, docker logs blocks writing stderr, never closes stdout, and the stdout copy waits until the context kills the process.

Reproduce: run diag against any Docker connector whose docker logs <container> 2>&1 >/dev/null | wc -c is above 65,536. Ours: 160,835 bytes on stderr, 0 on stdout → deadlock every time; another connector with 9,222 bytes → succeeds.

Workaround we used: a docker wrapper earlier in PATH: exec /path/to/real/docker "$@" 2>&1.

Suggested fix: read both pipes concurrently, or set command.Stdout and command.Stderr to the same *os.File (exec then copies both without a reader race), e.g. command.Stdout = outputHandle; command.Stderr = outputHandle; err := command.Run(). The same function serves the host and Kubernetes collectors (log_collector_host.go, log_collector_kubernetes.go), so kubectl logs would deadlock the same way.

主要语言
Go
星标
16.3k
派生
1.5k
PR 合并指标
30 天内没有已合并 PR

环境准备

  • 提供 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

cloudflare/cloudflared 的其他 Issue

查看 cloudflare/cloudflared 的全部 Issue

相似的 Issue

更多 Go Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。