Source code for osl_ephys.utils.logger

"""Logging module for OSL

Heavily inspired by logging in OSL.
"""

# Authors: Andrew Quinn <a.quinn@bham.ac.uk>
#          Chetan Gohil <chetan.gohil@psych.ox.ac.uk>

import yaml
import logging

# Initialise logging for this sub-module
[docs]osl_logger = logging.getLogger("osl_ephys")
osl_logger.setLevel(logging.WARNING) #%% ------------------------------------------------------------
[docs]default_config = """ version: 1 loggers: osl_ephys: level: DEBUG handlers: [console, file] propagate: false handlers: console: class : logging.StreamHandler formatter: brief level : DEBUG stream : ext://sys.stdout file: class : logging.handlers.RotatingFileHandler formatter: verbose filename: {log_file} backupCount: 3 maxBytes: 102400 formatters: brief: format: '{prefix} %(message)s' default: format: '[%(asctime)s] {prefix} %(levelname)-8s : %(message)s' datefmt: '%H:%M:%S' verbose: format: '[%(asctime)s] {prefix} - %(levelname)s - osl-ephys.%(module)s:%(lineno)s : %(message)s' datefmt: '%Y-%m-%d %H:%M:%S' disable_existing_loggers: true """
[docs]def set_up(prefix='', log_file=None, level=None, console_format=None, startup=True): """Initialise the osl-ephys module osl_logger. Parameters ---------- prefix : str Optional prefix to attach to osl_logger output log_file : str Optional path to a log file to record osl_logger output level : {'CRITICAL', 'WARNING', 'INFO', 'DEBUG'} String indicating initial logging level console_format : str Formatting string for console logging. """ # Format config with user options if (len(prefix) > 0) and (console_format != 'verbose'): prefix = prefix + ' :' new_config = default_config.format(prefix=prefix, log_file=log_file) # Load config to dict new_config = yaml.load(new_config, Loader=yaml.FullLoader) # Remove log file from dict if not user requested if log_file is None: new_config['loggers']['osl_ephys']['handlers'] = ['console'] del new_config['handlers']['file'] # Configure osl_logger with dict logging.config.dictConfig(new_config) #osl_logger.config.dictConfig(new_config) # Customise options if level is not None: set_level(level) if console_format is not None: set_format(formatter=console_format, prefix=prefix) if startup: # Say hello osl_logger.info('osl-ephys Logger Started') # Print some info if log_file is not None: osl_logger.info('logging to file: {0}'.format(log_file)) # Attribute to let us know if we have setup the OSL logger osl_logger.already_setup = True
[docs]def set_level(level, handler='console'): """Set new logging level for osl-ephys module. Parameters ---------- level : {'CRITICAL', 'WARNING', 'INFO', 'DEBUG'} String indicating new logging level handler : str The handler to set the level for. Defaults to 'console'. """ osl_logger = logging.getLogger('osl') for handler in osl_logger.handlers: if handler.get_name() == 'console': if level in ['INFO', 'DEBUG']: osl_logger.info("osl-ephys osl_logger: handler '{0}' level set to '{1}'".format(handler.get_name(), level)) handler.setLevel(getattr(logging, level))
[docs]def get_level(handler='console'): """Return current logging level for osl-ephys module. Parameters ---------- handler : str The handler to get the level for. Defaults to 'console'. Returns ------- level : {'CRITICAL', 'WARNING', 'INFO', 'DEBUG'} String indicating current logging level """ osl_logger = logging.getLogger('osl') for handler in osl_logger.handlers: if handler.get_name() == 'console': return handler.level
[docs]def log_or_print(msg, warning=False): """Execute logger.info if an OSL logger has been setup, otherwise print. Parameters ---------- msg : str Message to log/print. warning : bool Is the msg a warning? Defaults to False, which will print info. """ if warning: msg = f"WARNING: {msg}" if hasattr(osl_logger, "already_setup"): osl_logger.info(msg) else: print(msg)