Skip to main content

Prometheus Metrics

PRISM exports metrics in Prometheus text exposition format on the admin API at GET /metrics.

Request Metrics

MetricTypeDescription
prism_requests_total{status="hit|miss|bypass|stale|error"}counterTotal requests by cache status
prism_inflight_requestsgaugeCurrently processing requests
prism_rate_limit_rejections_totalcounterRequests rejected by rate limiter (429)

Render Metrics

MetricTypeDescription
prism_render_activegaugeCurrently active renders
prism_render_queue_depthgaugeRequests waiting for a Chrome tab
prism_render_totalcounterTotal renders completed
prism_render_duration_mshistogramRender duration in milliseconds
prism_shadow_renders_totalcounterShadow renders completed (shadow mode)
prism_content_validation_failures_totalcounterRenders that failed content validation

prism_render_duration_ms histogram buckets: 100, 250, 500, 1000, 2500, 5000, 10000, 30000

Cache Metrics

MetricTypeDescription
prism_cache_entriesgaugeNumber of entries in the render cache
prism_cache_memory_bytesgaugeMemory used by cached entries
prism_cache_evictions_totalcounterCache entries evicted (LRU or TTL)

Chrome Tab Pool Metrics

MetricTypeDescription
prism_tab_pool_sizegaugeTotal tabs in the pool
prism_tab_pool_availablegaugeIdle tabs available for rendering
prism_tab_crashes_totalcounterTab crashes detected
prism_tab_creates_totalcounterNew tabs created
prism_tab_recycles_totalcounterTabs recycled after max renders
prism_chrome_restarts_totalcounterFull Chrome process restarts

Origin Metrics

MetricTypeDescription
prism_origin_requests_totalcounterRequests forwarded to the origin server
prism_origin_duration_sum_mscounterCumulative origin request duration (ms)

Warmup Metrics

MetricTypeDescription
prism_warmup_urls_processedcounterURLs successfully warmed up
prism_warmup_urls_failedcounterURLs that failed during warmup

Circuit Breaker

MetricTypeDescription
prism_circuit_breaker_stategauge0 = closed (healthy), 1 = open (tripped), 2 = half-open (probing)

System Metrics

MetricTypeDescription
prism_uptime_secondsgaugeSeconds since PRISM started
process_resident_memory_bytesgaugeResident memory (RSS) of the PRISM process
process_virtual_memory_bytesgaugeVirtual memory of the PRISM process
process_cpu_seconds_totalcounterTotal CPU time consumed
process_open_fdsgaugeOpen file descriptors
process_max_fdsgaugeMaximum file descriptors (ulimit)
process_threadsgaugeNumber of OS threads

Scrape Configuration

Add PRISM to your Prometheus scrape_configs:

scrape_configs:
- job_name: prism
scrape_interval: 15s
static_configs:
- targets: ['127.0.0.1:4001']
# If bearer_token is configured:
authorization:
type: Bearer
credentials: your-secret-token

Grafana Dashboard

Import this JSON snippet as a Grafana dashboard to get started with key panels:

{
"title": "Trident PRISM",
"panels": [
{
"title": "Cache Hit Rate",
"type": "stat",
"targets": [
{
"expr": "rate(prism_requests_total{status=\"hit\"}[5m]) / (rate(prism_requests_total{status=\"hit\"}[5m]) + rate(prism_requests_total{status=\"miss\"}[5m]))",
"legendFormat": "Hit Rate"
}
],
"fieldConfig": {
"defaults": { "unit": "percentunit", "thresholds": { "steps": [
{ "value": 0, "color": "red" },
{ "value": 0.7, "color": "yellow" },
{ "value": 0.9, "color": "green" }
]}}
}
},
{
"title": "Render Duration (p50 / p95 / p99)",
"type": "timeseries",
"targets": [
{
"expr": "histogram_quantile(0.50, rate(prism_render_duration_ms_bucket[5m]))",
"legendFormat": "p50"
},
{
"expr": "histogram_quantile(0.95, rate(prism_render_duration_ms_bucket[5m]))",
"legendFormat": "p95"
},
{
"expr": "histogram_quantile(0.99, rate(prism_render_duration_ms_bucket[5m]))",
"legendFormat": "p99"
}
],
"fieldConfig": { "defaults": { "unit": "ms" } }
},
{
"title": "Active Renders & Queue Depth",
"type": "timeseries",
"targets": [
{ "expr": "prism_render_active", "legendFormat": "Active" },
{ "expr": "prism_render_queue_depth", "legendFormat": "Queued" }
]
},
{
"title": "Tab Pool",
"type": "timeseries",
"targets": [
{ "expr": "prism_tab_pool_size", "legendFormat": "Total" },
{ "expr": "prism_tab_pool_available", "legendFormat": "Available" }
]
},
{
"title": "Cache Entries & Memory",
"type": "timeseries",
"targets": [
{ "expr": "prism_cache_entries", "legendFormat": "Entries" },
{ "expr": "prism_cache_memory_bytes", "legendFormat": "Memory (bytes)" }
]
},
{
"title": "Circuit Breaker State",
"type": "stat",
"targets": [
{ "expr": "prism_circuit_breaker_state", "legendFormat": "State" }
],
"fieldConfig": {
"defaults": {
"mappings": [
{ "type": "value", "options": { "0": { "text": "CLOSED", "color": "green" } } },
{ "type": "value", "options": { "1": { "text": "OPEN", "color": "red" } } },
{ "type": "value", "options": { "2": { "text": "HALF-OPEN", "color": "yellow" } } }
]
}
}
},
{
"title": "Origin Latency (avg)",
"type": "timeseries",
"targets": [
{
"expr": "rate(prism_origin_duration_sum_ms[5m]) / rate(prism_origin_requests_total[5m])",
"legendFormat": "Avg Origin Latency (ms)"
}
],
"fieldConfig": { "defaults": { "unit": "ms" } }
},
{
"title": "Process Memory",
"type": "timeseries",
"targets": [
{ "expr": "process_resident_memory_bytes", "legendFormat": "RSS" },
{ "expr": "process_virtual_memory_bytes", "legendFormat": "Virtual" }
],
"fieldConfig": { "defaults": { "unit": "bytes" } }
}
]
}

Key Alerts

groups:
- name: prism
rules:
- alert: PrismCircuitBreakerOpen
expr: prism_circuit_breaker_state == 1
for: 1m
labels: { severity: critical }
annotations:
summary: "PRISM circuit breaker is open — renders disabled"

- alert: PrismHighRenderLatency
expr: histogram_quantile(0.95, rate(prism_render_duration_ms_bucket[5m])) > 10000
for: 5m
labels: { severity: warning }
annotations:
summary: "PRISM p95 render latency > 10s"

- alert: PrismTabPoolExhausted
expr: prism_tab_pool_available == 0
for: 2m
labels: { severity: warning }
annotations:
summary: "No available Chrome tabs in the pool"