rcastriotta
publish
1a3fc6f
import logging
import colorlog
import sys
import time
def initialize_logger(name, level=logging.WARNING):
logger = logging.getLogger(name)
logger.propagate = False
handler = colorlog.StreamHandler(stream=sys.stdout)
formatter = colorlog.ColoredFormatter(
"%(log_color)s[%(asctime)s][%(levelname)s][%(module)s]:%(reset)s %(message)s",
reset=True,
log_colors={
"DEBUG": "cyan",
"INFO": "green",
"WARNING": "yellow",
"ERROR": "red",
"CRITICAL": "red,bg_white",
},
)
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(level)
return logger
def catch_and_log_exceptions_for_sio_event_handlers(sio, logger):
# wrapper should have the same signature as the original function
def decorator(func):
async def catch_exception_wrapper(*args, **kwargs):
try:
return await func(*args, **kwargs)
except Exception as e:
message = f"[app_pubsub] Caught exception in '{func.__name__}' event handler:\n\n{e}"
logger.exception(message, stack_info=True)
try:
exception_data = {
"message": message,
"timeEpochMs": int(time.time() * 1000),
}
# For now let's emit this to all clients. We ultimatley may want to emit it just to the room it's happening in.
await sio.emit("server_exception", exception_data)
except Exception as inner_e:
logger.exception(
f"[app_pubsub] Caught exception while trying to emit server_exception event:\n{inner_e}"
)
# Re-raise the exception so it's handled normally by the server
raise e
# Set the name of the wrapper to the name of the original function so that the socketio server can associate it with the right event
catch_exception_wrapper.__name__ = func.__name__
return catch_exception_wrapper
return decorator