From cddc9a2f7edcd12fa78b5bd9307d342c8ae73c42 Mon Sep 17 00:00:00 2001 From: febux Date: Thu, 3 Sep 2026 02:04:00 +0300 Subject: [PATCH] Lightweight OpenObserve was added. --- .env.example | 21 ++++++++- .../contract-check-http.conf.template | 25 ++++++++++ .../templates/contract-check.conf.template | 25 ++++++++++ docker-compose.yml | 47 ++++++++++++++++++- 4 files changed, 116 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index c1c136b..e2a9e63 100644 --- a/.env.example +++ b/.env.example @@ -48,9 +48,28 @@ REFUND_FULL_USAGE_THRESHOLD=0.20 # ≤20% consumed + within window ⇒ full ref # --- Observability (leave empty to disable) --- SENTRY_DSN= -OTEL_EXPORTER_OTLP_ENDPOINT= # e.g. http://otel-collector:4317 +# OTLP endpoint for traces/metrics/logs. +# profile: observer → http://openobserve:5081 (OTLP/gRPC) +# profile: obs → configure your own otel-collector/tempo, or leave empty +OTEL_EXPORTER_OTLP_ENDPOINT= OTEL_SERVICE_NAME=contract-check +# --- OpenObserve (profile: observer) --- +OPENOBSERVE_PORT=5080 +OPENOBSERVE_GRPC_PORT=5081 +OPENOBSERVE_ROOT_USER_EMAIL=root@example.com +OPENOBSERVE_ROOT_USER_PASSWORD=Complexpass#123 +# disk | s3 (s3 requires ZO_S3_* env vars; see OpenObserve docs) +OPENOBSERVE_LOCAL_MODE_STORAGE=disk +# Nginx subpath for the OpenObserve UI. Must stay in sync with +# deploy/nginx/templates/contract-check*.template. +OPENOBSERVE_BASE_URI=/openobserve +# Resource guardrails for the lightweight stack. +OPENOBSERVE_CPU_LIMIT=2 +OPENOBSERVE_MEMORY_LIMIT=2G +OPENOBSERVE_CPU_RESERVATION=0.5 +OPENOBSERVE_MEMORY_RESERVATION=512M + # --- Grafana / Loki (profile: obs) --- GRAFANA_PORT=3000 GRAFANA_ADMIN_USER=admin diff --git a/deploy/nginx/templates/contract-check-http.conf.template b/deploy/nginx/templates/contract-check-http.conf.template index 42f80aa..e0c7390 100644 --- a/deploy/nginx/templates/contract-check-http.conf.template +++ b/deploy/nginx/templates/contract-check-http.conf.template @@ -87,6 +87,31 @@ server { proxy_buffering off; } + # OpenObserve: lightweight observability UI under ${OPENOBSERVE_BASE_URI}. + # The trailing slash in proxy_pass preserves the subpath for OpenObserve. + location ${OPENOBSERVE_BASE_URI} { + return 302 ${OPENOBSERVE_BASE_URI}/; + } + + location ${OPENOBSERVE_BASE_URI}/ { + # Variable forces dynamic DNS resolution for `openobserve`. + set $openobserve http://openobserve:5080; + proxy_pass $openobserve; + proxy_http_version 1.1; + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Correlation-Id $http_x_correlation_id; + + proxy_connect_timeout 10s; + proxy_send_timeout 30s; + proxy_read_timeout 60s; + proxy_buffering off; + } + location /stub_status { stub_status on; allow 10.0.0.0/8; diff --git a/deploy/nginx/templates/contract-check.conf.template b/deploy/nginx/templates/contract-check.conf.template index f21fe0d..e62475a 100644 --- a/deploy/nginx/templates/contract-check.conf.template +++ b/deploy/nginx/templates/contract-check.conf.template @@ -132,6 +132,31 @@ server { proxy_buffering off; } + # OpenObserve: lightweight observability UI under ${OPENOBSERVE_BASE_URI}. + # The trailing slash in proxy_pass preserves the subpath for OpenObserve. + location ${OPENOBSERVE_BASE_URI} { + return 302 ${OPENOBSERVE_BASE_URI}/; + } + + location ${OPENOBSERVE_BASE_URI}/ { + # Variable forces dynamic DNS resolution for `openobserve`. + set $openobserve http://openobserve:5080; + proxy_pass $openobserve; + proxy_http_version 1.1; + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Correlation-Id $http_x_correlation_id; + + proxy_connect_timeout 10s; + proxy_send_timeout 30s; + proxy_read_timeout 60s; + proxy_buffering off; + } + # Static web SPA (future). Placeholder: serve pre-built static assets. # location / { # root /usr/share/nginx/html; diff --git a/docker-compose.yml b/docker-compose.yml index fc8b0cf..b2b94a5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -343,6 +343,8 @@ services: NGINX_ENVSUBST_TEMPLATE_DIR: /etc/nginx/templates NGINX_ENVSUBST_OUTPUT_DIR: /etc/nginx/conf.d NGINX_ENVSUBST_TEMPLATE_SUFFIX: .template + # Passed to the template so the OpenObserve subpath can be changed in one place. + OPENOBSERVE_BASE_URI: ${OPENOBSERVE_BASE_URI:-/openobserve} healthcheck: test: ["CMD", "wget", "-qO-", "--no-check-certificate", "http://localhost/healthz"] interval: 10s @@ -381,7 +383,49 @@ services: ports: - "${NGINX_EXPORTER_PORT:-9113}:9113" - # ── OBSERVABILITY (profile: obs) ─────────────────────────────────────────── + # ── OBSERVABILITY ────────────────────────────────────────────────────────── + # Two observability stacks are provided; activate exactly one profile. + # + # profile: observer → OpenObserve (lightweight, single binary). + # Use for dev/homelab or when hardware is tight. + # profile: obs → Grafana + Prometheus + Loki (mature, heavier). + # Use for production-grade visibility. + # + # App services send OTLP traces/metrics/logs to the endpoint configured in + # OTEL_EXPORTER_OTLP_ENDPOINT (.env). Point it at openobserve:5081 for the + # lightweight profile, or at your own otel-collector/tempo for the obs profile. + + # ── LIGHTWEIGHT OBSERVABILITY (profile: observer) ─────────────────────────── + openobserve: + profiles: ["observer"] + image: public.ecr.aws/zinclabs/openobserve:latest + container_name: contract_check-openobserve + restart: unless-stopped + environment: + ZO_DATA_DIR: /data + ZO_ROOT_USER_EMAIL: ${OPENOBSERVE_ROOT_USER_EMAIL:-root@example.com} + ZO_ROOT_USER_PASSWORD: ${OPENOBSERVE_ROOT_USER_PASSWORD:-Complexpass#123} + # Keep the lightweight single-node SQLite/local-disk backend by default. + # Switch to S3-backed single-node by setting ZO_LOCAL_MODE_STORAGE=s3 and + # configuring ZO_S3_* variables (see docs/administration/configuration/). + ZO_LOCAL_MODE_STORAGE: ${OPENOBSERVE_LOCAL_MODE_STORAGE:-disk} + # Must match the nginx location prefix (deploy/nginx/templates/). + ZO_BASE_URI: ${OPENOBSERVE_BASE_URI:-/openobserve} + volumes: + - openobserve-data:/data + ports: + - "${OPENOBSERVE_PORT:-5080}:5080" # UI + OTLP/HTTP + - "${OPENOBSERVE_GRPC_PORT:-5081}:5081" # OTLP/gRPC + deploy: + resources: + limits: + cpus: "${OPENOBSERVE_CPU_LIMIT:-2}" + memory: "${OPENOBSERVE_MEMORY_LIMIT:-2G}" + reservations: + cpus: "${OPENOBSERVE_CPU_RESERVATION:-0.5}" + memory: "${OPENOBSERVE_MEMORY_RESERVATION:-512M}" + + # ── MATURE OBSERVABILITY (profile: obs) ───────────────────────────────────── # Grafana + Loki logs + Prometheus metrics. Promtail scrapes all compose # container logs via the local Docker socket. See deploy/observability/. prometheus: @@ -464,6 +508,7 @@ volumes: minio: certbot-data: certbot-webroot: + openobserve-data: loki-data: grafana-data: prometheus-data: