diff --git a/config.json b/config.json index a995721..4ab2cd4 100644 --- a/config.json +++ b/config.json @@ -32,6 +32,18 @@ "ports": [{"internal": 9187, "external": 9187}] }, + { + "name": "pgadmin", + "image": "dpage/pgadmin4:latest", + "envs": { + "PGADMIN_DEFAULT_EMAIL": "admin@admin.com", + "PGADMIN_DEFAULT_PASSWORD": "admin" + }, + "network_mode": "testNetwork", + "ports": [{"internal": 80, "external": 5050}] + }, + + { "name": "odoo", @@ -108,7 +120,30 @@ "volume_name": "backup-data" } ] + }, + { + "name": "postgres_metrics_exporter", + "image": "python:3.9-slim", + "command": [ + "python", + "-u", + "/scripts/prometheus_exporter.py" + ], + "volumes": [ + { + "host_path": "./prometheus_exporter.py", + "container_path": "/scripts/prometheus_exporter.py" + } + ], + "network_mode": "testNetwork", + "ports": [ + { + "internal": 8000, + "external": 8000 + } + ] } ] } + \ No newline at end of file diff --git a/prometheus.yml b/prometheus.yml index eddfb4e..870113e 100644 --- a/prometheus.yml +++ b/prometheus.yml @@ -1,23 +1,13 @@ global: - scrape_interval: 15s # How often to scrape metrics (every 15 seconds) - + scrape_interval: 15s + scrape_configs: - - job_name: 'postgres' # For scraping PostgreSQL - static_configs: - - targets: ['postgres:5432'] - - - job_name: 'odoo' # For scraping Odoo - static_configs: - - targets: ['odoo:8069'] - - - job_name: 'grafana' # For scraping Grafana - static_configs: - - targets: ['grafana:3000'] - - job_name: 'postgres_exporter' static_configs: - - targets: ['postgres_exporter:9187'] + - targets: ['postgres_exporter:9187'] + - job_name: 'pg_stat_statements' + static_configs: + - targets: ['postgres_metrics_exporter:8000'] + - - \ No newline at end of file diff --git a/prometheus_exporter.py b/prometheus_exporter.py new file mode 100644 index 0000000..a218278 --- /dev/null +++ b/prometheus_exporter.py @@ -0,0 +1,50 @@ +from prometheus_client import start_http_server, Gauge +import psycopg2 +import time + +# Configuration de la connexion à la base de données +conn_params = { + "host": "admin", + "database": "admin", + "user": "admin", + "password": "admin" +} + +# Définition des métriques Prometheus +QUERY_CALLS = Gauge('postgresql_query_calls', 'Nombre d\'appels de requêtes PostgreSQL', ['query']) +QUERY_TOTAL_TIME = Gauge('postgresql_query_total_time_ms', 'Temps total des requêtes PostgreSQL en millisecondes', ['query']) + +def generate_metrics(): + try: + # Connexion à la base de données + conn = psycopg2.connect(**conn_params) + cur = conn.cursor() + + # Exécution de la requête pour récupérer les informations sur les requêtes + cur.execute(""" + SELECT + query, + calls, + total_time + FROM pg_stat_statements + ORDER BY total_time DESC; + """) + + # Mise à jour des métriques Prometheus + for row in cur: + query = row[0].replace("\\", "\\\\").replace('"', '\\"') # échappement pour Prometheus + QUERY_CALLS.labels(query=query).set(row[1]) + QUERY_TOTAL_TIME.labels(query=query).set(row[2] * 1000) # Convertir le temps en millisecondes + + cur.close() + conn.close() + + except psycopg2.Error as e: + print(f"Erreur de connexion à la base de données: {e}") + +# Fonction principale pour démarrer l'exporteur +if __name__ == '__main__': + start_http_server(8000) # Démarre un serveur HTTP sur le port 8000 pour exposer les métriques + while True: + generate_metrics() # Génére les métriques + time.sleep(60) # Intervalle d'exécution, ici toutes les 60 secondes