11// SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
22// SPDX-License-Identifier: Apache-2.0
33
4- #[ cfg( feature = "metrics" ) ]
5- use std:: sync:: { Arc , OnceLock } ;
4+ #[ cfg( feature = "runtime-protocols" ) ]
5+ use std:: sync:: Arc ;
6+ #[ cfg( all( feature = "metrics" , feature = "runtime-protocols" ) ) ]
7+ use std:: sync:: OnceLock ;
68
9+ #[ cfg( feature = "runtime-protocols" ) ]
10+ use dynamo_runtime:: component:: Component ;
11+ #[ cfg( all( feature = "metrics" , feature = "runtime-protocols" ) ) ]
12+ use dynamo_runtime:: metrics:: MetricsHierarchy ;
713#[ cfg( feature = "metrics" ) ]
8- use dynamo_runtime:: {
9- component:: Component ,
10- metrics:: { MetricsHierarchy , prometheus_names:: kvrouter} ,
11- } ;
1214use prometheus:: { IntCounterVec , Opts } ;
1315
1416use crate :: protocols:: { KvCacheEventData , KvCacheEventError } ;
@@ -17,9 +19,17 @@ use crate::protocols::{KvCacheEventData, KvCacheEventError};
1719#[ derive( Clone ) ]
1820pub struct KvIndexerMetrics {
1921 /// Counter of events applied.
22+ #[ cfg( feature = "metrics" ) ]
2023 pub kv_cache_events_applied : IntCounterVec ,
2124}
2225
26+ #[ cfg( not( feature = "metrics" ) ) ]
27+ impl Default for KvIndexerMetrics {
28+ fn default ( ) -> Self {
29+ Self { }
30+ }
31+ }
32+
2333/// Metric status labels.
2434pub const METRIC_STATUS_OK : & str = "ok" ;
2535pub const METRIC_STATUS_PARENT_NOT_FOUND : & str = "parent_block_not_found" ;
@@ -32,9 +42,10 @@ pub const METRIC_EVENT_REMOVED: &str = "removed";
3242pub const METRIC_EVENT_CLEARED : & str = "cleared" ;
3343
3444/// Metric name for KV cache events applied counter.
45+ const KV_CACHE_EVENTS_APPLIED_SUFFIX : & str = "kv_cache_events_applied" ;
3546const KV_CACHE_EVENTS_APPLIED_NAME : & str = "dynamo_kvrouter_kv_cache_events_applied" ;
3647
37- #[ cfg( feature = "metrics" ) ]
48+ #[ cfg( all ( feature = "metrics" , feature = "runtime-protocols" ) ) ]
3849static KV_INDEXER_METRICS : OnceLock < Arc < KvIndexerMetrics > > = OnceLock :: new ( ) ;
3950
4051impl KvIndexerMetrics {
@@ -47,26 +58,40 @@ impl KvIndexerMetrics {
4758
4859 /// Creates a new KvIndexerMetrics from a Component, memoizing the result in
4960 /// KV_INDEXER_METRICS to avoid duplicate registration issues.
50- #[ cfg( feature = "metrics " ) ]
61+ #[ cfg( feature = "runtime-protocols " ) ]
5162 pub fn from_component ( component : & Component ) -> Arc < Self > {
52- KV_INDEXER_METRICS . get_or_init ( || {
53- match component. metrics ( ) . create_intcountervec (
54- kvrouter:: KV_CACHE_EVENTS_APPLIED ,
55- "Total number of KV cache events applied to index" ,
56- & [ "event_type" , "status" ] ,
57- & [ ] ,
58- ) {
59- Ok ( kv_cache_events_applied) => Arc :: new ( Self :: new ( kv_cache_events_applied) ) ,
60- Err ( e) => {
61- tracing:: warn!( "Failed to create kv indexer metrics from component: {}. Using unregistered metrics as fallback." , e) ;
62- Arc :: new ( Self :: new_unregistered ( ) )
63- }
64- }
65- } ) . clone ( )
63+ #[ cfg( feature = "metrics" ) ]
64+ {
65+ KV_INDEXER_METRICS
66+ . get_or_init ( || {
67+ match component. metrics ( ) . create_intcountervec (
68+ KV_CACHE_EVENTS_APPLIED_SUFFIX ,
69+ "Total number of KV cache events applied to index" ,
70+ & [ "event_type" , "status" ] ,
71+ & [ ] ,
72+ ) {
73+ Ok ( kv_cache_events_applied) => {
74+ Arc :: new ( Self :: new ( kv_cache_events_applied) )
75+ }
76+ Err ( e) => {
77+ tracing:: warn!( "Failed to create kv indexer metrics from component: {}. Using unregistered metrics as fallback." , e) ;
78+ Arc :: new ( Self :: new_unregistered ( ) )
79+ }
80+ }
81+ } )
82+ . clone ( )
83+ }
84+
85+ #[ cfg( not( feature = "metrics" ) ) ]
86+ {
87+ let _ = component;
88+ Arc :: new ( Self :: new_unregistered ( ) )
89+ }
6690 }
6791
6892 /// Creates a new KvIndexerMetrics which is not registered with a MetricsRegistry.
6993 /// This may be used for tests or as a fallback for when a MetricsRegistry is not available / has errored.
94+ #[ cfg( feature = "metrics" ) ]
7095 pub fn new_unregistered ( ) -> Self {
7196 Self {
7297 kv_cache_events_applied : IntCounterVec :: new (
@@ -80,6 +105,12 @@ impl KvIndexerMetrics {
80105 }
81106 }
82107
108+ /// Creates a no-op metrics instance when Prometheus support is disabled.
109+ #[ cfg( not( feature = "metrics" ) ) ]
110+ pub fn new_unregistered ( ) -> Self {
111+ Self :: default ( )
112+ }
113+
83114 pub fn get_event_type ( event_data : & KvCacheEventData ) -> & ' static str {
84115 match event_data {
85116 KvCacheEventData :: Stored ( _) => METRIC_EVENT_STORED ,
@@ -93,22 +124,27 @@ impl KvIndexerMetrics {
93124 event_type : & ' static str ,
94125 result : Result < ( ) , KvCacheEventError > ,
95126 ) {
96- match result {
97- Ok ( _) => {
98- self . kv_cache_events_applied
99- . with_label_values ( & [ event_type, METRIC_STATUS_OK ] )
100- . inc_by ( 1 ) ;
101- }
102- Err ( e) => {
103- let error_label = match e {
104- KvCacheEventError :: ParentBlockNotFound => METRIC_STATUS_PARENT_NOT_FOUND ,
105- KvCacheEventError :: BlockNotFound => METRIC_STATUS_BLOCK_NOT_FOUND ,
106- KvCacheEventError :: InvalidBlockSequence => METRIC_STATUS_INVALID_BLOCK ,
107- } ;
108- self . kv_cache_events_applied
109- . with_label_values ( & [ event_type, error_label] )
110- . inc_by ( 1 ) ;
127+ #[ cfg( feature = "metrics" ) ]
128+ {
129+ match result {
130+ Ok ( _) => {
131+ self . kv_cache_events_applied
132+ . with_label_values ( & [ event_type, METRIC_STATUS_OK ] )
133+ . inc_by ( 1 ) ;
134+ }
135+ Err ( e) => {
136+ let error_label = match e {
137+ KvCacheEventError :: ParentBlockNotFound => METRIC_STATUS_PARENT_NOT_FOUND ,
138+ KvCacheEventError :: BlockNotFound => METRIC_STATUS_BLOCK_NOT_FOUND ,
139+ KvCacheEventError :: InvalidBlockSequence => METRIC_STATUS_INVALID_BLOCK ,
140+ } ;
141+ self . kv_cache_events_applied
142+ . with_label_values ( & [ event_type, error_label] )
143+ . inc_by ( 1 ) ;
144+ }
111145 }
112146 }
147+ #[ cfg( not( feature = "metrics" ) ) ]
148+ let _ = ( self , event_type, result) ;
113149 }
114150}
0 commit comments