Skip to content

Monitoring ​

SLOzy uses VictoriaMetrics as the metrics backend, Loki for log aggregation, Tempo for distributed tracing, and Alertmanager for alerting. All services run in Docker containers managed by docker-compose.yml.

Docker Compose Services ​

ServicePortDescription
victoria-metrics8428Metrics storage (Prometheus-compatible)
loki3100Log aggregation
alloy—Log agent, sends Docker logs to Loki (replaces Promtail)
tempo3200 / 4317 / 4318Distributed tracing backend (OTLP)
alertmanager9093Alert routing (Telegram, etc.)
grafana3001Dashboards & visualisation
node-exporter9100Host metrics (CPU, RAM, disk, network)
cadvisor8083Container metrics (per-container CPU, memory)

Health Check Endpoints ​

GET /health ​

Basic liveness probe used by Docker.

json
{
  "status": "healthy",
  "time": "2026-06-11T10:00:00Z"
}

GET /api/v1/health ​

Detailed readiness probe with per-service health status.

json
{
  "status": "ok",
  "timestamp": "2026-06-11T10:00:00Z",
  "services": {
    "cache": true,
    "notifications": true,
    "websocket": true
  }
}

GET /api/v1/status/public ​

Public status endpoint used by the landing page widget. No authentication required.

  • healthy — SLO has at least one metric meeting its target
  • violated — SLO has metrics, but none meet the target
  • no_data — SLO has no metrics yet
json
{
  "status": "ok",
  "uptime": "3d 2h 15m",
  "timestamp": "2026-06-22T08:17:39Z",
  "services": {
    "api": true,
    "database": true,
    "cache": true
  },
  "slos": {
    "total": 5,
    "healthy": 0,
    "violated": 0,
    "no_data": 5
  }
}

VictoriaMetrics (Metrics) ​

Replaces Prometheus as the metrics backend. API-compatible with Prometheus.

Configuration ​

Scrape config: victoria-metrics/scrape.yml

yaml
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'slozy-web'
    targets: ['slozy-web:8080']
  - job_name: 'node-exporter'
    targets: ['node-exporter:9100']
  - job_name: 'cadvisor'
    targets: ['cadvisor:8080']
  - job_name: 'alertmanager'
    targets: ['alertmanager:9093']
    metrics_path: '/alertmanager/metrics'
  - job_name: 'loki'
    targets: ['loki:3100']
  - job_name: 'tempo'
    targets: ['tempo:3200']
  - job_name: 'victoria-metrics'
    targets: ['victoria-metrics:8428']

HTTP RED Metrics ​

SLOzy exports standard RED (Rate/Errors/Duration) metrics via the /metrics endpoint:

MetricTypeLabelsDescription
http_requests_totalCountermethod, path, statusTotal HTTP requests by method, route, and status code
http_request_duration_secondsHistogrammethod, pathRequest latency in seconds (standard Prometheus buckets)

These metrics are collected by the built-in middleware (internal/middleware/metrics.go) and registered with Prometheus' default registry. VictoriaMetrics scrapes them automatically via the slozy-web job.

Example PromQL queries:

promql
# Request rate by route
rate(http_requests_total{job="slozy-web"}[5m])

# Error ratio (5xx / total)
sum(rate(http_requests_total{job="slozy-web",status=~"5.."}[5m])) / sum(rate(http_requests_total{job="slozy-web"}[5m]))

# 95th percentile latency
histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket{job="slozy-web"}[5m])) by (le, path))

Alert Rules ​

Defined in alertmanager/rules/alerts.yml, evaluated by VictoriaMetrics:

RuleSeverityCondition
HostHighCpuwarningCPU > 80% for 5m
HostDiskFullwarningDisk > 85%
HostMemoryLowwarningRAM > 85%
SlozyWebDowncriticalWeb unreachable for 1m
SloBudgetBurnRatecriticalBurn rate > 1x

Storage ​

  • Retention: 30 days
  • Data path: /victoria-metrics-data (Docker volume victoria_metrics_data)

Loki (Logs) ​

Configuration ​

Config: loki/loki-config.yml

  • Filesystem storage at /loki (Docker volume loki_data)
  • Retention: 168 hours (7 days) for old samples rejection

Alloy (Log Agent) ​

Config: alloy/alloy-config.river

Replaces Promtail (EOL March 2026). Collects Docker container logs and ships them to Loki using a stage-based pipeline.

  • Reads Docker container logs from /var/lib/docker/containers/*/*.log
  • Sends to http://loki:3100/loki/api/v1/push
  • Parses JSON log format with timestamp, level, and message extraction

Tempo (Traces) ​

Configuration ​

Config: tempo/tempo.yml

  • Listens on OTLP gRPC (4317) and OTLP HTTP (4318)
  • Local filesystem storage at /var/tempo (Docker volume tempo_data)
  • Block retention: 72 hours
  • Metrics generator enabled: service graphs and span metrics, remote-writes to VictoriaMetrics

Application Integration ​

SLOzy uses the OpenTelemetry SDK (go.opentelemetry.io/otel) to create and export spans. The tracer is initialized in cmd/slozy-web/main.go — when OTEL_EXPORTER_OTLP_ENDPOINT is set, spans are batch-exported via OTLP HTTP to Tempo:

env
OTEL_EXPORTER_OTLP_ENDPOINT=http://tempo:4318
OTEL_TRACES_SAMPLER=parentbased_traceidratio
OTEL_TRACES_SAMPLER_ARG=0.1

Alertmanager ​

Configuration ​

Config: alertmanager/alertmanager.yml

  • Default receiver: null (discards all alerts)
  • To enable Telegram, update bot_token and chat_id in the telegram receiver, then change the route
  • Alertmanager runs with --web.external-url=/alertmanager — health endpoint at /alertmanager/-/healthy

Two Notification Systems ​

SLOzy has two independent notification systems — they do not share configuration and serve different purposes.

SLO Notifications (built-in) ​

Configured via the web interface (Settings → Notification Channels). Used for SLO violation alerts, delivered through the SLOzy backend.

Supported channels: Email, Slack, Telegram, Mattermost, Webhook.

Infrastructure Alerts (Alertmanager) ​

A separate system for host and container alerts (CPU, disk, RAM, service down). Works through Alertmanager + vmalert → Telegram.

Configuration: alertmanager/alertmanager.yml. The Telegram bot token is stored in alertmanager/telegram_bot_token (not in git). After a fresh deploy, create this file manually:

bash
echo -n "YOUR_BOT_TOKEN" > alertmanager/telegram_bot_token
chmod 644 alertmanager/telegram_bot_token
docker compose up -d --force-recreate alertmanager

⚠️ These systems are independent — adding a channel in the web UI does not configure Alertmanager, and configuring Alertmanager does not affect SLO notifications.

Grafana Dashboards ​

Grafana runs at https://slozy.net/grafana (admin / from .env).

Pre-provisioned Datasources ​

NameTypeURL
VictoriaMetricsprometheushttp://victoria-metrics:8428
Lokilokihttp://loki:3100
Tempotempohttp://tempo:3200

Available Dashboards ​

DashboardSourceDescription
Host & Containersgrafana/dashboards/host-overview.json13 panels — host CPU, RAM, disk, load, network, IO + per-container CPU, memory, network

Dashboards are auto-provisioned from grafana/dashboards/.

Infrastructure Monitoring ​

ExporterContainerMetrics
node_exporterslozy-node-exporterHost CPU, memory, disk, network, load
cAdvisorslozy-cadvisorPer-container CPU, memory, network

Both are pre-configured in docker-compose.yml and auto-discovered by VictoriaMetrics. Their metrics are visualised in the Host & Containers Grafana dashboard.

Cache Statistics ​

GET /api/v1/cache/statistics

Key metrics:

  • hit_rate — Target > 0.85
  • memory_usage_mb — Should stay within limits
  • hot_entries_count — Frequently accessed entries

SLO Real-Time Metrics ​

GET /api/v1/prometheus/real-time-metrics

Returns SLO values, error budget, and status for all active SLOs in the user's organization.

Dashboard: Availability Trend ​

The Availability Trend chart on the Dashboard page shows the average SLI (Service Level Indicator) across all SLOs over time.

How It Works ​

  1. The frontend calls GET /api/v1/slos/availability-trend?period=24h&step=1h
  2. For each SLO with a Prometheus data source, the backend queries VictoriaMetrics for the actual SLI value (the result of the SLO's metric_query)
  3. Responses are aggregated: avg_sli = mean of all SLO SLI values at each time point
  4. The frontend renders an area chart with the averaged SLI line

What the Numbers Mean ​

MetricMeaning
Average across all SLOs: 74.95%Weighted average of the SLO target values across all SLOs for the selected team. Represents the expected performance floor, not the actual measured SLI.
SLOs with dataNumber of SLOs that returned metric data from VictoriaMetrics for the period. If all SLOs show 0, check that your Prometheus data source is reachable.
Chart Y-axisSLI ratio (0.0–1.0), where 1.0 = 100% compliance with the target.

Why "No metric data yet" ​

This message appears when:

  • No SLOs have Prometheus data sources configured
  • The Prometheus queries return no time-series data (e.g., metric names don't exist yet, or the data source is unreachable)
  • VictoriaMetrics is still starting up and hasn't collected enough data

Once you create SLOs with valid metric_query values that match real Prometheus metrics, the trend chart will populate automatically.