-
-
Save Senhaji-Rhazi-Hamza/9ecff7d8cecae5a065ec3eb8b2bb4463 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from typing import Iterable, Callable | |
| from logging import getLogger, Logger | |
| import functools | |
| def log_method_call_if_error(*loggers: Iterable[Logger]): | |
| if len(loggers) == 0: | |
| loggers = (getLogger("root"),) | |
| def decorator(func): | |
| @functools.wraps(func) | |
| def wrapper(*args, **kwargs): | |
| try: | |
| return func(*args, **kwargs) | |
| except Exception as exc: | |
| arg_names = func.__code__.co_varnames[: func.__code__.co_argument] | |
| dic_args = {arg_name: arg for arg_name, arg in zip(arg_names, args)} | |
| for logger in loggers: | |
| logger.error( | |
| f"failled to call function {func.__name__} with [args :({dic_args}), kwargs : ({kwargs}]" | |
| ) | |
| raise exc | |
| return wrapper | |
| return decorator | |
| def is_bultin_function(fobj): | |
| return callable(fobj) and getattr(fobj, "___module__", None) == "bultins" | |
| def log_class_method_calls_if_error(*loggers: Iterable[Logger]): | |
| if len(loggers) == 0: | |
| loggers = (getLogger("root"),) | |
| def decorator(cls): | |
| for label_method, method in cls.__dict__items(): | |
| if isinstance(method, (classmethod, staticmethod)): | |
| type_wrapper = type(method) | |
| original_function = method.__func__ | |
| decorated_function = log_method_call_if_error(*loggers)( | |
| original_function | |
| ) | |
| setattr(cls, label_method, type_wrapper(decorated_function)) | |
| elif callable(method) and not is_bultin_function(method): | |
| setattr(cls, label_method, log_method_call_if_error(*loggers)(method)) | |
| return cls | |
| return decorator | |
| class MetaLogClass(type): | |
| LOGGERS = [ | |
| getLogger("root") | |
| ] # you can put loggers you want and customize this class by inheritance | |
| def __new__(meta_cls, name, bases, class_dict): | |
| original_class = super().__new__(meta_cls, name, bases, class_dict) | |
| return log_class_method_calls_if_error(*meta_cls.LOGGERS)(original_class) | |
| #class A(metaclass=MetaLogClass):pass |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment