Appearance
Monitoring & Observability
BitDrip exposes health endpoints and structured JSON logs for every service. This guide covers what to monitor and how to wire it into your existing observability stack.
Health Checks
Quick local check: Every installer bundle includes status.sh. Run it from your install directory to get an instant pass/fail summary:
bash
bash status.shIt checks container states and hits every health endpoint, printing the exact docker compose logs command if anything is unhealthy.
All services expose a /health endpoint. The Policy Engine response includes a structured breakdown of each dependency.
| Service | Endpoint | Response |
|---|---|---|
| Proxy Daemon | GET /health | {"status":"ok"} |
| Policy Engine | GET /health | See below |
| Dashboard | GET /health | 200 healthy (nginx) |
Policy Engine /health response format:
json
{
"status": "healthy",
"timestamp": "2026-06-06T12:00:00.000Z",
"version": "2.2.15",
"services": {
"database": { "status": "healthy" },
"cache": { "status": "healthy" }
}
}HTTP status codes:
| HTTP code | status value | Meaning |
|---|---|---|
200 | healthy | Database and Redis are both up |
200 | degraded | Redis is down; database is up — service is running with caching disabled |
503 | unhealthy | Database is unreachable — service cannot serve traffic |
A 503 response means the Policy Engine cannot evaluate content. A 200 degraded response means the service is still serving traffic but Redis caching is unavailable, which may increase evaluation latency.
Use the /health endpoint for:
- Load balancer health checks (configure the load balancer to remove the instance only on
503) - Uptime monitoring (Pingdom, Better Uptime, etc.)
- Kubernetes liveness and readiness probes
Uptime Monitoring
Configure an external check against your Policy Engine health endpoint. A 503 response means content evaluation is unavailable. Recommended check frequency: every 30 seconds.
Monitor URL: http://your-policy-engine:3002/health
Expected status: 200
Alert on: 503 for > 1 minuteStructured Logs
All services emit JSON logs to stdout. Each log line includes:
json
{
"timestamp": "2026-05-24T12:00:00.000Z",
"level": "info",
"message": "Policy evaluation completed",
"logType": "policy_evaluation",
"organizationId": "org_abc123",
"riskScore": 0.87,
"action": "block",
"service": "bitdrip-policy-engine",
"environment": "production"
}Log Types
logType | What it means |
|---|---|
api_request | Every inbound HTTP request with method, path, status, latency |
policy_evaluation | Content evaluation result — action, risk score, detector IDs/versions, match counts, and workstation attribution; no matched text |
policy_violation | High-risk block events (risk > 0.8 or action = block) |
authentication | Login, logout, failed login, API key usage |
security | Security events — rate limit hits, suspicious patterns |
performance | Slow operations (> 100ms policy evaluation) |
Log Drain
BitDrip ships with a built-in HTTP log drain transport. Set these environment variables on the Policy Engine and Proxy Daemon to forward logs to any HTTP endpoint:
bash
LOG_DRAIN_URL=https://your-log-collector/ingest
LOG_DRAIN_SECRET=<shared-secret> # sent as X-Drain-Token headerLogs are batched (up to 100 entries or 10 seconds) and POSTed as a JSON array. The drain transport is fire-and-forget — drain failure never impacts request handling.
Compatible with any HTTP-based log collector: Datadog, Splunk HEC, Elastic, Grafana Loki, or a custom endpoint.
Log Retention
For CIS Control 8 compliance, retain logs for a minimum of 90 days. Forward your logs to your chosen log management system and configure a retention policy there. See Database for backup procedures including audit log export.
Error Tracking
BitDrip supports the SENTRY_DSN environment variable for optional error tracking via Sentry (a third-party service). This is disabled by default and not required for BitDrip to function.
If you choose to use it, set these variables before starting the services:
bash
# Policy Engine
SENTRY_DSN=https://<key>@o<org>.ingest.sentry.io/<project>
# Dashboard (also set at build time via Vite env)
VITE_SENTRY_DSN=https://<key>@o<org>.ingest.sentry.io/<project>If configured, Sentry captures unhandled exceptions and slow database queries. It does not capture policy evaluation content — only metadata (error type, stack trace, org ID). BitDrip functions identically without this set.
Key Metrics to Monitor
Availability
| Metric | Target | Alert threshold |
|---|---|---|
| Proxy Daemon uptime | 99.9% | Any downtime > 1 min |
| Policy Engine uptime | 99.9% | Any downtime > 1 min |
| Database connectivity | 100% | Any failure |
Performance
| Metric | Target | Alert threshold |
|---|---|---|
| Policy evaluation p95 latency | < 100ms | > 250ms |
| Proxy Daemon request time | < 150ms | > 500ms |
| Database query time | < 50ms | > 200ms |
These are logged in every api_request and performance log entry. Parse responseTimeMs and durationMs to build latency histograms in your observability tool.
Business Metrics
Extract these from your audit log or policy evaluation logs:
| Metric | SQL / log filter |
|---|---|
| Block rate by org | logType=policy_evaluation AND action=block |
| Top violated rules | matchedRules[].ruleId aggregated over time |
| Active users (24h) | Distinct userId in logType=authentication |
| Evaluations per hour | Count of logType=policy_evaluation |
Alerting Recommendations
Configure alerts for:
- Health check failure — Policy Engine
/healthreturns503(unhealthy — database unreachable) - Degraded health — Policy Engine
/healthreturns200withstatus: degraded(Redis unavailable — elevated latency expected) - High error rate — > 1% of requests returning 5xx over a 5-minute window
- Evaluation latency spike — p95 > 250ms for > 2 minutes
- License expiry — 30 days before your license expires (check
expclaim in your JWT) - Audit log chain break — The hash chain verification script exits non-zero
