Bonnes pratiques et cas avances¶
Tuning des quality profiles¶
Stratégie de demarrage¶
La stratégie recommandee est de démarrer strict et de relacher selectivement, avec une justification documentee pour chaque exception.
| Phase | Action | Duree |
|---|---|---|
| Demarrage | Activer le profil Sonar way par defaut | Semaine 1 |
| Évaluation | Analyser les faux positifs et les regles trop bruyantes | Mois 1 |
| Ajustement | Créer le profil Organisation, désactiver les regles documentees | Mois 2 |
| Stabilisation | Profil stable, revue trimestrielle | Ongoing |
Documenter les exceptions¶
Chaque regle desactivee ou modifiée doit etre documentee dans un fichier de référence :
# quality-profile-exceptions.yml
# Regles desactivees dans le profil Organisation-Java
exceptions:
- rule: "java:S1135"
status: disabled
reason: "Les TODO sont geres par le backlog Gitea, pas par SonarQube"
approved_by: "tech-lead"
date: "2026-04-16"
- rule: "java:S3776"
status: modified
parameter: "Threshold=20" # defaut: 15
reason: "Seuil de complexite cognitive releve pour le code legacy existant"
approved_by: "tech-lead"
date: "2026-04-16"
review_date: "2026-07-16"
Pas de desactivation sans justification
Désactiver une regle pour faire passer le quality gate est une dette technique cachee. Chaque exception doit etre validee par le tech lead et revue trimestriellement.
Gestion des faux positifs¶
Workflow de traitement¶
Issue detectee → Developpeur analyse → Faux positif ?
│
┌─────────────┼────────────────┐
│ │
Oui (FP) Non (vrai positif)
│ │
Marquer "Won't Fix" Corriger le code
+ justification + verifier le scan
│
Review par tech lead
│
Valide → Accepte
Invalide → Correction requise
Résolution des issues dans SonarQube¶
# Marquer une issue comme "Won't Fix" (faux positif)
curl -u admin:TOKEN -X POST \
"http://localhost:9000/api/issues/do_transition" \
-d "issue=AYxxxxxx" \
-d "transition=wontfix"
# Ajouter un commentaire de justification
curl -u admin:TOKEN -X POST \
"http://localhost:9000/api/issues/add_comment" \
-d "issue=AYxxxxxx" \
-d "text=Faux positif : ce pattern est securise par le middleware d'authentification en amont. Valide par @tech-lead le 2026-04-16."
Metriques de faux positifs¶
| Metrique | Seuil acceptable | Action si depasse |
|---|---|---|
| Taux de FP par projet | < 5% | Ajuster le quality profile |
| FP non traites (plus de 7 jours) | 0 | Revue hebdomadaire obligatoire |
| FP sans justification | 0 | Refuser le marquage |
Gestion de portfolio (multi-projets)¶
Dashboard de portfolio¶
SonarQube permet de regrouper les projets par équipe, domaine ou application pour une vue d'ensemble.
Portfolios : edition Enterprise
Les portfolios sont une fonctionnalité de l'edition Enterprise. En edition Community, utiliser l'API pour construire un dashboard Grafana équivalent.
Dashboard Grafana pour le portfolio¶
# Script de collecte des metriques pour Grafana
#!/bin/bash
# /home/sonarqube/scripts/collect-metrics.sh
SONAR_URL="http://localhost:9000"
SONAR_TOKEN="${SONAR_TOKEN}"
OUTPUT="/var/lib/prometheus/textfile/sonarqube.prom"
# Lister tous les projets
projects=$(curl -s -u "${SONAR_TOKEN}:" \
"${SONAR_URL}/api/projects/search?ps=500" | \
jq -r '.components[].key')
echo "# HELP sonarqube_quality_gate_status Quality gate status (1=OK, 0=ERROR)" > "${OUTPUT}"
echo "# TYPE sonarqube_quality_gate_status gauge" >> "${OUTPUT}"
for project in ${projects}; do
status=$(curl -s -u "${SONAR_TOKEN}:" \
"${SONAR_URL}/api/qualitygates/project_status?projectKey=${project}" | \
jq -r '.projectStatus.status')
value=0
[ "${status}" = "OK" ] && value=1
echo "sonarqube_quality_gate_status{project=\"${project}\"} ${value}" >> "${OUTPUT}"
done
Suivi des tendances¶
| Indicateur | Fréquence | Objectif |
|---|---|---|
| Projets en quality gate OK | Quotidien | > 90% des projets actifs |
| Nouvelles vulnerabilites | Hebdo | Tendance a la baisse |
| Dette technique globale | Mensuel | Reduction de 5% par trimestre |
| Couverture moyenne | Mensuel | Augmentation vers 80% |
Optimisation des performances¶
Elasticsearch — Le point critique¶
La majorite des problèmes de performance SonarQube viennent d'Elasticsearch.
| Symptome | Cause probable | Solution |
|---|---|---|
| Dashboard lent (> 5s) | Heap ES trop petit | Augmenter -Xmx (max 2 Go) |
| Scan timeout | Compute Engine surcharge | Augmenter le timeout CE |
| SonarQube ne demarre pas | vm.max_map_count trop bas | Ajuster le sysctl |
| Index corrompu | Arrêt brutal, disque plein | Reindexation au redemarrage |
| OOM (OutOfMemory) | Trop de projets / issues | Augmenter la RAM, archiver |
Configuration JVM optimisee¶
# sonar.properties — profil moyen (100-200 projets)
# Web Server JVM
sonar.web.javaOpts=-Xmx512m -Xms256m -XX:+UseG1GC
# Compute Engine JVM
sonar.ce.javaOpts=-Xmx1024m -Xms512m -XX:+UseG1GC
# Elasticsearch JVM
sonar.search.javaOpts=-Xmx1024m -Xms1024m -XX:+UseG1GC
Analyse incrementale¶
# sonar-project.properties
# Limiter l'analyse aux fichiers modifies (pour les gros projets)
sonar.scm.provider=git
sonar.scm.forceReloadAll=false
# Exclure les fichiers generes et les dependances
sonar.exclusions=**/generated/**,**/vendor/**,**/node_modules/**,**/dist/**
SSD obligatoire
Ne jamais déployer SonarQube avec un stockage HDD. Elasticsearch effectue des milliers d'opérations I/O aleatoires par scan. Un SSD ameliore les performances de 5-10x.
Sauvegarde et restauration¶
Stratégie de backup¶
| Composant | Méthode | Fréquence | Retention |
|---|---|---|---|
| Base PostgreSQL | pg_dump + WAL archiving | Toutes les 6h + continu | 30 jours |
| Volume ES data | Snapshot du volume | Quotidien | 7 jours |
| Volume extensions | Copie fichier | Apres chaque install | 3 versions |
| Configuration | Export API + fichier | Quotidien | 90 jours |
Script de backup¶
#!/bin/bash
# /home/sonarqube/scripts/backup.sh
set -euo pipefail
DATE=$(date +%Y%m%d-%H%M%S)
BACKUP_DIR="/backup/sonarqube"
mkdir -p "${BACKUP_DIR}"
# Dump PostgreSQL
podman exec sonarqube-db pg_dump -U sonarqube sonarqube | \
gzip > "${BACKUP_DIR}/db-${DATE}.sql.gz"
# Export des quality profiles
for lang in java python js ts go; do
curl -s -u "${SONAR_TOKEN}:" \
"http://localhost:9000/api/qualityprofiles/backup?language=${lang}" \
> "${BACKUP_DIR}/profile-${lang}-${DATE}.xml" 2>/dev/null || true
done
# Export de la configuration
curl -s -u "${SONAR_TOKEN}:" \
"http://localhost:9000/api/settings/values" | \
jq . > "${BACKUP_DIR}/settings-${DATE}.json"
# Nettoyage des backups > 30 jours
find "${BACKUP_DIR}" -name "*.gz" -mtime +30 -delete
find "${BACKUP_DIR}" -name "*.xml" -mtime +90 -delete
find "${BACKUP_DIR}" -name "*.json" -mtime +90 -delete
echo "Backup completed: ${DATE}"
Procedure de restauration¶
# 1. Arreter SonarQube
sudo -u sonarqube podman-compose down
# 2. Restaurer la base PostgreSQL
gunzip -c "${BACKUP_DIR}/db-YYYYMMDD-HHMMSS.sql.gz" | \
podman exec -i sonarqube-db psql -U sonarqube sonarqube
# 3. Restaurer les quality profiles
for profile in "${BACKUP_DIR}"/profile-*-YYYYMMDD-HHMMSS.xml; do
lang=$(echo "${profile}" | sed 's/.*profile-\(.*\)-[0-9].*/\1/')
curl -u "${SONAR_TOKEN}:" -X POST \
"http://localhost:9000/api/qualityprofiles/restore" \
-F "backup=@${profile}"
done
# 4. Redemarrer SonarQube (reindexation automatique)
sudo -u sonarqube podman-compose up -d
Tester la restauration
Planifier un test de restauration trimestriel dans un environnement isole. Vérifier que les projets, issues, quality profiles et historiques sont intacts.
Processus d'upgrade SonarQube¶
Regles d'upgrade¶
| Regle | Detail |
|---|---|
| Lire les release notes | Changements de breaking changes, deprecations |
| Upgrade une version majeure à la fois | Ne pas sauter de version (10.x -> 11.x, pas 9.x -> 11.x) |
| Backup complet avant l'upgrade | Base + volumes + configuration |
| Tester en environnement de staging | Reproduire l'upgrade avant la production |
| Planifier une fenêtre de maintenance | SonarQube est indisponible pendant la migration DB |
Procedure d'upgrade¶
# 1. Backup complet
/home/sonarqube/scripts/backup.sh
# 2. Arreter SonarQube
sudo -u sonarqube podman-compose down
# 3. Mettre a jour l'image
# Dans podman-compose.yml, changer :
# image: docker.io/library/sonarqube:10-community
# en :
# image: docker.io/library/sonarqube:11-community
# 4. Demarrer (migration automatique de la base)
sudo -u sonarqube podman-compose up -d
# 5. Verifier les logs de migration
sudo -u sonarqube podman logs -f sonarqube
# Attendre "SonarQube is operational"
# 6. Verifier le statut
curl -s http://localhost:9000/api/system/status | jq .
Migration depuis un autre outil¶
Migration vers SonarQube¶
| Source | Méthode |
|---|---|
| CodeClimate | Pas de migration directe. Re-scanner tous les projets |
| Codacy | Pas de migration directe. Re-scanner tous les projets |
| SonarCloud | Export/import des quality profiles. Re-scanner |
| SonarQube (ancien) | Upgrade de la base (voir procedure d'upgrade) |
L'historique ne migre pas
Lors d'une migration depuis un autre outil, l'historique des mesures est perdu. L'historique se reconstruit naturellement au fil des scans. Prevoir 2-4 semaines pour avoir des tendances exploitables.
Troubleshooting¶
Scan lent¶
| Cause | Diagnostic | Solution |
|---|---|---|
| Trop de fichiers analyses | Vérifier sonar.exclusions | Exclure les fichiers générés/vendor |
| Heap CE insuffisant | Logs CE : OutOfMemoryError | Augmenter sonar.ce.javaOpts -Xmx |
| PostgreSQL lent | pg_stat_activity : requêtes longues | Ajouter des index, VACUUM ANALYZE |
| Réseau lent (CI -> SonarQube) | Temps de transfert du rapport | Rapprocher le runner du serveur |
Elasticsearch heap issues¶
# Verifier l'utilisation du heap ES
curl -s http://localhost:9000/api/system/info | \
jq '.Statistics."Search State"'
# Si le heap est > 85%, augmenter la memoire
# sonar.search.javaOpts=-Xmx2g -Xms2g
Ne jamais dépasser 2 Go pour ES heap
Elasticsearch utilise les caches filesystem au-delà du heap JVM. Donner plus de 2 Go au heap ES est contre-productif : mieux vaut laisser la RAM au cache OS.
Scanner incompatible¶
| Erreur | Solution |
|---|---|
Server version X is too old | Mettre a jour le scanner CLI |
Language not analyzed | Vérifier que le plugin du langage est installé |
Coverage report not found | Vérifier le chemin dans sonar.coverage.*ReportPaths |
Token invalid | Régénérer le token, vérifier l'expiration |
Quality gate flapping¶
Le quality gate passe et échoue de manière alternee sans changement de code.
| Cause | Solution |
|---|---|
| Coverage instable (tests flaky) | Corriger les tests instables |
| Seuil trop proche de la valeur | Ajouter une marge (ex: seuil 78% au lieu de 80%) |
| Analyse non deterministe | Vérifier que fetch-depth: 0 est utilisé dans le CI |
| Cache SonarQube stale | Forcer un re-scan complet (sonar.scm.forceReloadAll=true) |