Skip to content

Commit

Permalink
Track response start duration
Browse files Browse the repository at this point in the history
This commit adds a feature to track the latency excluding
streaming duration.
  • Loading branch information
Shinya Maeda committed Mar 4, 2024
1 parent b645ccb commit 019c8a5
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 3 deletions.
13 changes: 11 additions & 2 deletions src/prometheus_fastapi_instrumentator/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def __init__(
modified_handler: str,
modified_status: str,
modified_duration: float,
modified_duration_without_streaming: float,
):
"""Creates Info object that is used for instrumentation functions.
Expand All @@ -42,6 +43,8 @@ def __init__(
by instrumentator. For example grouping into `2xx`, `3xx` and so on.
modified_duration (float): Latency representation after processing
by instrumentator. For example rounding of decimals. Seconds.
modified_duration_without_streaming (float): Latency between request arrival and response starts (i.e. first chunk duration).
Excluding the streaming duration.
"""

self.request = request
Expand All @@ -50,6 +53,7 @@ def __init__(
self.modified_handler = modified_handler
self.modified_status = modified_status
self.modified_duration = modified_duration
self.modified_duration_without_streaming = modified_duration_without_streaming


def _build_label_attribute_names(
Expand Down Expand Up @@ -114,6 +118,7 @@ def latency(
should_include_handler: bool = True,
should_include_method: bool = True,
should_include_status: bool = True,
should_exclude_streaming_duration: bool = False,
buckets: Sequence[Union[float, str]] = Histogram.DEFAULT_BUCKETS,
registry: CollectorRegistry = REGISTRY,
) -> Optional[Callable[[Info], None]]:
Expand Down Expand Up @@ -184,15 +189,19 @@ def latency(
)

def instrumentation(info: Info) -> None:
duration = info.modified_duration
if should_exclude_streaming_duration == True:
duration = info.modified_duration_without_streaming

if label_names:
label_values = [
getattr(info, attribute_name)
for attribute_name in info_attribute_names
]

METRIC.labels(*label_values).observe(info.modified_duration)
METRIC.labels(*label_values).observe(duration)
else:
METRIC.observe(info.modified_duration)
METRIC.observe(duration)

return instrumentation
except ValueError as e:
Expand Down
10 changes: 9 additions & 1 deletion src/prometheus_fastapi_instrumentator/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
status_code = 500
headers = []
body = b""
response_start_time = None

# Message body collected for handlers matching body_handlers patterns.
if any(pattern.search(handler) for pattern in self.body_handlers):
Expand All @@ -158,9 +159,10 @@ async def send_wrapper(message: Message) -> None:

async def send_wrapper(message: Message) -> None:
if message["type"] == "http.response.start":
nonlocal status_code, headers
nonlocal status_code, headers, response_start_time
headers = message["headers"]
status_code = message["status"]
response_start_time = default_timer()
await send(message)

try:
Expand All @@ -176,12 +178,17 @@ async def send_wrapper(message: Message) -> None:

if not is_excluded:
duration = max(default_timer() - start_time, 0)
duration_without_streaming = 0

if response_start_time:
duration_without_streaming = max(response_start_time - start_time, 0)

if self.should_instrument_requests_inprogress:
inprogress.dec()

if self.should_round_latency_decimals:
duration = round(duration, self.round_latency_decimals)
duration_without_streaming = round(duration_without_streaming, self.round_latency_decimals)

if self.should_group_status_codes:
status = status[0] + "xx"
Expand All @@ -197,6 +204,7 @@ async def send_wrapper(message: Message) -> None:
modified_handler=handler,
modified_status=status,
modified_duration=duration,
modified_duration_without_streaming=duration_without_streaming,
)

for instrumentation in self.instrumentations:
Expand Down

0 comments on commit 019c8a5

Please sign in to comment.