#!/bin/bash # Script pour générer automatiquement les dashboards Grafana # basés sur les modules définis dans les variables d'environnement # Fonction pour charger les variables d'environnement load_env_files() { local env_files=(".env.secrets" ".env" ".env.auto" ".env.post") for env_file in "${env_files[@]}"; do if [ -f "$env_file" ]; then echo "📄 Chargement de $env_file..." source "$env_file" 2>/dev/null || true else echo "⚠️ Fichier $env_file non trouvé, ignoré." fi done } # Fonction pour générer un dashboard de base pour un service generate_service_dashboard() { local SERVICE="$1" local SERVICE_NAME="$2" local DASHBOARD_TYPE="$3" echo "🔧 Génération du dashboard pour $SERVICE ($SERVICE_NAME)" # Créer le répertoire si nécessaire mkdir -p "_4NK_modules/grafana/dashboards" # Générer le nom du fichier local DASHBOARD_FILE="_4NK_modules/grafana/dashboards/${SERVICE_NAME}.json" # Générer le contenu JSON du dashboard cat > "$DASHBOARD_FILE" << EOF { "annotations": { "list": [] }, "editable": true, "fiscalYearStartMonth": 0, "graphTooltip": 0, "id": null, "links": [], "liveNow": false, "panels": [ { "datasource": { "type": "loki", "uid": "loki" }, "fieldConfig": { "defaults": { "color": { "mode": "palette-classic" }, "custom": { "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "none", "hideFrom": { "legend": false, "tooltip": false, "vis": false }, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, "scaleDistribution": { "type": "linear" }, "showPoints": "never", "spanNulls": false, "stacking": { "group": "A", "mode": "none" }, "thresholdsStyle": { "mode": "off" } }, "mappings": [], "thresholds": { "mode": "absolute", "steps": [ { "color": "green", "value": null }, { "color": "red", "value": 80 } ] } }, "overrides": [] }, "gridPos": { "h": 8, "w": 12, "x": 0, "y": 0 }, "id": 1, "options": { "legend": { "calcs": [], "displayMode": "list", "placement": "bottom" }, "tooltip": { "mode": "single" } }, "targets": [ { "datasource": { "type": "loki", "uid": "loki" }, "editorMode": "code", "expr": "sum(rate({container=\"\$${SERVICE}_DOCKER_NAME\"} |= \"INFO\" [5m])) by (container)", "queryType": "", "refId": "A" } ], "title": "Logs INFO - $SERVICE_NAME", "type": "timeseries" }, { "datasource": { "type": "loki", "uid": "loki" }, "fieldConfig": { "defaults": { "color": { "mode": "palette-classic" }, "custom": { "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "none", "hideFrom": { "legend": false, "tooltip": false, "vis": false }, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, "scaleDistribution": { "type": "linear" }, "showPoints": "never", "spanNulls": false, "stacking": { "group": "A", "mode": "none" }, "thresholdsStyle": { "mode": "off" } }, "mappings": [], "thresholds": { "mode": "absolute", "steps": [ { "color": "green", "value": null }, { "color": "red", "value": 80 } ] } }, "overrides": [] }, "gridPos": { "h": 8, "w": 12, "x": 12, "y": 0 }, "id": 2, "options": { "legend": { "calcs": [], "displayMode": "list", "placement": "bottom" }, "tooltip": { "mode": "single" } }, "targets": [ { "datasource": { "type": "loki", "uid": "loki" }, "editorMode": "code", "expr": "sum(rate({container=\"\$${SERVICE}_DOCKER_NAME\"} |= \"ERROR\" [5m])) by (container)", "queryType": "", "refId": "A" } ], "title": "Erreurs - $SERVICE_NAME", "type": "timeseries" }, { "datasource": { "type": "loki", "uid": "loki" }, "fieldConfig": { "defaults": { "color": { "mode": "thresholds" }, "mappings": [], "thresholds": { "mode": "absolute", "steps": [ { "color": "green", "value": null }, { "color": "red", "value": 80 } ] } }, "overrides": [] }, "gridPos": { "h": 4, "w": 6, "x": 0, "y": 8 }, "id": 3, "options": { "colorMode": "value", "graphMode": "area", "justifyMode": "auto", "orientation": "auto", "reduceOptions": { "calcs": [ "lastNotNull" ], "fields": "", "values": false }, "textMode": "auto" }, "pluginVersion": "10.0.0", "targets": [ { "datasource": { "type": "loki", "uid": "loki" }, "editorMode": "code", "expr": "count_over_time({container=\"\$${SERVICE}_DOCKER_NAME\"} |= \"ERROR\" [1h])", "queryType": "", "refId": "A" } ], "title": "Erreurs (1h)", "type": "stat" }, { "datasource": { "type": "loki", "uid": "loki" }, "gridPos": { "h": 8, "w": 24, "x": 0, "y": 12 }, "id": 4, "options": { "showTime": false, "showLabels": false, "showCommonLabels": false, "wrapLogMessage": false, "prettifyLogMessage": false, "enableLogDetails": true, "dedupStrategy": "none", "sortOrder": "Descending" }, "targets": [ { "datasource": { "type": "loki", "uid": "loki" }, "editorMode": "code", "expr": "{container=\"\$${SERVICE}_DOCKER_NAME\"} |= \"ERROR\" | line_format \"{{.timestamp}} - {{.message}}\"", "queryType": "", "refId": "A" } ], "title": "Logs d'Erreur - $SERVICE_NAME", "type": "logs" } ], "refresh": "5s", "schemaVersion": 37, "style": "dark", "tags": [ "$SERVICE_NAME", "auto-generated" ], "templating": { "list": [] }, "time": { "from": "now-1h", "to": "now" }, "timepicker": {}, "timezone": "", "title": "$SERVICE_NAME - Monitoring", "uid": "$(echo $SERVICE_NAME | tr '[:upper:]' '[:lower:]' | tr '_' '-')", "version": 1, "weekStart": "" } EOF echo "✅ Dashboard généré: $DASHBOARD_FILE" } # Fonction pour générer un dashboard overview generate_overview_dashboard() { echo "🔧 Génération du dashboard overview" mkdir -p "_4NK_modules/grafana/dashboards" cat > "_4NK_modules/grafana/dashboards/services-overview.json" << EOF { "annotations": { "list": [] }, "editable": true, "fiscalYearStartMonth": 0, "graphTooltip": 0, "id": null, "links": [], "liveNow": false, "panels": [ { "datasource": { "type": "loki", "uid": "loki" }, "fieldConfig": { "defaults": { "color": { "mode": "palette-classic" }, "custom": { "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "none", "hideFrom": { "legend": false, "tooltip": false, "vis": false }, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, "scaleDistribution": { "type": "linear" }, "showPoints": "never", "spanNulls": false, "stacking": { "group": "A", "mode": "none" }, "thresholdsStyle": { "mode": "off" } }, "mappings": [], "thresholds": { "mode": "absolute", "steps": [ { "color": "green", "value": null }, { "color": "red", "value": 80 } ] }, "unit": "short" }, "overrides": [] }, "gridPos": { "h": 8, "w": 24, "x": 0, "y": 0 }, "id": 1, "options": { "legend": { "calcs": [], "displayMode": "list", "placement": "bottom" }, "tooltip": { "mode": "single", "sort": "none" } }, "targets": [ { "datasource": { "type": "loki", "uid": "loki" }, "editorMode": "code", "expr": "sum by (container) (count_over_time({container=~\"\$${BITCOIN}_DOCKER_NAME|\$${BLINDBIT_ORACLE}_DOCKER_NAME|\$${SDK_RELAY}_DOCKER_NAME|\$${SDK_STORAGE}_DOCKER_NAME|\$${IHM_CLIENT}_DOCKER_NAME|\$${LECOFFRE_FRONT}_DOCKER_NAME\"} |= \"ERROR\" [5m]))", "queryType": "", "refId": "A" } ], "title": "Erreurs par Service (5 dernières minutes)", "type": "timeseries" } ], "refresh": "30s", "schemaVersion": 36, "style": "dark", "tags": ["overview", "auto-generated"], "templating": { "list": [] }, "time": { "from": "now-1h", "to": "now" }, "timepicker": {}, "timezone": "", "title": "Services Overview - Auto Generated", "uid": "services-overview-auto", "version": 1, "weekStart": "" } EOF echo "✅ Dashboard overview généré" } # Fonction pour déterminer le type de service get_service_type() { local service="$1" case "$service" in "BITCOIN"|"BLINDBIT_ORACLE") echo "blockchain" ;; "SDK_RELAY"|"SDK_STORAGE") echo "sdk" ;; "IHM_CLIENT"|"LECOFFRE_FRONT") echo "frontend" ;; "_4NK_MINER") echo "mining" ;; "REDIS"|"POSTGRESQL"|"LOKI"|"PROMTAIL"|"GRAFANA") echo "infrastructure" ;; *) echo "service" ;; esac } # Fonction pour déterminer le nom du dashboard get_dashboard_name() { local service="$1" case "$service" in "BITCOIN") echo "bitcoin" ;; "BLINDBIT_ORACLE") echo "blindbit-oracle" ;; "SDK_RELAY") echo "sdk-relay" ;; "SDK_STORAGE") echo "sdk-storage" ;; "IHM_CLIENT") echo "ihm-client" ;; "LECOFFRE_FRONT") echo "lecoffre-front" ;; "_4NK_MINER") echo "_4NK-miner" ;; "_4NK_CERTIFICATOR") echo "_4NK-certificator" ;; "_4NK_WEB_STATUS") echo "_4NK-web-status" ;; "_4NK_VAULT") echo "_4NK-vault" ;; *) echo "${service,,}" ;; # Convertir en minuscules esac } # Fonction principale main() { echo "🚀 GÉNÉRATION AUTOMATIQUE DES DASHBOARDS GRAFANA" echo "==================================================" # Charger les variables d'environnement load_env_files # Supprimer les fichiers de sortie existants (remplacer complètement) rm -f "_4NK_modules/grafana/dashboards"/*.json 2>/dev/null || true # Créer le répertoire des dashboards mkdir -p "_4NK_modules/grafana/dashboards" echo "📋 Génération des dashboards pour ${#SERVICES[@]} services..." # Générer les dashboards en boucle depuis la variable SERVICES for SERVICE_VAR in "${SERVICES[@]}"; do # Déterminer le nom du dashboard et le type de service local DASHBOARD_NAME=$(get_dashboard_name "$SERVICE_VAR") local SERVICE_TYPE=$(get_service_type "$SERVICE_VAR") echo "🔄 Traitement de $SERVICE_VAR -> $DASHBOARD_NAME ($SERVICE_TYPE)" # Générer le dashboard pour ce service generate_service_dashboard "$SERVICE_VAR" "$DASHBOARD_NAME" "$SERVICE_TYPE" done # Générer le dashboard overview echo "🔄 Génération du dashboard overview..." generate_overview_dashboard echo "" echo "✅ GÉNÉRATION TERMINÉE !" echo "📁 Dashboards générés dans: _4NK_modules/grafana/dashboards/" echo "🔧 Les dashboards utilisent les variables d'environnement pour les noms de containers" echo "📊 Services traités: ${#SERVICES[@]}" } # Exécuter le script principal main "$@"