Disciplines · Reference

Monitoring and Observability

Oshun uses a layered observability strategy: OpenTelemetry for instrumentation, Prometheus and Grafana for metrics and dashboards, Jaeger for distributed tracing, and CloudWatch for production AWS monitoring.

7sections2 minread

On this page

Overview#

Oshun uses a layered observability strategy: OpenTelemetry for instrumentation, Prometheus and Grafana for metrics and dashboards, Jaeger for distributed tracing, and CloudWatch for production AWS monitoring.


Development Environment#

Starting Observability Stack#

The observability services are available as a Docker Compose profile:

bash
docker compose -f docker/docker-compose.dev.yml --profile observability up -d

This starts:

Service Port Purpose Credentials
Prometheus 9090 Metrics scraping & storage None
Grafana 3100 Dashboards & visualization admin/admin
Jaeger 16686 Distributed tracing UI None

Prometheus#

URL: http://localhost:9090

Configuration file: docker/observability/prometheus.dev.yml

Prometheus scrapes metrics from all services exposing a /metrics endpoint. Services use @oshun/metrics (which wraps prom-client) to expose Prometheus metrics.

Grafana#

URL: http://localhost:3100

Default credentials: admin / admin

Grafana connects to Prometheus as a data source and provides pre-built dashboards. Dashboard provisioning configs are in docker/observability/grafana/provisioning/.

Jaeger#

URL: http://localhost:16686

Jaeger collects distributed traces via OpenTelemetry. Services use @oshun/tracing to instrument HTTP requests, database queries, and inter-service calls.

Ports:

  • 16686 - UI
  • 14268 - Collector (HTTP)
  • 6831/udp - Agent (Thrift compact)
  • 9411 - Zipkin-compatible endpoint

Instrumentation Libraries#

@oshun/metrics#

Wraps prom-client to provide:

  • HTTP request duration histograms
  • Request count counters
  • Active connection gauges
  • Custom domain-specific metrics
  • /metrics endpoint middleware

@oshun/tracing#

Wraps OpenTelemetry SDK to provide:

  • Automatic HTTP request tracing
  • Database query instrumentation
  • Inter-service propagation (W3C Trace Context)
  • Custom span creation

OpenTelemetry packages used:

  • @opentelemetry/api
  • @opentelemetry/sdk-trace-node
  • @opentelemetry/sdk-trace-base
  • @opentelemetry/exporter-trace-otlp-http
  • @opentelemetry/resources
  • @opentelemetry/semantic-conventions
  • @opentelemetry/context-async-hooks
  • @opentelemetry/propagator-aws-xray (production)

@oshun/health#

Provides standardized health check endpoints:

  • GET /health - Basic liveness check
  • GET /ready - Readiness check (includes dependency verification)

Production Monitoring#

AWS CloudWatch#

Production services log to CloudWatch Logs and emit CloudWatch Metrics via the @aws-sdk/client-cloudwatch SDK.

Terraform modules in infra/terraform/cloudwatch/ configure:

  • Log groups per service
  • Metric alarms
  • Dashboard definitions

Iris Domain: Production Dashboards#

The Iris domain has the most comprehensive production monitoring setup, located in infra/monitoring/iris/:

Prometheus Configuration:

  • prometheus/prometheus.yml - Scrape targets
  • prometheus/recording-rules.yaml - Pre-computed metrics
  • prometheus/servicemonitors.yaml - Kubernetes ServiceMonitor CRDs

Grafana Dashboards:

Dashboard Purpose
iris-overview.json System-wide health overview
iris-agent.json AI agent performance metrics
iris-memory.json Memory service utilization
iris-ai-providers.json LLM provider latency and costs
iris-slo.json Service level objective tracking
iris-conversations.json Conversation analytics

Alerting:

  • alerting/alerts.yaml - Alert rules for critical conditions
  • Kustomize overlays for environment-specific thresholds

Adding Monitoring to a Service#

1. Add metrics#

typescript
import { createMetrics } from '@oshun/metrics';

const metrics = createMetrics({ serviceName: 'my-service' });

// Register custom metrics
const requestCounter = metrics.counter({
  name: 'my_service_requests_total',
  help: 'Total requests processed',
  labelNames: ['method', 'status'],
});

2. Add tracing#

typescript
import { initTracing } from '@oshun/tracing';

initTracing({
  serviceName: 'my-service',
  exporterUrl: process.env.OTEL_EXPORTER_OTLP_ENDPOINT,
});

3. Add health checks#

typescript
import { createHealthCheck } from '@oshun/health';

const health = createHealthCheck({
  checks: {
    database: () => db.ping(),
    redis: () => redis.ping(),
  },
});

app.get('/health', health.liveness);
app.get('/ready', health.readiness);

Admin Tools#

Additional admin tools are available via the tools Docker Compose profile:

bash
docker compose -f docker/docker-compose.dev.yml --profile tools up -d
Tool Port Purpose Credentials
Redis Commander 8081 Redis GUI None
PgAdmin 5050 PostgreSQL GUI admin@oshun.dev/admin
Kafka UI 8082 Kafka management None

Further Reading#