Skip to content

Monitoring

The API exposes Prometheus metrics at /metrics (text exposition format, no auth). In production the endpoint is restricted to the internal network (192.168.1.0/24 in the reference nginx config).

ComponentPurposeNotes
PrometheusMetrics storage and alertingRules in deploy/monitoring/
GrafanaDashboardsIncludes SLO dashboard (slo_dashboard.json)
LokiLog aggregationStructured JSON logs; retention policy documented
TempoDistributed tracingOpenTelemetry OTLP export
AlertmanagerAlert routingLoaded with Prometheus rule files

The full stack is defined in deploy/docker-compose.prod.yml and can also be deployed independently.

99.9% availability (0.1% error budget per 30-day window), tracked with the multi-window burn-rate approach recommended by Google SRE.

Metric names exposed by the API (used by the alert rules):

MetricTypeDescription
http_requests_totalCounterTotal HTTP requests, labelled by status
http_request_duration_secondsHistogramRequest latency distribution
blocmarket_bids_totalCounterBids placed
blocmarket_registrations_totalCounterUser registrations
blocmarket_transaction_value_totalCounterCumulative transaction value
blocmarket_pool_active_connectionsGaugeActive DB connections
blocmarket_pool_max_connectionsGaugeDB pool maximum

Defined in deploy/monitoring/prometheus_rules.yml:

AlertConditionSeverity
SLOBurnRateHigh1h and 5m error rate above 14.4x burn rate, for 2mCritical
SLOBurnRateWarning6h and 1h error rate above 6x burn rate, for 15mWarning
ErrorBudgetExhausted30-day accumulated error rate >= 0.1% for 5mCritical
ErrorBudgetLow< 20% of the 30-day error budget remainsWarning
HighLatencyP99p99 latency > 2.0s for 5mWarning
HighLatencyP95p95 latency > 1.0s for 5mWarning

Defined in deploy/monitoring/business_alerts.yml — thresholds are starting points; tune against production baselines:

AlertConditionMeaning
BidVolumeAnomaly5m bid rate > 10x same window 1h ago, for 10mViral event or automated bidding
TransactionValueSpikeCumulative transaction value > 100,000Verify against expected daily volume; check for fraud
RegistrationSpike> 20 registrations in 5mPossible bot account creation
HighErrorRate5xx rate > 5% of requests for 5mCheck API logs, DB health, recent deployments
PoolExhaustionDB pool > 90% of maximum for 2mInvestigate slow queries and long transactions

The SLO dashboard (deploy/monitoring/slo_dashboard.json) tracks error budget consumption, burn rate, and latency percentiles. Import it into Grafana alongside per-service dashboards for the API, PostgreSQL, and Redis.

Distributed tracing via the observability crate with OTLP export to Tempo. Traces span API requests through database queries, enabling end-to-end latency analysis.

Logs flow: Application → Promtail → Loki → Grafana.

Structured JSON logging with no PII in production logs. Key patterns to watch:

PatternSeverityMeaning
ERROR.*database.*connectionCriticalDB pool exhausted or PostgreSQL down
ERROR.*redis.*connectionWarningRedis unavailable, rate limiting disabled
WARN.*rate_limitInfoUser hitting rate limit (expected)
ERROR.*migrationCriticalMigration failed on startup
ERROR.*smtpWarningEmail delivery failure

Query Loki directly:

Terminal window
curl -G "http://localhost:3100/loki/api/v1/query_range" \
--data-urlencode 'query={service="api"} |~ "error"'

Baseline targets measured with k6 (scripts/load/api_load_test.js):

MetricTarget
API health< 50ms p50, < 100ms p99
Property search< 200ms p50
Auth (login)< 100ms p50
Notification list< 150ms p50
API memory< 512MB RSS
Concurrent users100 simultaneous
Throughput> 500 rps (read)

Run the load test against a running API:

Terminal window
cargo run -p bloc-api
k6 run scripts/load/api_load_test.js
Terminal window
# Increase log verbosity
export RUST_LOG=info,bloc_api=debug,bloc_market=debug
# Container deployments
docker compose logs -f api
docker compose logs --tail 100 postgres
docker compose logs --tail 100 redis