Skip to content
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ _run:
-f tools/make/pre-commit.mk \
-f tools/make/docker.mk \
-f tools/make/kube.mk \
-f tools/make/observability.mk \
$(MAKECMDGOALS)

.PHONY: _run
Expand Down
10 changes: 0 additions & 10 deletions config/grafana/dashboards.yaml

This file was deleted.

7 changes: 0 additions & 7 deletions config/grafana/datasource.yaml

This file was deleted.

22 changes: 0 additions & 22 deletions config/prometheus.yaml

This file was deleted.

42 changes: 42 additions & 0 deletions docker-compose.obs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Local observability stack for monitoring semantic-router running on host
#
# Usage: make obs-local
# Or: docker compose -f docker-compose.obs.yml up
#
# This provides Prometheus and Grafana in Docker with network_mode: host
# to scrape metrics from router running natively on localhost:9190

version: '3.8'

services:
prometheus:
image: prom/prometheus:v2.53.0
container_name: prometheus-local
network_mode: host
volumes:
- ./tools/observability/prometheus.yaml:/etc/prometheus/prometheus.yaml:ro
- prometheus-local-data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yaml'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention.time=15d'
environment:
- ROUTER_TARGET=localhost:9190

grafana:
image: grafana/grafana:11.5.1
container_name: grafana-local
network_mode: host
volumes:
- ./tools/observability/grafana-datasource.yaml:/etc/grafana/provisioning/datasources/datasource.yaml:ro
- ./tools/observability/grafana-dashboard.yaml:/etc/grafana/provisioning/dashboards/dashboard.yaml:ro
- ./tools/observability/llm-router-dashboard.json:/etc/grafana/provisioning/dashboards/llm-router-dashboard.json:ro
- grafana-local-data:/var/lib/grafana
environment:
- PROMETHEUS_URL=localhost:9090
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_ALLOW_SIGN_UP=false

volumes:
prometheus-local-data:
grafana-local-data:
17 changes: 13 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,13 @@ services:
image: prom/prometheus:v2.53.0
container_name: prometheus
volumes:
- ./config/prometheus.yaml:/etc/prometheus/prometheus.yaml:ro
- ./tools/observability/prometheus.yaml:/etc/prometheus/prometheus.yaml:ro
- prometheus-data:/prometheus
command:
- --config.file=/etc/prometheus/prometheus.yaml
- --storage.tsdb.retention.time=15d
environment:
- ROUTER_TARGET=semantic-router:9190
ports:
- "9090:9090"
networks:
Expand All @@ -84,14 +87,18 @@ services:
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin
- PROMETHEUS_URL=prometheus:9090
ports:
- "3000:3000"
volumes:
- ./config/grafana/datasource.yaml:/etc/grafana/provisioning/datasources/datasource.yaml:ro
- ./config/grafana/dashboards.yaml:/etc/grafana/provisioning/dashboards/dashboards.yaml:ro
- ./deploy/llm-router-dashboard.json:/etc/grafana/provisioning/dashboards/llm-router-dashboard.json:ro
- ./tools/observability/grafana-datasource.yaml:/etc/grafana/provisioning/datasources/datasource.yaml:ro
- ./tools/observability/grafana-dashboard.yaml:/etc/grafana/provisioning/dashboards/dashboard.yaml:ro
- ./tools/observability/llm-router-dashboard.json:/etc/grafana/provisioning/dashboards/llm-router-dashboard.json:ro
- grafana-data:/var/lib/grafana
networks:
- semantic-network
depends_on:
- prometheus

# LLM Katan service for testing
llm-katan:
Expand All @@ -118,3 +125,5 @@ networks:
volumes:
models-cache:
driver: local
prometheus-data:
grafana-data:
11 changes: 11 additions & 0 deletions tools/make/common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,17 @@ help:
@echo " docs-serve - Serve built documentation"
@echo " docs-clean - Clean documentation artifacts"
@echo ""
@echo " Observability targets:"
@echo " run-observability - Start observability (alias for o11y-local)"
@echo " o11y-local - Start observability in LOCAL mode"
@echo " o11y-compose - Start observability in COMPOSE mode"
@echo " stop-observability - Stop observability stack"
@echo " open-observability - Open Prometheus and Grafana in browser"
@echo " o11y-status - Check observability stack status"
@echo " o11y-logs - Show observability logs"
@echo " o11y-clean - Remove observability data volumes"
@echo " (aliases: obs-local, obs-compose, obs-status, obs-logs, obs-clean)"
@echo ""
@echo " Environment variables:"
@echo " CONTAINER_RUNTIME - Container runtime (docker|podman, default: docker)"
@echo " CONFIG_FILE - Config file path (default: config/config.yaml)"
Expand Down
52 changes: 52 additions & 0 deletions tools/make/observability.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# ====================== observability.mk ======================
# = Observability targets for semantic-router monitoring =
# ====================== observability.mk ======================

# Observability directories
OBS_CONFIG_DIR = tools/observability
OBS_SCRIPTS_DIR = tools/observability/scripts

.PHONY: run-observability stop-observability \
o11y-local o11y-compose o11y-logs o11y-status o11y-clean open-observability

## run-observability: Start observability stack (alias for o11y-local)
run-observability: o11y-local

## o11y-local: Start observability in LOCAL mode (router on host, o11y in Docker)
o11y-local:
@$(call log, Starting observability in LOCAL mode...)
@$(OBS_SCRIPTS_DIR)/start-observability.sh local

## o11y-compose: Start observability in COMPOSE mode (all services in Docker)
o11y-compose:
@$(call log, Starting observability in COMPOSE mode...)
@$(OBS_SCRIPTS_DIR)/start-observability.sh compose

## stop-observability: Stop and remove observability containers
stop-observability:
@$(call log, Stopping observability stack...)
@$(OBS_SCRIPTS_DIR)/stop-observability.sh

## open-observability: Open Prometheus and Grafana in browser
open-observability:
@echo "Opening Prometheus and Grafana..."
@open http://localhost:9090 2>/dev/null || xdg-open http://localhost:9090 2>/dev/null || echo "Please open http://localhost:9090"
@open http://localhost:3000 2>/dev/null || xdg-open http://localhost:3000 2>/dev/null || echo "Please open http://localhost:3000"

## o11y-logs: Show logs from observability containers
o11y-logs:
@docker compose -f docker-compose.obs.yml logs -f 2>/dev/null || docker compose logs prometheus grafana -f

## o11y-status: Check status of observability containers
o11y-status:
@echo "==> Local mode:"
@docker compose -f docker-compose.obs.yml ps 2>/dev/null || echo " Not running"
@echo ""
@echo "==> Compose mode:"
@docker compose ps prometheus grafana 2>/dev/null || echo " Not running"

## o11y-clean: Remove observability data volumes
o11y-clean:
@echo "⚠️ Removing all observability data volumes..."
@docker volume rm prometheus-local-data grafana-local-data prometheus-data grafana-data 2>/dev/null || true
@echo "✓ Done"
30 changes: 30 additions & 0 deletions tools/observability/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Observability Configuration

Prometheus and Grafana configuration files for monitoring semantic-router.

## Files

- `prometheus.yaml` - Prometheus scrape config (uses `$ROUTER_TARGET` env var)
- `grafana-datasource.yaml` - Grafana datasource (uses `$PROMETHEUS_URL` env var)
- `grafana-dashboard.yaml` - Dashboard provisioning config
- `llm-router-dashboard.json` - LLM Router dashboard

## Usage

**Local mode** (router on host, observability in Docker):

```bash
make o11y-local
```

**Compose mode** (all services in Docker):

```bash
make o11y-compose
# or: docker compose up
```

**Access:**

- Prometheus: http://localhost:9090
- Grafana: http://localhost:3000 (admin/admin)
15 changes: 15 additions & 0 deletions tools/observability/grafana-dashboard.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Grafana dashboard provisioning configuration
# This file tells Grafana where to find dashboard JSON files

apiVersion: 1

providers:
- name: "Semantic Router"
orgId: 1
folder: ""
type: file
disableDeletion: false
updateIntervalSeconds: 10
allowUiUpdates: true
options:
path: /etc/grafana/provisioning/dashboards
14 changes: 14 additions & 0 deletions tools/observability/grafana-datasource.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Grafana datasource configuration for Prometheus
# This file is provisioned automatically when Grafana starts

apiVersion: 1

datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://${PROMETHEUS_URL:-localhost:9090}
isDefault: true
editable: true
jsonData:
timeInterval: 15s
Loading
Loading