Skip to content

Commit

Permalink
Support sync function for observation
Browse files Browse the repository at this point in the history
  • Loading branch information
aleks-v-k committed Nov 2, 2024
1 parent 978acd2 commit 7c0081e
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 14 deletions.
1 change: 0 additions & 1 deletion .github/workflows/python-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ on:

jobs:
test:

runs-on: ubuntu-latest
strategy:
matrix:
Expand Down
32 changes: 25 additions & 7 deletions src/huntflow_base_metrics/base.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Base definitions for metrics collections via prometheus client."""

import inspect
import logging
import platform
import time
Expand Down Expand Up @@ -30,7 +31,7 @@

# Labels must be present in all collectors.
# These labels identify the whole service and it's current instance.
# The values should be set via `init_metrics_common` function
# The values should be set via `start_metrics` function
# before usage.
COMMON_LABELS = [SERVICE_LABEL, POD_LABEL]
COMMON_LABELS_VALUES = {
Expand Down Expand Up @@ -160,22 +161,39 @@ def observe_metrics(
counter.
"""

def wrap(coro: Callable) -> Callable:
@wraps(coro)
async def _wrapper(*args: Any, **kwargs: Any) -> Any:
def wrap(func: Callable) -> Callable:
@wraps(func)
async def wrapper(*args: Any, **kwargs: Any) -> Any:
if not _MetricsContext.enable_metrics:
return await coro(*args, **kwargs)
return await func(*args, **kwargs)
start = time.perf_counter()
if metric_inprogress is not None:
apply_labels(metric_inprogress, method=method).inc()
try:
return await coro(*args, **kwargs)
return await func(*args, **kwargs)
finally:
end = time.perf_counter()
apply_labels(metric_timings, method=method).observe(end - start)
if metric_inprogress is not None:
apply_labels(metric_inprogress, method=method).dec()

return _wrapper
@wraps(func)
def sync_wrapper(*args: Any, **kwargs: Any) -> Any:
if not _MetricsContext.enable_metrics:
return func(*args, **kwargs)
start = time.perf_counter()
if metric_inprogress is not None:
apply_labels(metric_inprogress, method=method).inc()
try:
return func(*args, **kwargs)
finally:
end = time.perf_counter()
apply_labels(metric_timings, method=method).observe(end - start)
if metric_inprogress is not None:
apply_labels(metric_inprogress, method=method).dec()

if inspect.iscoroutinefunction(func):
return wrapper
return sync_wrapper

return wrap
37 changes: 31 additions & 6 deletions tests/test_observe_metrics.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
import time
from unittest.mock import Mock
from uuid import uuid4

Expand All @@ -21,10 +22,19 @@ async def observable_func(sleep_time=None):
await asyncio.sleep(sleep_time)
return sleep_time

@observe_metrics(method, histogram_mock)
def sync_observable_func(sleep_time=None):
if sleep_time:
time.sleep(sleep_time)
return sleep_time

sleep_time = 0.3
result = await observable_func(sleep_time)
assert sleep_time == result

result = sync_observable_func(sleep_time)
assert sleep_time == result

assert not histogram_mock.labels.called


Expand Down Expand Up @@ -55,10 +65,25 @@ async def observable_func(sleep_time=None):
}
)

assert (
REGISTRY.get_sample_value(
"test_timing_histogram_sum",
labels,
)
>= sleep_time
time_sum = REGISTRY.get_sample_value(
"test_timing_histogram_sum",
labels,
)
assert time_sum is not None
assert sleep_time <= time_sum < sleep_time + 0.01

@observe_metrics(method, histogram)
def sync_observable_func(sleep_time=None):
if sleep_time:
time.sleep(sleep_time)
return sleep_time

result = sync_observable_func(sleep_time)
assert sleep_time == result

time_sum = REGISTRY.get_sample_value(
"test_timing_histogram_sum",
labels,
)
assert time_sum is not None
assert sleep_time * 2 <= time_sum < sleep_time * 2 + 0.01

0 comments on commit 7c0081e

Please sign in to comment.