Driftbase emits drift scores as OpenTelemetry Protocol (OTLP) compatible metrics, enabling integration with your existing observability stack (Prometheus, Grafana, Datadog, etc.).
Every time you run driftbase diff, drift metrics are automatically written to a local JSON file in OTLP-compatible format. External collectors can scrape this file and forward metrics to your monitoring system.
Default: ~/.driftbase/metrics.json
Override:
export DRIFTBASE_METRICS_PATH=/path/to/metrics.jsonMetrics are enabled by default. To disable:
driftbase diff v1 v2 --no-emit-metricsThe --metrics-endpoint flag is reserved for future direct OTLP push support:
driftbase diff v1 v2 --metrics-endpoint http://localhost:4318Currently, this flag is accepted but unused. Use file-based scraping for now.
Type: Gauge Range: [0, 1] Description: Overall drift score combining all dimensions
{
"name": "driftbase.drift.composite",
"type": "gauge",
"value": 0.45,
"attributes": {
"baseline_version": "v1.0.0",
"current_version": "v1.1.0",
"environment": "production",
"verdict": "MONITOR"
}
}driftbase.drift.decision- Tool sequence outcome distributiondriftbase.drift.latency- P95 latency driftdriftbase.drift.error- Error rate changedriftbase.drift.semantic- Semantic cluster distributiondriftbase.drift.tool_distribution- Tool frequency changesdriftbase.drift.verbosity- Output verbosity ratiodriftbase.drift.loop_depth- Loop count changesdriftbase.drift.output_length- Output length changesdriftbase.drift.tool_sequence- Tool sequence patternsdriftbase.drift.retry- Retry rate changesdriftbase.drift.time_to_first_tool- Planning time changesdriftbase.drift.tool_sequence_transitions- Bigram transition patterns
Type: Gauge Range: [0, 3] Description: Numeric verdict mapping
- 0 = SHIP
- 1 = MONITOR
- 2 = REVIEW
- 3 = BLOCK
Type: Gauge Range: [1, 3] Description: Statistical confidence level
- 1 = TIER1 (n < 15, insufficient data)
- 2 = TIER2 (15 ≤ n < min_runs, directional signal only)
- 3 = TIER3 (n ≥ min_runs, full analysis)
{
"format": "driftbase_otlp_v1",
"exported_at": "2026-04-23T10:30:00.123456",
"metrics": [
{
"name": "driftbase.drift.composite",
"type": "gauge",
"value": 0.45,
"timestamp": 1745324600000,
"attributes": {
"baseline_version": "v1.0.0",
"current_version": "v1.1.0",
"environment": "production",
"verdict": "MONITOR"
}
}
]
}- Convert JSON to Prometheus format:
#!/bin/bash
# /usr/local/bin/driftbase-to-prom.sh
METRICS_FILE="${DRIFTBASE_METRICS_PATH:-$HOME/.driftbase/metrics.json}"
OUTPUT_FILE="/var/lib/node_exporter/textfile_collector/driftbase.prom"
if [ ! -f "$METRICS_FILE" ]; then
echo "# No metrics file found" > "$OUTPUT_FILE"
exit 0
fi
# Extract metrics and convert to Prometheus format
jq -r '.metrics[] |
"# TYPE " + .name + " gauge\n" +
.name + "{" +
(.attributes | to_entries | map(.key + "=\"" + .value + "\"") | join(",")) +
"} " + (.value | tostring)
' "$METRICS_FILE" > "$OUTPUT_FILE.tmp"
mv "$OUTPUT_FILE.tmp" "$OUTPUT_FILE"- Schedule conversion:
* * * * * /usr/local/bin/driftbase-to-prom.sh- Configure Node Exporter:
node_exporter --collector.textfile.directory=/var/lib/node_exporter/textfile_collectorscrape_configs:
- job_name: 'driftbase'
static_configs:
- targets: ['localhost:9100']
relabel_configs:
- source_labels: [__name__]
regex: 'driftbase_.*'
action: keepDrift Score Over Time:
driftbase_drift_composite{environment="production"}
Verdict Distribution:
count by (verdict) (driftbase_verdict)
High-Drift Dimensions:
topk(5,
rate(driftbase_drift_decision[1h]) or
rate(driftbase_drift_latency[1h]) or
rate(driftbase_drift_error[1h])
)
{
"dashboard": {
"title": "Driftbase Drift Monitoring",
"panels": [
{
"title": "Composite Drift Score",
"targets": [
{
"expr": "driftbase_drift_composite",
"legendFormat": "{{baseline_version}} → {{current_version}}"
}
],
"type": "graph"
},
{
"title": "Verdicts",
"targets": [
{
"expr": "driftbase_verdict",
"legendFormat": "{{verdict}}"
}
],
"type": "stat",
"mappings": [
{"value": 0, "text": "SHIP", "color": "green"},
{"value": 1, "text": "MONITOR", "color": "yellow"},
{"value": 2, "text": "REVIEW", "color": "orange"},
{"value": 3, "text": "BLOCK", "color": "red"}
]
}
]
}
}# /etc/datadog-agent/checks.d/driftbase.py
import json
from checks import AgentCheck
class DriftbaseCheck(AgentCheck):
def check(self, instance):
metrics_file = instance.get('metrics_file',
'/home/user/.driftbase/metrics.json')
try:
with open(metrics_file) as f:
data = json.load(f)
for metric in data['metrics']:
tags = [f"{k}:{v}" for k, v in metric['attributes'].items()]
self.gauge(metric['name'], metric['value'], tags=tags)
except Exception as e:
self.log.warning(f"Failed to read driftbase metrics: {e}")# /etc/datadog-agent/conf.d/driftbase.yaml
instances:
- metrics_file: /home/user/.driftbase/metrics.jsongroups:
- name: driftbase
interval: 1m
rules:
- alert: HighDriftScore
expr: driftbase_drift_composite > 0.5
for: 5m
labels:
severity: warning
annotations:
summary: "High drift detected: {{ $labels.baseline_version }} → {{ $labels.current_version }}"
description: "Composite drift score is {{ $value }}"
- alert: BlockVerdict
expr: driftbase_verdict == 3
for: 1m
labels:
severity: critical
annotations:
summary: "BLOCK verdict: {{ $labels.baseline_version }} → {{ $labels.current_version }}"
- alert: InsufficientData
expr: driftbase_confidence_tier < 3
for: 10m
labels:
severity: info
annotations:
summary: "Insufficient data for reliable drift detection"#!/bin/bash
# Alert on high drift
DRIFT_SCORE=$(jq -r '.metrics[] | select(.name == "driftbase.drift.composite") | .value' \
~/.driftbase/metrics.json)
if (( $(echo "$DRIFT_SCORE > 0.5" | bc -l) )); then
curl -X POST https://hooks.slack.com/services/YOUR/WEBHOOK/URL \
-H 'Content-Type: application/json' \
-d "{\"text\": \"🚨 High drift detected: $DRIFT_SCORE\"}"
fiCheck:
# Verify metrics emission is enabled
driftbase diff v1 v2 # Should create/update metrics file
# Check file location
echo $DRIFTBASE_METRICS_PATH
ls -l ~/.driftbase/metrics.json
# Verify file permissions
chmod 644 ~/.driftbase/metrics.jsonCheck:
# Verify Prometheus format conversion
cat /var/lib/node_exporter/textfile_collector/driftbase.prom
# Check Node Exporter
curl http://localhost:9100/metrics | grep driftbaseMetrics are only emitted after a successful driftbase diff. Run a diff first:
driftbase diff v1 v2
cat ~/.driftbase/metrics.json- Feedback Loop - Weight learning from drift verdicts
- Prometheus Documentation
- OpenTelemetry Protocol