import logging from functools import wraps from time import time def log(level): def decorator(func_or_class): logging.basicConfig(level=level) if isinstance(func_or_class, type): @wraps(func_or_class) def wrapper_class(*args, **kwargs): logging.log( level, f"Creating instance of class {func_or_class.__name__}" ) return func_or_class(*args, **kwargs) return wrapper_class else: @wraps(func_or_class) def wrapper(*args, **kwargs): start_time = time() result = func_or_class(*args, **kwargs) duration = time() - start_time logging.log( level, f"Invoked {func_or_class.__name__} with arguments {args}, {kwargs}. " f"elapsed: {duration:.4f}s, return value: {result}", ) return result return wrapper return decorator @log(logging.DEBUG) def example_function(x, y): return x + y @log(logging.INFO) class ExampleClass: def __init__(self, value): self.value = value if __name__ == "__main__": example_function(1, 2) ExampleClass(42) example_function(3, 4) ExampleClass(1337) example_function(5, 6) ExampleClass(9001)