diff --git a/src/xfel_calibrate/setup_logging.py b/src/xfel_calibrate/setup_logging.py index 5526ef72dcd3396d40e6448d4bcdaea7652a8c1b..1ecc6658f3e48f20870ed8fb975efb2af46ee7fe 100644 --- a/src/xfel_calibrate/setup_logging.py +++ b/src/xfel_calibrate/setup_logging.py @@ -1,8 +1,10 @@ import logging +import os import sys import traceback import warnings -import os + +import IPython class ContextFilter(logging.Filter): @@ -18,7 +20,8 @@ formatter = logging.Formatter( '[Notebook: %(notebook)s] - [Directory: %(directory)s] - %(message)s' ) -# Retrieve notebook name and current working directory from environment variables +# Retrieve notebook name and current working directory from +# environment variables NOTEBOOK_NAME = os.getenv('CAL_NOTEBOOK_NAME', 'Unknown notebook') CURRENT_WORKING_DIR = os.getenv('CAL_WORKING_DIR', 'Unknown directory') @@ -37,22 +40,23 @@ warning_handler.setLevel(logging.WARNING) warning_handler.addFilter(lambda record: record.levelno < logging.ERROR) warning_handler.setFormatter(formatter) -# Create console handler for info and debug -# No formatter used for console handler on purpose. -# console is slurm.out & the notebook output cells. -console_handler = logging.StreamHandler() -console_handler.setLevel(logging.DEBUG) +# In case any info is logged and for logged data +# by other packages like calibration_client. +info_handler = logging.FileHandler('info.log') +info_handler.setLevel(logging.DEBUG) +info_handler.setFormatter(formatter) + # Add the custom filter to handlers context_filter = ContextFilter() error_handler.addFilter(context_filter) warning_handler.addFilter(context_filter) -console_handler.addFilter(context_filter) +info_handler.addFilter(context_filter) # Add handlers to logger logger.addHandler(error_handler) logger.addHandler(warning_handler) -logger.addHandler(console_handler) +logger.addHandler(info_handler) handling_error = False @@ -61,7 +65,8 @@ def safe_handle_error(exc_type, exc_value, exc_traceback): global handling_error if handling_error: # Avoid infinite loop of errors. sys.stderr.write("Recursive error detected!\n") - traceback.print_exception(exc_type, exc_value, exc_traceback, file=sys.stderr) + traceback.print_exception( + exc_type, exc_value, exc_traceback, file=sys.stderr) return handling_error = True @@ -70,13 +75,17 @@ def safe_handle_error(exc_type, exc_value, exc_traceback): logger.error( "An error occurred. Exception type: %s, Message: %s", exc_type.__name__, str(exc_value), - extra={'notebook': NOTEBOOK_NAME, 'directory': CURRENT_WORKING_DIR}, + extra={ + 'notebook': NOTEBOOK_NAME, + 'directory': CURRENT_WORKING_DIR + }, exc_info=(exc_type, exc_value, exc_traceback) ) except Exception as log_error: sys.stderr.write(f"Logging failed: {log_error}\n") - traceback.print_exception(exc_type, exc_value, exc_traceback, file=sys.stderr) + traceback.print_exception( + exc_type, exc_value, exc_traceback, file=sys.stderr) finally: handling_error = False @@ -97,6 +106,9 @@ def handle_warning(message, category, filename, lineno, file=None, line=None): sys.excepthook = safe_handle_error warnings.showwarning = handle_warning + # Override IPython's exception handling -import IPython -IPython.core.interactiveshell.InteractiveShell.showtraceback = lambda self, *args, **kwargs: safe_handle_error(*sys.exc_info()) \ No newline at end of file +def custom_showtraceback(self, *args, **kwargs): + return safe_handle_error(*sys.exc_info()) + +IPython.core.interactiveshell.InteractiveShell.showtraceback = custom_showtraceback # noqa