2023-04-28 22:40:46 -07:00
|
|
|
import time
|
|
|
|
from collections.abc import Callable
|
2023-07-16 16:25:33 -07:00
|
|
|
from collections.abc import Generator
|
2023-09-05 22:32:00 -07:00
|
|
|
from collections.abc import Iterator
|
2023-11-07 14:21:04 -08:00
|
|
|
from functools import wraps
|
2023-05-12 20:37:52 -07:00
|
|
|
from typing import Any
|
2023-05-21 13:24:25 -07:00
|
|
|
from typing import cast
|
2023-05-16 20:14:06 -07:00
|
|
|
from typing import TypeVar
|
2023-04-28 22:40:46 -07:00
|
|
|
|
2024-12-13 09:48:43 -08:00
|
|
|
from onyx.utils.logger import setup_logger
|
|
|
|
from onyx.utils.telemetry import optional_telemetry
|
|
|
|
from onyx.utils.telemetry import RecordType
|
2023-04-28 22:40:46 -07:00
|
|
|
|
|
|
|
logger = setup_logger()
|
|
|
|
|
2023-05-16 20:14:06 -07:00
|
|
|
F = TypeVar("F", bound=Callable)
|
2023-09-05 22:32:00 -07:00
|
|
|
FG = TypeVar("FG", bound=Callable[..., Generator | Iterator])
|
2023-05-16 20:14:06 -07:00
|
|
|
|
2023-04-28 22:40:46 -07:00
|
|
|
|
2023-12-24 17:39:37 -08:00
|
|
|
def log_function_time(
|
2024-02-28 13:01:32 -08:00
|
|
|
func_name: str | None = None,
|
|
|
|
print_only: bool = False,
|
|
|
|
debug_only: bool = False,
|
2024-03-05 09:46:02 -08:00
|
|
|
include_args: bool = False,
|
2023-12-24 17:39:37 -08:00
|
|
|
) -> Callable[[F], F]:
|
2023-11-07 14:21:04 -08:00
|
|
|
def decorator(func: F) -> F:
|
|
|
|
@wraps(func)
|
2023-05-12 20:37:52 -07:00
|
|
|
def wrapped_func(*args: Any, **kwargs: Any) -> Any:
|
2023-04-28 22:40:46 -07:00
|
|
|
start_time = time.time()
|
2024-02-04 13:41:19 -08:00
|
|
|
user = kwargs.get("user")
|
2023-04-28 22:40:46 -07:00
|
|
|
result = func(*args, **kwargs)
|
2024-08-18 12:14:32 -07:00
|
|
|
elapsed_time = time.time() - start_time
|
|
|
|
elapsed_time_str = f"{elapsed_time:.3f}"
|
2023-11-16 09:22:36 -08:00
|
|
|
log_name = func_name or func.__name__
|
2024-03-05 09:46:02 -08:00
|
|
|
args_str = f" args={args} kwargs={kwargs}" if include_args else ""
|
|
|
|
final_log = f"{log_name}{args_str} took {elapsed_time_str} seconds"
|
2024-02-28 13:01:32 -08:00
|
|
|
if debug_only:
|
2024-03-05 09:46:02 -08:00
|
|
|
logger.debug(final_log)
|
2024-02-28 13:01:32 -08:00
|
|
|
else:
|
2024-08-18 21:53:40 -07:00
|
|
|
# These are generally more important logs so the level is a bit higher
|
|
|
|
logger.notice(final_log)
|
2023-12-24 17:39:37 -08:00
|
|
|
|
|
|
|
if not print_only:
|
|
|
|
optional_telemetry(
|
|
|
|
record_type=RecordType.LATENCY,
|
|
|
|
data={"function": log_name, "latency": str(elapsed_time_str)},
|
2024-02-04 13:41:19 -08:00
|
|
|
user_id=str(user.id) if user else "Unknown",
|
2023-12-24 17:39:37 -08:00
|
|
|
)
|
|
|
|
|
2023-04-28 22:40:46 -07:00
|
|
|
return result
|
|
|
|
|
2023-05-21 13:24:25 -07:00
|
|
|
return cast(F, wrapped_func)
|
2023-04-28 22:40:46 -07:00
|
|
|
|
2023-11-07 14:21:04 -08:00
|
|
|
return decorator
|
2023-07-16 16:25:33 -07:00
|
|
|
|
|
|
|
|
2023-12-24 17:39:37 -08:00
|
|
|
def log_generator_function_time(
|
|
|
|
func_name: str | None = None, print_only: bool = False
|
|
|
|
) -> Callable[[FG], FG]:
|
2023-11-07 14:21:04 -08:00
|
|
|
def decorator(func: FG) -> FG:
|
|
|
|
@wraps(func)
|
2023-07-16 16:25:33 -07:00
|
|
|
def wrapped_func(*args: Any, **kwargs: Any) -> Any:
|
|
|
|
start_time = time.time()
|
2024-02-04 13:41:19 -08:00
|
|
|
user = kwargs.get("user")
|
2023-11-07 14:21:04 -08:00
|
|
|
gen = func(*args, **kwargs)
|
|
|
|
try:
|
|
|
|
value = next(gen)
|
|
|
|
while True:
|
|
|
|
yield value
|
|
|
|
value = next(gen)
|
|
|
|
except StopIteration:
|
|
|
|
pass
|
|
|
|
finally:
|
2023-11-16 09:22:36 -08:00
|
|
|
elapsed_time_str = str(time.time() - start_time)
|
|
|
|
log_name = func_name or func.__name__
|
|
|
|
logger.info(f"{log_name} took {elapsed_time_str} seconds")
|
2023-12-24 17:39:37 -08:00
|
|
|
if not print_only:
|
|
|
|
optional_telemetry(
|
|
|
|
record_type=RecordType.LATENCY,
|
|
|
|
data={"function": log_name, "latency": str(elapsed_time_str)},
|
2024-02-04 13:41:19 -08:00
|
|
|
user_id=str(user.id) if user else "Unknown",
|
2023-12-24 17:39:37 -08:00
|
|
|
)
|
2023-07-16 16:25:33 -07:00
|
|
|
|
2023-07-22 13:00:51 -07:00
|
|
|
return cast(FG, wrapped_func)
|
2023-07-16 16:25:33 -07:00
|
|
|
|
2023-11-07 14:21:04 -08:00
|
|
|
return decorator
|