SonarQube Troubleshooting
SonarQube Analysis Troubleshooting แก้ปัญหา Scanner Config Memory OOM Coverage Quality Gate CI/CD GitHub GitLab Jenkins Production
| ปัญหา | สาเหตุ | วิธีแก้ | Priority |
|---|---|---|---|
| Connection Refused | Server ไม่ทำงาน / URL ผิด / Firewall | ตรวจ URL Port Token Network | Critical |
| Scanner OOM | JVM Heap น้อยเกินไป / Project ใหญ่ | SONAR_SCANNER_OPTS=-Xmx4g | High |
| Coverage 0% | Report Path ผิด / Format ไม่ถูก | ตั้ง sonar.coverage.reportPaths | High |
| Analysis Timeout | Project ใหญ่ / Server ช้า / Network | เพิ่ม Timeout + Exclude ไฟล์ไม่จำเป็น | Medium |
| Quality Gate Fail | Code ไม่ผ่านเกณฑ์ที่ตั้ง | แก้ Issues หรือ ปรับ Quality Gate | Medium |
| Server OOM | CE/ES Memory ไม่พอ | เพิ่ม ce.javaOpts search.javaOpts | Critical |
Scanner Configuration
# === SonarQube Scanner Configuration ===
# sonar-project.properties
# sonar.projectKey=my-project
# sonar.projectName=My Project
# sonar.projectVersion=1.0
#
# # Source
# sonar.sources=src
# sonar.tests=test
# sonar.sourceEncoding=UTF-8
#
# # Server
# sonar.host.url=https://sonarqube.example.com
# sonar.token=sqp_xxxxxxxxxxxx
#
# # Exclusions
# sonar.exclusions=**/vendor/**,**/node_modules/**,**/*.min.js,**/dist/**
# sonar.coverage.exclusions=**/test/**,**/*_test.go,**/*.spec.ts
# sonar.cpd.exclusions=**/generated/**
#
# # Coverage Report
# sonar.javascript.lcov.reportPaths=coverage/lcov.info
# sonar.go.coverage.reportPaths=coverage.out
# sonar.python.coverage.reportPaths=coverage.xml
# sonar.java.coveragePlugin=jacoco
# sonar.coverage.jacoco.xmlReportPaths=build/reports/jacoco/test/jacocoTestReport.xml
#
# # SCM
# sonar.scm.provider=git
# sonar.scm.forceReloadAll=true
from dataclasses import dataclass
@dataclass
class ScannerIssue:
problem: str
symptom: str
cause: str
fix: str
config: str
issues = [
ScannerIssue("Connection Failed",
"ERROR: SonarQube server [url] can not be reached",
"URL ผิด Server ไม่ทำงาน Firewall Block Port",
"ตรวจ URL Port 9000 Token Network curl ทดสอบ",
"sonar.host.url=http://sonarqube:9000"),
ScannerIssue("Authentication Failed",
"ERROR: Not authorized. Analyzing this project requires authentication",
"Token หมดอายุ Token ไม่มีสิทธิ์ Analysis",
"สร้าง Token ใหม่ ตั้ง Permission Execute Analysis",
"sonar.token=sqp_newtoken"),
ScannerIssue("Coverage 0%",
"Coverage widget shows 0.0% despite having tests",
"Report Path ผิด Format ไม่รองรับ Report ไม่ถูกสร้าง",
"ตรวจ Path ถูก Run Test ก่อน Scan ตรวจ Format",
"sonar.javascript.lcov.reportPaths=coverage/lcov.info"),
ScannerIssue("Source Not Found",
"WARN: Invalid value of sonar.sources",
"sonar.sources ชี้ไป Directory ที่ไม่มี",
"ตรวจ Path ถูกต้อง Relative to Project Root",
"sonar.sources=src/main/java"),
ScannerIssue("SCM Not Working",
"SCM provider autodetection failed",
"ไม่มี .git Directory หรือ Git ไม่ได้ติดตั้ง",
"ตั้ง scm.provider=git Checkout Full History",
"sonar.scm.provider=git"),
]
print("=== Scanner Issues ===")
for i in issues:
print(f"\n [{i.problem}]")
print(f" Symptom: {i.symptom}")
print(f" Cause: {i.cause}")
print(f" Fix: {i.fix}")
print(f" Config: {i.config}")
Memory & Performance
# === Memory & Performance Tuning ===
# Scanner Memory
# export SONAR_SCANNER_OPTS="-Xmx4g -Xms1g"
# sonar-scanner
# Maven
# mvn sonar:sonar -Dsonar.host.url=http://sonarqube:9000 \
# -Dsonar.token=sqp_xxx \
# MAVEN_OPTS="-Xmx4g"
# Gradle
# ./gradlew sonar -Dsonar.host.url=http://sonarqube:9000 \
# -Dorg.gradle.jvmargs="-Xmx4g"
# Server Memory (sonar.properties)
# sonar.web.javaOpts=-Xmx2g -Xms1g -XX:+UseG1GC
# sonar.ce.javaOpts=-Xmx4g -Xms2g -XX:+UseG1GC
# sonar.search.javaOpts=-Xmx2g -Xms2g
@dataclass
class MemoryConfig:
component: str
default: str
recommended: str
when_to_increase: str
max: str
memory_configs = [
MemoryConfig("Scanner (SONAR_SCANNER_OPTS)",
"-Xmx512m",
"-Xmx2g-4g",
"Project > 500K LOC หรือ OOM Error",
"-Xmx8g (ขึ้นกับ Project Size)"),
MemoryConfig("Web Server (sonar.web.javaOpts)",
"-Xmx512m",
"-Xmx1g-2g",
"Server ช้า UI ไม่ตอบสนอง",
"-Xmx4g"),
MemoryConfig("Compute Engine (sonar.ce.javaOpts)",
"-Xmx512m",
"-Xmx2g-4g",
"Analysis Queue สะสม Background Task ช้า",
"-Xmx8g (สำคัญที่สุด)"),
MemoryConfig("Elasticsearch (sonar.search.javaOpts)",
"-Xmx512m",
"-Xmx1g-2g",
"Search ช้า Project เยอะ Index ใหญ่",
"-Xmx4g (ไม่เกิน 50% RAM)"),
MemoryConfig("Database Connection Pool",
"10",
"20-50",
"Connection Timeout หลาย Concurrent Analysis",
"100 (PostgreSQL max_connections)"),
]
print("=== Memory Config ===")
for m in memory_configs:
print(f" [{m.component}]")
print(f" Default: {m.default} → Recommended: {m.recommended}")
print(f" Increase when: {m.when_to_increase}")
print(f" Max: {m.max}")
CI/CD Integration
# === CI/CD Integration Examples ===
# GitHub Actions
# - name: SonarQube Scan
# uses: SonarSource/sonarqube-scan-action@master
# env:
# SONAR_TOKEN: }
# SONAR_HOST_URL: }
#
# - name: Quality Gate
# uses: SonarSource/sonarqube-quality-gate-action@master
# timeout-minutes: 5
# env:
# SONAR_TOKEN: }
# GitLab CI
# sonarqube:
# image: sonarsource/sonar-scanner-cli:latest
# variables:
# SONAR_HOST_URL: $SONAR_HOST_URL
# SONAR_TOKEN: $SONAR_TOKEN
# script:
# - sonar-scanner -Dsonar.projectKey=$CI_PROJECT_NAME
# -Dsonar.branch.name=$CI_COMMIT_BRANCH
# Jenkins Pipeline
# pipeline {
# stages {
# stage('SonarQube') {
# steps {
# withSonarQubeEnv('SonarQube') {
# sh 'sonar-scanner'
# }
# }
# }
# stage('Quality Gate') {
# steps {
# timeout(time: 5, unit: 'MINUTES') {
# waitForQualityGate abortPipeline: true
# }
# }
# }
# }
# }
@dataclass
class CICDIssue:
ci_tool: str
issue: str
cause: str
fix: str
cicd_issues = [
CICDIssue("GitHub Actions",
"Quality Gate timeout",
"Webhook ไม่ส่งกลับ หรือ Analysis ยังไม่เสร็จ",
"ตั้ง Webhook ใน SonarQube ชี้ไป GitHub เพิ่ม timeout"),
CICDIssue("GitLab CI",
"sonar-scanner not found",
"ใช้ Image ที่ไม่มี sonar-scanner",
"ใช้ sonarsource/sonar-scanner-cli Docker Image"),
CICDIssue("Jenkins",
"waitForQualityGate hangs",
"Webhook ไม่ Configure หรือ Firewall Block",
"ตั้ง Webhook ใน SonarQube → Jenkins URL/sonarqube-webhook/"),
CICDIssue("All",
"Branch Analysis ไม่ทำงาน",
"ไม่ตั้ง sonar.branch.name หรือ ใช้ Community Edition",
"ตั้ง sonar.branch.name=$BRANCH (Developer Edition+)"),
CICDIssue("All",
"PR Decoration ไม่แสดง",
"ALM Integration ไม่ Configure",
"ตั้ง DevOps Platform Integration ใน SonarQube Admin"),
]
print("=== CI/CD Issues ===")
for c in cicd_issues:
print(f" [{c.ci_tool}] {c.issue}")
print(f" Cause: {c.cause}")
print(f" Fix: {c.fix}")
เคล็ดลับ
- Exclusions: ตั้ง Exclusions ลด Scan Time ไม่ Scan vendor node_modules
- CE Memory: Compute Engine สำคัญที่สุด เพิ่ม Memory ก่อน
- PostgreSQL: ใช้ PostgreSQL สำหรับ Production ไม่ใช้ H2
- Webhook: ตั้ง Webhook สำหรับ Quality Gate ใน CI/CD
- Token: ใช้ Project Token แทน Global Token Least Privilege
ปัญหาที่พบบ่อยมีอะไร
Connection Refused OOM Coverage 0% Timeout Quality Gate Fail SCM Language Plugin Elasticsearch Database Duplicate False Positive
Scanner Config แก้อย่างไร
sonar-project.properties projectKey sources tests host.url token exclusions coverage.reportPaths scm.provider sourceEncoding UTF-8
Memory Issues แก้อย่างไร
SONAR_SCANNER_OPTS -Xmx4g web.javaOpts ce.javaOpts search.javaOpts G1GC PostgreSQL Connection Pool JMX Monitor Heap GC
CI/CD Integration แก้อย่างไร
GitHub Actions GitLab CI Jenkins Pipeline Webhook Quality Gate waitForQualityGate Branch Analysis PR Decoration Token Secret ALM
สรุป
SonarQube Troubleshooting Scanner Config Memory OOM Coverage Quality Gate CI/CD GitHub GitLab Jenkins Webhook PostgreSQL Production
