1616
1717import ray
1818from ray ._common .utils import get_or_create_event_loop
19+ from ray ._private .ray_logging .filters import CoreContextFilter
1920from ray .serve ._private .common import (
2021 DeploymentID ,
2122 EndpointInfo ,
3334 REQUEST_LATENCY_BUCKETS_MS ,
3435 SERVE_CONTROLLER_NAME ,
3536 SERVE_HTTP_REQUEST_ID_HEADER ,
37+ SERVE_LOG_COMPONENT ,
38+ SERVE_LOG_COMPONENT_ID ,
39+ SERVE_LOG_REQUEST_ID ,
40+ SERVE_LOG_ROUTE ,
3641 SERVE_LOGGER_NAME ,
3742 SERVE_MULTIPLEXED_MODEL_ID ,
3843 SERVE_NAMESPACE ,
7984from ray .serve .config import HTTPOptions , gRPCOptions
8085from ray .serve .generated .serve_pb2 import HealthzResponse , ListApplicationsResponse
8186from ray .serve .handle import DeploymentHandle
82- from ray .serve .schema import LoggingConfig
87+ from ray .serve .schema import EncodingType , LoggingConfig
8388from ray .util import metrics
8489
8590logger = logging .getLogger (SERVE_LOGGER_NAME )
@@ -127,6 +132,7 @@ def __init__(
127132 is_head : bool ,
128133 proxy_router : ProxyRouter ,
129134 request_timeout_s : Optional [float ] = None ,
135+ access_log_context : Dict [str , Any ] = None ,
130136 ):
131137 self .request_timeout_s = request_timeout_s
132138 if self .request_timeout_s is not None and self .request_timeout_s < 0 :
@@ -203,6 +209,8 @@ def __init__(
203209 # The node is not draining if it's None.
204210 self ._draining_start_time : Optional [float ] = None
205211
212+ self ._access_log_context = access_log_context or {}
213+
206214 getattr (ServeUsageTag , f"{ self .protocol .upper ()} _PROXY_USED" ).record ("1" )
207215
208216 @property
@@ -437,14 +445,16 @@ async def proxy_request(self, proxy_request: ProxyRequest) -> ResponseGenerator:
437445 latency_ms = (time .time () - start_time ) * 1000.0
438446 if response_handler_info .should_record_access_log :
439447 request_context = ray .serve .context ._get_serve_request_context ()
448+ self ._access_log_context [SERVE_LOG_ROUTE ] = request_context .route
449+ self ._access_log_context [SERVE_LOG_REQUEST_ID ] = request_context .request_id
440450 logger .info (
441451 access_log_msg (
442452 method = proxy_request .method ,
443453 route = request_context .route ,
444454 status = str (status .code ),
445455 latency_ms = latency_ms ,
446456 ),
447- extra = { "log_to_stderr" : False , "serve_access_log" : True } ,
457+ extra = self . _access_log_context ,
448458 )
449459
450460 self .request_counter .inc (
@@ -704,13 +714,15 @@ def __init__(
704714 proxy_router : ProxyRouter ,
705715 self_actor_name : str ,
706716 request_timeout_s : Optional [float ] = None ,
717+ access_log_context : Dict [str , Any ] = None ,
707718 ):
708719 super ().__init__ (
709720 node_id ,
710721 node_ip_address ,
711722 is_head ,
712723 proxy_router ,
713724 request_timeout_s = request_timeout_s ,
725+ access_log_context = access_log_context ,
714726 )
715727 self .self_actor_name = self_actor_name
716728 self .asgi_receive_queues : Dict [str , MessageQueue ] = dict ()
@@ -1053,6 +1065,32 @@ def __init__(
10531065 configure_component_memory_profiler (
10541066 component_name = "proxy" , component_id = node_ip_address
10551067 )
1068+ if logging_config .encoding == EncodingType .JSON :
1069+ # Create logging context for access logs as a performance optimization.
1070+ # While logging_utils can automatically add Ray core and Serve access log context,
1071+ # we pre-compute it here since context evaluation is expensive and this context
1072+ # will be reused for multiple access log entries.
1073+ ray_core_logging_context = CoreContextFilter .get_ray_core_logging_context ()
1074+ # remove task level log keys from ray core logging context, it would be nice
1075+ # to have task level log keys here but we are letting those go in favor of
1076+ # performance optimization. Also we cannot include task level log keys here because
1077+ # they would referance the current task (__init__) and not the task that is logging.
1078+ for key in CoreContextFilter .TASK_LEVEL_LOG_KEYS :
1079+ ray_core_logging_context .pop (key , None )
1080+ access_log_context = {
1081+ ** ray_core_logging_context ,
1082+ SERVE_LOG_COMPONENT : "proxy" ,
1083+ SERVE_LOG_COMPONENT_ID : self ._node_ip_address ,
1084+ "log_to_stderr" : False ,
1085+ "skip_context_filter" : True ,
1086+ "serve_access_log" : True ,
1087+ }
1088+ else :
1089+ access_log_context = {
1090+ "log_to_stderr" : False ,
1091+ "skip_context_filter" : True ,
1092+ "serve_access_log" : True ,
1093+ }
10561094
10571095 is_head = self ._node_id == get_head_node_id ()
10581096 self .proxy_router = ProxyRouter (get_proxy_handle )
@@ -1063,6 +1101,7 @@ def __init__(
10631101 self_actor_name = ray .get_runtime_context ().get_actor_name (),
10641102 proxy_router = self .proxy_router ,
10651103 request_timeout_s = self ._http_options .request_timeout_s ,
1104+ access_log_context = access_log_context ,
10661105 )
10671106 self .grpc_proxy = (
10681107 gRPCProxy (
@@ -1071,6 +1110,7 @@ def __init__(
10711110 is_head = is_head ,
10721111 proxy_router = self .proxy_router ,
10731112 request_timeout_s = self ._grpc_options .request_timeout_s ,
1113+ access_log_context = access_log_context ,
10741114 )
10751115 if grpc_enabled
10761116 else None
0 commit comments