import logging
DEBUG_MODE = False
LOG_FILE = False
BUFFER = 1
ticker = 1
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.handlers = []
if LOG_FILE:
logger.propagate = False
console_handler = logging.FileHandler(LOG_FILE)
else:
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
console_formatter = logging.Formatter("%(name)s - %(levelname)s - %(message)s")
console_handler.setFormatter(console_formatter)
logger.addHandler(console_handler)
[docs]
def log_decorator(func):
"""
Decorator to log functions while in debug mode, i.e., when
`debug_montecarlo` is True in the config. Works for
`@jit'd and `@njit`'d functions, but with a significant speed
penalty.
TODO: in nopython mode: do I need a context manager?
Input:
func : (function) function to be logged.
Output:
wrapper : (function) wrapper to the function being logged.
"""
# to ensure that calling `help` on the decorated function still works
# @wraps(func)
def wrapper(*args, **kwargs):
"""
Wrapper to the log_decorator.
When called, it has the side effect of
logging every `BUFFER` input and output to `func`, if `DEBUG_MODE` is
`True`.
Input:
*args : arguments to be passed to `func`.
**kwargs : keyword arguments to be passed to `func`.
Output:
result : result of calling `func` on `*args` and `**kwargs`.
"""
result = func(*args, **kwargs)
if DEBUG_MODE:
global ticker
ticker += 1
if ticker % BUFFER == 0: # without a buffer, performance suffers
logger.debug(f"Func: {func.__name__}. Input: {(args, kwargs)}")
logger.debug(f"Output: {result}.")
return result
return wrapper