golangci-lint run -v 显示高层运行信息:加载的linter列表、跳过的目录、配置文件路径、缓存命中情况及各linter耗时,不输出AST解析细节或规则匹配过程;加 -v -v 才启用debug级日志,含AST节点、规则判断条件、忽略原因和缓存key生成。

golangci-lint run -v 会输出什么
golangci-lint run -v 是最常用、也最接近“debug 模式”的启动方式,但它不等于完整调试日志——它只显示运行时的高层信息:加载了哪些 linter、跳过了哪些目录、用了哪个配置文件、是否命中缓存、每个 linter 耗时多少。不会打印 AST 解析细节或规则匹配过程。
真正要看到 lint 规则触发的底层原因,得加 -v -v(两个 -v)
golangci-lint 支持多级 verbose:
- 单个 -v:显示配置加载路径、linter 启用列表、文件扫描范围
- -v -v(即 --verbose --verbose):开启 debug 级别日志,会输出:
- 每个 linter 实际接收的 AST 节点(如
ast.CallExpr入参) - 规则匹配时的具体条件判断(例如 “skip func named ‘init’”)
- 被忽略的 issue 原因(比如因
issues.exclude-rules或//nolint注释) - 缓存 key 的生成过程(用于排查 CI 缓存失效问题)
注意:-v -v 输出量极大,建议配合 --fast 或 --skip-dirs 限制范围,例如:golangci-lint run -v -v --fast --skip-dirs vendor,testdata ./pkg/...
为什么 -vv 不一定能看到你期待的“某条报错怎么来的”
golangci-lint 的 debug 日志不跟踪单个 issue 的完整决策链,尤其当 issue 来自第三方 linter(如 staticcheck 或 revive)时,其内部日志默认不透出。此时需:
- 确认该 linter 是否支持自身 debug 开关(例如
revive可加--debug,但 golangci-lint 不透传) - 单独运行那个 linter 验证(如
staticcheck -debug ./path/to/file.go) - 检查
linters-settings中是否意外禁用了它的诊断选项(如staticcheck的checks列表漏写了某条规则) - 留意 Go 版本兼容性——某些 linter 在 Go 1.22 下 debug 输出格式有变,旧版解析逻辑可能静默失败
CI 环境下 debug 日志容易被截断或丢失
在 GitHub Actions / GitLab CI 等环境中,-v -v 输出常因超长被截断,或因日志缓冲未刷新而缺失末尾。稳妥做法是:
- 重定向到文件:
golangci-lint run -v -v 2>&1 | tee golangci-debug.log - 确保 CI runner 使用 bash/zsh(不是 dash/sh),否则
2>&1可能不生效 - 添加超时保护:
timeout 5m golangci-lint run -v -v ...,避免卡死 - 不要依赖
GOLANGCI_LINT_CACHE在 debug 时复用——先清空缓存再跑:rm -rf $(go env GOPATH)/cache/golangci-lint
真正难定位的问题,往往藏在 linter 和 Go parser 的版本对齐细节里,而不是日志开关开没开全。



















