必须安装 sonar-scanner CLI(4.8+ 版本),配置 sonar.host.url、sonar.sources=.、sonar.go.coverage.reportPaths=coverage.out(需 mode: count),并启用 gosec 等扩展规则提升检测能力。

sonar-scanner 命令找不到或报错 command not found
本地没装扫描器,Go 项目再规范也没法进 SonarQube。必须先装 sonar-scanner CLI,不能只靠 go install 或 IDE 插件糊弄。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 从 SonarQube 官方下载页拿对应系统的
sonar-scannerZIP 包(别用 Homebrew 或 apt 仓里的旧版,常缺 Go 插件支持) - 解压后把
bin/目录加进$PATH,运行sonar-scanner -v确认输出含4.8+版本号(低于 4.7 的 scanner 不识别sonar.go.tests.reportPaths) - 检查
conf/sonar-scanner.properties里sonar.host.url指向的是你本地启动的 SonarQube(默认http://localhost:9000),不是 SaaS 地址
Go 测试覆盖率不显示,sonar.go.coverage.reportPaths 总是无效
SonarQube 不会自动跑 go test,它只认你生成好的 coverage.out 文件——而且必须是 mode: count 格式,mode: atomic 或 mode: set 都会被静默忽略。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 在项目根目录执行:
go test -coverprofile=coverage.out -covermode=count ./...(注意./...,漏掉子包就测不全) -
sonar-scanner启动前确认coverage.out存在且非空,用head -n 1 coverage.out看第一行是不是mode: count -
sonar-project.properties中写死路径:sonar.go.coverage.reportPaths=coverage.out,不要用通配符或相对路径变量 - 如果项目用
ginkgo或testify,得额外加-coverpkg=./...参数,否则覆盖率统计会漏掉被测包外的依赖代码
扫描报错 ERROR: Missing required property 'sonar.sources'
Go 是编译型语言,没有传统意义上的 “源码根目录” 概念,但 SonarQube 强制要这个字段——它不关心你 go build 怎么找包,只按路径字符串递归扫描文件。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
-
sonar.sources必须设为 Go 源码所在目录,通常是.(当前目录),但不能是./cmd或./internal这种子目录(会漏包) - 排除测试文件:加
sonar.exclusions=**/*_test.go,否则TestMain之类函数会被当成业务逻辑误报漏洞 - 如果项目有多个 module(
go.mod在子目录),每个 module 得单独配一套sonar-project.properties并分别扫描——SonarQube 不支持跨 module 自动合并
扫描后指标全绿但没发现已知 bug,比如空指针或 goroutine 泄漏
SonarQube 默认只开基础规则(sonar-go 插件自带约 120 条),对 Go 特有风险覆盖弱:它不跑静态分析工具如 staticcheck、gosec,也不集成 go vet 的全部检查项。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 进 SonarQube Web 页面 → Quality Profiles → Go → Activate more rules,重点打开
Use of unsafe、Possible nil pointer dereference、Leaking goroutine这几类 - 想补强检测,得在 CI 里另起一步:
gosec -fmt=json -out=gosec-report.json ./...,再用sonar.go.gosec.reportPaths=gosec-report.json接入 - 注意
sonar.go.gosec.reportPaths要求 JSON 格式严格匹配 gosec v2.14+ 输出结构,老版本 gosec 生成的 report 会导致扫描直接失败
Go 的模块化和编译期类型检查让很多问题在扫描时已消失,SonarQube 真正能抓到的是代码结构、注释缺失、测试覆盖盲区这类“人留下的痕迹”。别指望它替你查 select {} 死锁,那得靠 go run -gcflags="-l" -ldflags="-s -w" 加 race detector。










