Metrics
OpenViking provides a machine-oriented metrics system for exposing runtime health, request status, model usage, resource processing throughput, and probe health states.
Unlike the human-facing /api/v1/observer/* endpoints and the analytics-oriented /api/v1/stats/* endpoints, Metrics are designed for:
- high-frequency scraping by Prometheus, Grafana Agent, and similar systems
- low-cardinality, aggregatable metric models
- monitoring, alerting, capacity observation, and regression diagnosis
Overview
Why Metrics
Metrics are well suited to answer questions like:
- Has HTTP traffic increased abnormally over the last few minutes?
- Are resource ingestion, retrieval, or model calls getting slower?
- Is there queue backlog?
- Are key dependencies such as storage, model providers, VikingDB, encryption, and async systems currently healthy?
- Is a specific tenant showing abnormal traffic or error rates?
Compared with logs and observer snapshots, metrics are better for:
- continuous scraping
- time-series aggregation
- dashboard visualization
- alert rules
How Metrics Differ from Observer and Stats
| Capability | Best For | Output Format | Typical Usage |
|---|---|---|---|
/metrics | online monitoring, alerting, trend aggregation | Prometheus exposition text | Grafana dashboards, Prometheus scraping |
/api/v1/observer/* | human inspection of component snapshots | JSON / status tables | debugging, health checks |
/api/v1/stats/* | analytics-oriented statistics | JSON | memory health, staleness, session extraction |
The boundary is:
/metricsonly carries low-cardinality, low-cost metrics/api/v1/stats/*continues to carry analytics-oriented statistics without being constrained by the Prometheus scraping model
Metrics Architecture
The current metrics stack in OpenViking has four layers:
Business logic / HTTP requests / background tasks
│
▼
DataSource
(event emission / state reads)
│
▼
Collector
(semantic routing + labels)
│
▼
MetricRegistry
(in-process metric store)
│
▼
Exporter
(Prometheus text rendering)
│
▼
/metricsDataSource
DataSources provide inputs to the metrics system in two main forms:
- Event-based: business code emits events at key points, such as retrieval completion, successful model calls, or resource ingestion stage completion
- Read-based: current state is read before
/metricsexport, such as queue state, lock state, or probe state
Collector
Collectors turn inputs into metric semantics:
- choose which metric to write
- choose which labels to attach
- define how failure is exposed, such as
valid=1/0
MetricRegistry
The MetricRegistry is the in-process metric store that keeps the current metric values and serves them to the exporter.
Exporter
The first exporter implementation is the Prometheus exporter, which renders registry contents into Prometheus exposition text.
Usage
Accessing /metrics
/metrics does not require an OpenViking API key. Restrict access at the gateway or reverse proxy when needed.
curl http://localhost:1933/metricsIf your deployment protects /metrics at the gateway, reverse proxy, or service discovery layer, attach auth according to the deployment environment.
Prometheus Scrape Example
scrape_configs:
- job_name: openviking
metrics_path: /metrics
static_configs:
- targets: ["localhost:1933"]Understanding Common Labels
| Label | Meaning | Example |
|---|---|---|
account_id | tenant dimension label | test-account, __unknown__, __overflow__ |
route | HTTP route template | /api/v1/search/find |
method | HTTP method | GET, POST |
status | request or stage status | 200, ok, error |
operation | structured operation name | search.find, resources.add_resource |
context_type | retrieval context type | resource |
provider | model or external service provider | volcengine |
model_name | model name | doubao-seed-1-8-251228 |
stage | stage label (defined by each metric family) | resource stage: parse_artifact; token attribution stage: embed_query |
valid | whether the current sample is fresh and valid | 1 / 0 |
Notes:
account_idis only enabled on controlled allowlisted metric families to prevent high-cardinality growthvalid=0means the current state/probe sample is a fallback or stale value, not that the label itself is malformedstagesemantics depend on the metric family:openviking_resource_stage_*: resource ingestion pipeline stages (for exampleparse_artifact/target_resolve/content_commit)openviking_operation_tokens_total: token attribution stages (for exampleembed_query/rerank/vlm)
Key Metric Families
The tables list representative metrics defined by the collectors. A series appears only when its feature is enabled, the relevant event occurs, and collection succeeds. An absent series does not necessarily mean zero.
Requests and Operations
| Metric Family | Type | Common Labels | Meaning |
|---|---|---|---|
openviking_http_requests_total | Counter | account_id, method, route, status | total HTTP requests |
openviking_http_request_duration_seconds | Histogram | account_id, method, route, status | HTTP latency distribution |
openviking_http_inflight_requests | Gauge | account_id, route | current inflight requests (in-process approximation) |
openviking_operation_requests_total | Counter | account_id, operation, status | total structured operations |
openviking_operation_duration_seconds | Histogram | account_id, operation, status | structured operation duration distribution |
Typical usage:
- inspect whether
/api/v1/search/findor/api/v1/resourcesis slowing down - inspect whether a specific
operationhas elevated error rates
Retrieval and Resource Processing
| Metric Family | Type | Common Labels | Meaning |
|---|---|---|---|
openviking_retrieval_requests_total | Counter | account_id, context_type | retrieval request count |
openviking_retrieval_results_total | Counter | account_id, context_type | total retrieved results |
openviking_retrieval_latency_seconds | Histogram | account_id, context_type | retrieval latency distribution |
openviking_retrieval_zero_result_total | Counter | account_id, context_type | retrieval zero-result count |
openviking_retrieval_rerank_used_total | Counter | account_id | number of retrievals that used rerank |
openviking_retrieval_rerank_fallback_total | Counter | account_id | retrieval rerank fallback count |
openviking_resource_imports_total | Counter | account_id, pipeline, source_type | accepted resource import tasks; Connector imports use pipeline="connector" and source_type="repository" or "document" |
openviking_resource_stage_total | Counter | account_id, stage, status | count of resource ingestion stages |
openviking_resource_stage_duration_seconds | Histogram | account_id, stage, status | duration distribution of ingestion stages |
openviking_resource_wait_duration_seconds | Histogram | account_id, operation | resource ingestion wait duration distribution (for example queue waiting) |
Current built-in resource event producers emit these stage values, depending on the path taken:
source_prepareparse_artifacttarget_resolveupdate_plancontent_commitderived_enqueuesemantic_queue_waitsemantic_executeembedding_queue_waitembedding_execute
The telemetry bridge also recognizes legacy summary keys for request, process, parse, finalize, summarize, wait, and watch. The current resource summary builder does not produce those keys, so they are not additional stages emitted by the current import pipeline. persist is not in that bridge map.
Vector, Memory, and Semantic Metrics
| Metric Family | Type | Common Labels | Meaning |
|---|---|---|---|
openviking_vector_searches_total | Counter | operation | vector search count |
openviking_vector_scored_total | Counter | operation | total scored candidates |
openviking_vector_passed_total | Counter | operation | total passed candidates |
openviking_vector_returned_total | Counter | operation | total returned candidates |
openviking_vector_scanned_total | Counter | operation | total scanned candidates |
openviking_memory_extracted_total | Counter | operation, memory_type | total extracted memory items, split by memory schema type |
openviking_semantic_nodes_total | Counter | status | total semantic nodes |
Model Calls and Tokens
| Metric Family | Type | Common Labels | Meaning |
|---|---|---|---|
openviking_model_calls_total | Counter | model_type, provider, model_name | unified model call count |
openviking_model_tokens_total | Counter | model_type, provider, model_name, token_type | unified model token count |
openviking_vlm_calls_total | Counter | account_id, provider, model_name | VLM call count |
openviking_vlm_tokens_input_total | Counter | account_id, provider, model_name | VLM input tokens |
openviking_vlm_tokens_output_total | Counter | account_id, provider, model_name | VLM output tokens |
openviking_vlm_tokens_total | Counter | account_id, provider, model_name | VLM total tokens |
openviking_vlm_ingestion_tokens_total | Counter | account_id, source_type | VLM total tokens during resource ingestion; source_type is repository or document |
openviking_vlm_call_duration_seconds | Histogram | account_id, provider, model_name | VLM call duration distribution |
openviking_embedding_requests_total | Counter | account_id, status | embedding request count |
openviking_embedding_latency_seconds | Histogram | account_id, status | embedding latency distribution |
openviking_embedding_errors_total | Counter | account_id, error_code | embedding error count |
openviking_embedding_calls_total | Counter | account_id, provider, model_name | embedding provider call count (per-call) |
openviking_embedding_call_duration_seconds | Histogram | account_id, provider, model_name | embedding provider call duration distribution (per-call) |
openviking_embedding_tokens_input_total | Counter | account_id, provider, model_name | embedding input tokens (per-call aggregate) |
openviking_embedding_tokens_output_total | Counter | account_id, provider, model_name | embedding output tokens (per-call aggregate; may not appear if always 0) |
openviking_embedding_tokens_total | Counter | account_id, provider, model_name | embedding total tokens (per-call aggregate) |
openviking_embedding_ingestion_tokens_total | Counter | account_id, source_type | embedding total tokens during resource ingestion; source_type is repository or document |
openviking_rerank_calls_total | Counter | account_id, provider, model_name | rerank provider call count (per-call) |
openviking_rerank_call_duration_seconds | Histogram | account_id, provider, model_name | rerank provider call duration distribution (per-call) |
openviking_rerank_tokens_input_total | Counter | account_id, provider, model_name | rerank input tokens (per-call aggregate) |
openviking_rerank_tokens_output_total | Counter | account_id, provider, model_name | rerank output tokens (per-call aggregate; may not appear if always 0) |
openviking_rerank_tokens_total | Counter | account_id, provider, model_name | rerank total tokens (per-call aggregate) |
openviking_operation_tokens_total | Counter | account_id, operation, stage, token_type | operation token aggregation (token attribution stages) |
Notes:
openviking_model_*gives a unified cross-model view for embedding and VLM usageopenviking_vlm_*andopenviking_embedding_*are better suited for workload-specific dashboards*_requests_*represents business requests;*_calls_*, call duration, and token families represent provider callsopenviking_operation_tokens_totalhas no pre-aggregatedtoken_type="all/total"; aggregate totals in TSDB queries
Queues, Locks, and Runtime State
| Metric Family | Type | Common Labels | Meaning |
|---|---|---|---|
openviking_queue_processed_total | Counter | queue | total processed items per queue |
openviking_queue_errors_total | Counter | queue | total error count per queue |
openviking_queue_pending | Gauge | queue | pending queue items |
openviking_queue_in_progress | Gauge | queue | in-progress queue items |
openviking_queue_process_duration_seconds | Histogram | queue, outcome | handler execution time after a worker dequeues a message |
openviking_queue_end_to_end_duration_seconds | Histogram | queue, outcome | enqueue-to-handler-completion latency, including queue wait time |
openviking_executor_max_workers | Gauge | pool, process_role, worker | maximum workers in the asyncio default executor |
openviking_executor_threads | Gauge | pool, process_role, worker | threads created by the asyncio default executor |
openviking_executor_active_tasks | Gauge | pool, process_role, worker | default executor tasks currently running |
openviking_executor_pending_tasks | Gauge | pool, process_role, worker | default executor tasks waiting to run |
openviking_executor_submitted_total | Counter | pool, process_role, worker | total tasks submitted to the default executor |
openviking_executor_completed_total | Counter | pool, process_role, worker | default executor tasks that finished, including failed tasks |
openviking_executor_failed_total | Counter | pool, process_role, worker | default executor callables that raised exceptions |
openviking_lock_active | Gauge | none | current published lock leases |
openviking_lock_waiting | Gauge | none | requests currently waiting for locks |
openviking_lock_stale | Gauge | none | cumulative count of stale lock tokens removed |
openviking_lock_conflicts_total | Counter | none | observed lock conflicts |
openviking_lock_stale_leases_released_total | Counter | none | stale leases released |
openviking_lock_descendant_scans_total | Counter | none | completed descendant scans |
openviking_lock_descendant_scan_duration_seconds_total | Counter | none | cumulative descendant scan duration |
The queue duration outcome label is one of success, failed, requeued, cancelled, or exception. failed means the handler returned a settled failure that can be acknowledged, while exception means processing raised and the current message is left unacknowledged.
These help answer:
- Is there queue backlog?
- Which queue is slow, and is the latency caused by waiting or processing?
- Is there lock contention or stale locking?
- Is the default executor near its worker limit or building a queue?
Executor metrics only cover loop.run_in_executor(None, ...) and asyncio.to_thread(...). Calls using an explicit custom executor and Rust / RAGFS internal runtimes or threads are not included. failed_total counts callables that raise exceptions. If the caller catches that exception and treats it as a normal branch, it still counts here, so this is not the business request failure count.
RAGFS
RAGFS exports filesystem, cache, multi-backend and lock metrics through one native metrics() call. The collector replaces Registry values directly without computing deltas. Durations are sampled in integer nanoseconds and exported as fractional seconds, for example 123 ns = 0.000000123 seconds.
| Metric Family | Type | Common Labels | Meaning |
|---|---|---|---|
openviking_ragfs_operation_results_total | Counter | plugin, operation, status | successful and failed operations |
openviking_ragfs_operation_duration_seconds | Histogram | plugin, operation | operation duration distribution |
openviking_ragfs_cache_requests_total | Counter | kind, result | file/directory cache hits and misses |
openviking_ragfs_cache_backend_fallbacks_total | Counter | none | backend loads after cache misses |
openviking_ragfs_cache_operations_total | Counter | operation | cache put/delete attempts |
openviking_ragfs_cache_invalidations_total | Counter | none | completed invalidations |
openviking_ragfs_cache_errors_total | Counter | none | cache errors hidden by bypass mode |
openviking_ragfs_cache_policy_bypasses_total | Counter | none | reads bypassing cache |
openviking_ragfs_cache_bytes_total | Counter | source | bytes from backend/cache |
openviking_ragfs_cache_operation_duration_seconds_total | Counter | operation | cumulative get/put/delete duration |
openviking_ragfs_cache_inflight_events_total | Counter | event | leader/follower/backend_saved counts |
openviking_ragfs_multiwrite_background_tasks | Gauge | none | active flush runtime, 0 or 1 per mount |
openviking_ragfs_multiwrite_pending_events | Gauge | none | submitted events that are queued, executing, or awaiting retry |
openviking_ragfs_multiwrite_errors_total | Counter | worker | final failures for flush, checkpoint, catch_up, or gc |
openviking_ragfs_multiwrite_backend_lag_events | Gauge | backend, partition | sum of tail - synced_seq across accounts |
openviking_ragfs_multiwrite_protocol_version | Gauge | version | mount count for the closed label v2 |
openviking_ragfs_multiwrite_protocol_status | Gauge | status | mount count for closed labels migrating and stable |
These metrics have no mount or account_id label. Cache and multi-backend families are absent when those capabilities are not enabled. status is success or error; exists=false is successful and replace uses rename. Histogram buckets cover all outcomes, with finite bounds from 0.0001 to 10 seconds. Python get_stats() retains its microsecond fields.
The protocol family always contains both closed-label series. One unreadable or invalid protocol, account, or segment manifest rejects the whole scrape snapshot instead of publishing partial zero lag.
Tasks and Task Tracker
| Metric Family | Type | Common Labels | Meaning |
|---|---|---|---|
openviking_task_pending | Gauge | task_type | pending tasks tracked by task tracker |
openviking_task_running | Gauge | task_type | running tasks tracked by task tracker |
openviking_task_completed | Gauge | task_type | completed tasks tracked by task tracker |
openviking_task_failed | Gauge | task_type | failed tasks tracked by task tracker |
openviking_task_cancelling | Gauge | task_type | tasks being cancelled |
openviking_task_cancelled | Gauge | task_type | cancelled tasks |
Cache
| Metric Family | Type | Common Labels | Meaning |
|---|---|---|---|
openviking_cache_hits_total | Counter | level | cache hit count |
openviking_cache_misses_total | Counter | level | cache miss count |
Session
| Metric Family | Type | Common Labels | Meaning |
|---|---|---|---|
openviking_session_lifecycle_total | Counter | account_id, action, status | session lifecycle event count |
openviking_session_archive_total | Counter | account_id, status | session archive count |
Feedback
These metrics summarize persisted VikingBot feedback and outcome data at scrape time. They are exported as gauges because the collector recomputes the current aggregate snapshot from bot session files instead of incrementing counters online.
| Metric Family | Type | Common Labels | Meaning |
|---|---|---|---|
openviking_feedback_sessions_scanned_total | Gauge | valid | number of bot sessions scanned for the current snapshot |
openviking_feedback_responses_total | Gauge | valid | total persisted assistant responses included in the snapshot, including legacy responses outside the new observability contract |
openviking_feedback_tracked_responses_total | Gauge | valid | responses covered by the current feedback observability contract (metadata.feedback_events or metadata.response_outcomes) |
openviking_feedback_responses_with_feedback_total | Gauge | valid | responses that have at least one explicit feedback event |
openviking_feedback_events_total | Gauge | valid | explicit feedback event count |
openviking_feedback_thumb_up_total | Gauge | valid | thumb-up event count |
openviking_feedback_thumb_down_total | Gauge | valid | thumb-down event count |
openviking_feedback_positive_outcomes_total | Gauge | valid | responses classified as positive feedback outcomes |
openviking_feedback_negative_outcomes_total | Gauge | valid | responses classified as negative feedback outcomes |
openviking_feedback_reasked_outcomes_total | Gauge | valid | responses classified as reasked outcomes |
openviking_feedback_resolved_outcomes_total | Gauge | valid | responses classified as resolved outcomes |
openviking_feedback_follow_up_without_feedback_outcomes_total | Gauge | valid | responses followed up without explicit feedback |
openviking_feedback_coverage | Gauge | valid | fraction of tracked responses with explicit feedback |
openviking_feedback_thumbs_up_rate | Gauge | valid | fraction of feedback events that are thumbs up |
openviking_feedback_thumbs_down_rate | Gauge | valid | fraction of feedback events that are thumbs down |
openviking_feedback_positive_feedback_rate | Gauge | valid | fraction of tracked responses with positive feedback outcomes |
openviking_feedback_negative_feedback_rate | Gauge | valid | fraction of tracked responses with negative feedback outcomes |
openviking_feedback_reask_rate | Gauge | valid | fraction of tracked responses that led to reasking |
openviking_feedback_one_turn_resolution_rate | Gauge | valid | fraction of tracked responses resolved in one turn |
openviking_feedback_channel_* | Gauge | channel, valid | per-channel variants of response volume, feedback volume, negative outcomes, reasks, coverage, thumb rates, and one-turn resolution |
For mixed historical data, use openviking_feedback_tracked_responses_total as the denominator reference for rate panels. openviking_feedback_responses_total is kept to show overall persisted assistant-response volume, including legacy responses that predate the current feedback metadata contract.
Typical usage:
- build Grafana panels for feedback coverage, thumbs-down rate, and one-turn resolution rate over time
- compare feedback quality across channels such as
cli__defaultandbot_api__demo - alert when
valid="0"appears persistently, which indicates the collector is serving the last successful snapshot after a refresh failure
PromQL / Grafana examples:
- overall feedback coverage:
openviking_feedback_coverage{valid="1"}- overall thumbs-down rate:
openviking_feedback_thumbs_down_rate{valid="1"}- one-turn resolution rate:
openviking_feedback_one_turn_resolution_rate{valid="1"}- per-channel coverage and resolution comparison:
openviking_feedback_channel_coverage{valid="1"}openviking_feedback_channel_one_turn_resolution_rate{valid="1"}- detect fallback snapshots:
max by (job) (openviking_feedback_events_total{valid="0"})Because these are scrape-time snapshot gauges, they work well in Grafana time-series panels and side-by-side channel comparison panels.
For /metrics endpoint behavior and scrape usage, see Metrics API.
Probes and Health State
| Metric Family | Type | Common Labels | Meaning |
|---|---|---|---|
openviking_service_readiness | Gauge | may include valid | main service readiness |
openviking_api_key_manager_readiness | Gauge | may include valid | API key manager readiness |
openviking_storage_readiness | Gauge | probe, valid | storage probe, for example agfs |
openviking_model_provider_readiness | Gauge | provider, valid | whether a VLM client can be created from configuration; no model request is sent |
openviking_async_system_readiness | Gauge | probe, valid | async system readiness |
openviking_retrieval_backend_readiness | Gauge | probe, valid | retrieval backend readiness |
openviking_encryption_component_health | Gauge | valid | overall encryption component health |
openviking_encryption_root_key_ready | Gauge | valid | whether the root key is ready |
openviking_encryption_kms_provider_ready | Gauge | provider, valid | KMS provider readiness |
Meaning of valid:
valid="1": the sample was produced by a successful refreshvalid="0": the sample is a fallback or stale value and should be treated with caution
Encryption (Operational Metrics)
These metrics are driven by Python encryption events and are not complete counts of all encrypted RAGFS file I/O. Assess file throughput together with RAGFS metrics and the enabled backends.
| Metric Family | Type | Common Labels | Meaning |
|---|---|---|---|
openviking_encryption_operations_total | Counter | account_id, operation, status | encrypt/decrypt operation count |
openviking_encryption_duration_seconds | Histogram | account_id, operation, status | encrypt/decrypt duration distribution |
openviking_encryption_bytes_total | Counter | account_id, operation | encrypt/decrypt processed bytes total |
openviking_encryption_payload_size_bytes | Histogram | account_id, operation | encrypt/decrypt payload size distribution |
openviking_encryption_auth_failed_total | Counter | account_id, status | auth-failed count |
openviking_encryption_key_derivation_total | Counter | account_id, status | key derivation count |
openviking_encryption_key_derivation_duration_seconds | Histogram | account_id, status | key derivation duration distribution |
openviking_encryption_key_load_duration_seconds | Histogram | account_id, status, provider | key load duration distribution |
openviking_encryption_key_cache_hits_total | Counter | account_id, provider | key cache hit count |
openviking_encryption_key_cache_misses_total | Counter | account_id, provider | key cache miss count |
openviking_encryption_key_version_usage_total | Counter | account_id, key_version | key version usage count |
Component and Observer Aggregate Metrics
| Metric Family | Type | Common Labels | Meaning |
|---|---|---|---|
openviking_component_health | Gauge | component, valid | component health state |
openviking_component_errors | Gauge | component, valid | component error state |
openviking_observer_components_total | Gauge | valid | number of observed components |
openviking_observer_components_unhealthy | Gauge | valid | number of unhealthy components |
openviking_observer_components_with_errors | Gauge | valid | number of components with errors |
Typical component values include:
queuemodelslockretrievalvikingdbfilesystem
VikingDB and Model Usage Statistics
| Metric Family | Type | Common Labels | Meaning |
|---|---|---|---|
openviking_vikingdb_collection_health | Gauge | collection, valid | collection health |
openviking_vikingdb_collection_vectors | Gauge | collection, valid | current vector count per collection |
openviking_model_usage_available | Gauge | model_type, valid | whether model usage statistics are currently available |
Possible model_type values include:
vlmembeddingrerank
openviking_model_provider_readiness=1 does not verify credentials, quota, or remote inference. It only checks client construction. Use actual model-call errors and latency to assess requests.
Configuration Example
Enabling Metrics
In ov.conf, the metrics subsystem can be explicitly enabled through server.observability.metrics:
{
"server": {
"observability": {
"metrics": {
"enabled": true,
"account_dimension": {
"enabled": true,
"max_active_accounts": 100,
"metric_allowlist": [
"openviking_http_requests_total",
"openviking_http_request_duration_seconds",
"openviking_http_inflight_requests",
"openviking_operation_requests_total",
"openviking_operation_duration_seconds",
"openviking_vlm_calls_total",
"openviking_vlm_call_duration_seconds",
"openviking_rerank_*"
]
}
}
}
}
}Recommended mental model:
server.observability.metrics.enabled: master switch for the metrics subsystemserver.observability.metrics.account_dimension: controls whetheraccount_idlabels are enabled and where they are allowed
Exporters
By default, OpenViking exports metrics via Prometheus exposition format at /metrics. You can also enable additional exporters under server.observability.metrics.exporters.
Key fields:
server.observability.metrics.exporters.prometheus.enabled: enable the Prometheus exporter (serves/metrics)server.observability.metrics.exporters.otel.enabled: enable OTLP export from the same in-process registryserver.observability.metrics.exporters.otel.protocol:"grpc"or"http"server.observability.metrics.exporters.otel.tls.insecure: OTLP/gRPC only;truemeans plaintext (no TLS)server.observability.metrics.exporters.otel.endpoint: OTLP endpoint (for gRPC, usehost:4317; for HTTP, use a full URL)server.observability.metrics.exporters.otel.service_name: OTLPservice.nameresource attribute; defaults to top-levelservice_namewhen omittedserver.observability.metrics.exporters.otel.export_interval_ms: OTLP push interval in milliseconds (default10000)server.observability.metrics.exporters.otel.headers: optional custom OTLP headers; sent as gRPC metadata for gRPC and HTTP headers for HTTP- When using gRPC, header keys in
headersshould be lowercase, for examplex-byteapm-appkey; HTTP does not have this restriction
Example:
{
"server": {
"observability": {
"metrics": {
"enabled": true,
"exporters": {
"prometheus": {
"enabled": true
},
"otel": {
"enabled": true,
"protocol": "grpc",
"tls": {
"insecure": true
},
"endpoint": "otel-collector:4317",
"service_name": "openviking-server",
"export_interval_ms": 10000,
"headers": {}
}
}
}
}
}
}Recommended account_id Usage
- enabled by default, but only allowlisted metric families will receive tenant ids (empty allowlist still yields
__unknown__) - do not turn
user_id,session_id, orresource_uriinto labels - only enable tenant dimensions on a small set of critical dashboard and alert metrics
metric_allowlistsupports a limited wildcard syntax: only trailing*prefix matches (e.g.openviking_rerank_*,openviking_embedding_*)- a standalone
*is not supported, nor full glob/regex patterns
Related Documentation
- Architecture Overview - overall OpenViking architecture
- Multi-Tenant -
account/user/peerisolation model - Data Encryption - storage-layer encryption and isolation
- Metrics API -
/metricsendpoint usage - VikingBot Feedback Observability Design - feedback observability design background and rollout plan (Chinese)