From ee4fd677eacf556291c559d8653f73d3e9ab2a33 Mon Sep 17 00:00:00 2001 From: asepharyana Date: Wed, 22 Jul 2026 18:26:41 +0700 Subject: [PATCH] feat(infra): add Prometheus and Chart.js dashboard with real-time charts - Add Prometheus server scraping OTel collector - Add Chart.js donut chart for service health distribution - Add line charts for RPS, latency, error rate, trace volume - Add Prometheus API proxy to nginx whitelist - Restructure dashboard layout with 12-column responsive grid --- infra/compose/observability.yml | 24 ++ infra/dashboard/index.html | 740 +++++++++++++++++++++----------- infra/dashboard/nginx.conf | 8 +- infra/otel/prometheus.yml | 12 + 4 files changed, 523 insertions(+), 261 deletions(-) create mode 100644 infra/otel/prometheus.yml diff --git a/infra/compose/observability.yml b/infra/compose/observability.yml index d8dbb9a..00cdf32 100644 --- a/infra/compose/observability.yml +++ b/infra/compose/observability.yml @@ -35,6 +35,27 @@ services: - PROMETHEUS_SERVER_URL=http://otel-collector:8889 - LOG_LEVEL=info + # ── Prometheus (Metrics Backend) ── + prometheus: + container_name: prometheus + image: prom/prometheus:latest + restart: always + networks: + app-shared-net: + aliases: + - prometheus + ports: + - '9090:9090' + command: + - '--config.file=/etc/prometheus/prometheus.yml' + - '--storage.tsdb.path=/prometheus' + - '--web.console.libraries=/etc/prometheus/console_libraries' + - '--web.console.templates=/etc/prometheus/consoles' + - '--web.enable-lifecycle' + volumes: + - ../../infra/otel/prometheus.yml:/etc/prometheus/prometheus.yml:ro + - prometheus_data:/prometheus + # ── Custom Dashboard (nginx:alpine) ── dashboard: container_name: dashboard @@ -57,6 +78,9 @@ services: otel-collector: condition: service_started +volumes: + prometheus_data: + networks: app-shared-net: name: app-shared-net diff --git a/infra/dashboard/index.html b/infra/dashboard/index.html index 7dd3758..01faf47 100644 --- a/infra/dashboard/index.html +++ b/infra/dashboard/index.html @@ -4,6 +4,7 @@ Hub Dashboard + +
-
-

asepharyana-hub

-
System Dashboard
+
+ +
+

asepharyana-hub

+
System Dashboard
+
-
- Loading... +
+ + Loading... + -
+
- -
-

Services 0

-
Loading...
+ + +
+
+

Services

+ 0 +
+
+
Loading...
+
- -
-

Overview

+ +
+

Overview

-
-
+
-
Services
-
-
+
-
+
Healthy
+
+
+
-
Traces (5m)
-
-
+
-
Errors (5m)
-
-
-
-
P99 Latency
-
- -
-

Quick Links

+ +
+

Health Distribution

+
+
+ + +
+

Quick Links

+ + +
+

Request Rate

-
+
- -
-

Recent Traces 0

-
Loading...
+ +
+

Latency

-
+
+ + +
+

Error Rate

-
+
+
+ + +
+

Trace Volume

0/min
+
+
+ + +
+

Recent Traces

0
+
Loading...
+
+ +
diff --git a/infra/dashboard/nginx.conf b/infra/dashboard/nginx.conf index 442fbff..5e45673 100644 --- a/infra/dashboard/nginx.conf +++ b/infra/dashboard/nginx.conf @@ -62,10 +62,16 @@ http { # OTel collector health location /api/health { proxy_pass http://otel-collector:13133/; - proxy_set_header Host $host; proxy_read_timeout 5s; } + # Prometheus API (read-only queries) + location /api/prometheus/ { + proxy_pass http://prometheus:9090/; + proxy_set_header Host $host; + proxy_read_timeout 15s; + } + # Docker API proxy — strict whitelist (read-only Unix socket) # Uses exact match (=) to avoid regex+proxy_pass URI limitation. location = /api/docker/containers/json { diff --git a/infra/otel/prometheus.yml b/infra/otel/prometheus.yml new file mode 100644 index 0000000..ba65be1 --- /dev/null +++ b/infra/otel/prometheus.yml @@ -0,0 +1,12 @@ +global: + scrape_interval: 15s + evaluation_interval: 15s + +scrape_configs: + - job_name: 'otel-collector' + scrape_interval: 10s + metrics_path: /metrics + static_configs: + - targets: ['otel-collector:8889'] + labels: + service: otel-collector