2929from vllm .v1 .engine .parallel_sampling import ParentRequest
3030from vllm .v1 .engine .processor import Processor
3131from vllm .v1 .executor .abstract import Executor
32- from vllm .v1 .metrics .loggers import (LoggingStatLogger , PrometheusStatLogger ,
32+ from vllm .v1 .metrics .loggers import (PROMETHEUS_LOGGING_LOGGER_NAME ,
33+ STANDARD_LOGGING_LOGGER_NAME ,
34+ LoggingStatLogger , PrometheusStatLogger ,
3335 StatLoggerBase )
3436from vllm .v1 .metrics .stats import IterationStats , SchedulerStats
3537
@@ -48,6 +50,7 @@ def __init__(
4850 use_cached_outputs : bool = False ,
4951 log_requests : bool = True ,
5052 start_engine_loop : bool = True ,
53+ stat_loggers : Optional [dict [str , StatLoggerBase ]] = None ,
5154 ) -> None :
5255
5356 assert start_engine_loop
@@ -56,11 +59,16 @@ def __init__(
5659
5760 self .log_requests = log_requests
5861 self .log_stats = log_stats
59- self .stat_loggers : list [ StatLoggerBase ] = []
62+ self .stat_loggers : dict [ str , StatLoggerBase ] = dict ()
6063 if self .log_stats :
61- if logger .isEnabledFor (logging .INFO ):
62- self .stat_loggers .append (LoggingStatLogger ())
63- self .stat_loggers .append (PrometheusStatLogger (vllm_config ))
64+ if stat_loggers is not None :
65+ self .stat_loggers = stat_loggers
66+ else :
67+ if logger .isEnabledFor (logging .INFO ):
68+ self .stat_loggers [STANDARD_LOGGING_LOGGER_NAME ] = (
69+ LoggingStatLogger ())
70+ self .stat_loggers [PROMETHEUS_LOGGING_LOGGER_NAME ] = (
71+ PrometheusStatLogger (vllm_config ))
6472
6573 # Tokenizer (+ ensure liveness if running in another process).
6674 self .tokenizer = init_tokenizer_from_configs (
@@ -99,6 +107,7 @@ def from_engine_args(
99107 engine_config : Optional [VllmConfig ] = None ,
100108 start_engine_loop : bool = True ,
101109 usage_context : UsageContext = UsageContext .ENGINE_CONTEXT ,
110+ stat_loggers : Optional [dict [str , StatLoggerBase ]] = None ,
102111 ) -> "AsyncLLM" :
103112 """Create an AsyncLLM from the EngineArgs."""
104113
@@ -118,6 +127,7 @@ def from_engine_args(
118127 log_stats = not engine_args .disable_log_stats ,
119128 start_engine_loop = start_engine_loop ,
120129 usage_context = usage_context ,
130+ stat_loggers = stat_loggers ,
121131 )
122132
123133 def shutdown (self ):
@@ -313,7 +323,7 @@ def _record_stats(
313323 return
314324
315325 assert scheduler_stats is not None
316- for stat_logger in self .stat_loggers :
326+ for stat_logger in self .stat_loggers . values () :
317327 stat_logger .record (scheduler_stats = scheduler_stats ,
318328 iteration_stats = iteration_stats )
319329
@@ -351,9 +361,27 @@ async def do_log_stats(
351361 scheduler_outputs = None ,
352362 model_output = None ,
353363 ) -> None :
354- for stat_logger in self .stat_loggers :
364+ for stat_logger in self .stat_loggers . values () :
355365 stat_logger .log ()
356366
367+ def add_logger (self , logger_name : str , logger : StatLoggerBase ) -> None :
368+ if not self .log_stats :
369+ raise RuntimeError (
370+ "Stat logging is disabled. Set `disable_log_stats=False` "
371+ "argument to enable." )
372+ if logger_name in self .stat_loggers :
373+ raise KeyError (f"Logger with name { logger_name } already exists." )
374+ self .stat_loggers [logger_name ] = logger
375+
376+ def remove_logger (self , logger_name : str ) -> None :
377+ if not self .log_stats :
378+ raise RuntimeError (
379+ "Stat logging is disabled. Set `disable_log_stats=False` "
380+ "argument to enable." )
381+ if logger_name not in self .stat_loggers :
382+ raise KeyError (f"Logger with name { logger_name } does not exist." )
383+ del self .stat_loggers [logger_name ]
384+
357385 async def check_health (self ) -> None :
358386 logger .debug ("Called check_health." )
359387
0 commit comments