Source code for threeML.io.logging

import logging
import logging.handlers as handlers
import sys
from contextlib import contextmanager
from pathlib import Path

from astromodels import astromodels_config
from astromodels.utils.logging import (
    LogFilter,
    _console_formatter,
    _dev_formatter,
    _usr_formatter,
    astromodels_console_log_handler,
    astromodels_dev_log_handler,
    astromodels_usr_log_handler,
)

from astromodels.utils.valid_variable import is_valid_variable_name
from rich.console import Console
from rich.logging import RichHandler
from rich.theme import Theme
from threeML.config.config import threeML_config

# set up the console logging


[docs] def invalid_plugin_name(name: str, log: logging.Logger) -> None: if not is_valid_variable_name(name): log.error( f"Name {name} is not a valid name for a plugin. You must use a name which is " "a valid python identifier: no spaces, no operators (+,-,/,*), " "it cannot start with a number, no special characters" ) raise AssertionError( f"Name {name} is not a valid name for a plugin. You must use a name which is " "a valid python identifier: no spaces, no operators (+,-,/,*), " "it cannot start with a number, no special characters" )
[docs] def get_path_of_log_dir() -> Path: """ get the path to the logging directory """ log_path: Path = Path(threeML_config.logging.path).expanduser() if not log_path.exists(): log_path.mkdir(parents=True) return log_path
_log_file_names = ["usr.log", "dev.log"]
[docs] def get_path_of_log_file(log_file: str) -> Path: """ returns the path of the log files """ assert ( log_file in _log_file_names ), f"{log_file} is not one of {_log_file_names}" return get_path_of_log_dir() / log_file
# now create the developer handler that rotates every day and keeps # 10 days worth of backup threeML_dev_log_handler = handlers.TimedRotatingFileHandler( get_path_of_log_file("dev.log"), when="D", interval=1, backupCount=10 ) # lots of info written out threeML_dev_log_handler.setFormatter(_dev_formatter) threeML_dev_log_handler.setLevel(logging.DEBUG) # now set up the usr log which will save the info threeML_usr_log_handler = handlers.TimedRotatingFileHandler( get_path_of_log_file("usr.log"), when="D", interval=1, backupCount=10 ) threeML_usr_log_handler.setLevel(logging.INFO) # lots of info written out threeML_usr_log_handler.setFormatter(_usr_formatter) # now set up the console logger _theme = {} # Banner _theme["h1"] = "deep_sky_blue3" _theme["status.spinner"] = "cyan2" _theme["status.text"] = "deep_sky_blue4" _theme["repr.filename"] = "blue" _theme["repr.number"] = "white" _theme["repr.path"] = "grey37" _theme["repr.str"] = "grey37" _theme["repr.tag_name"] = "white" _theme["repr.url"] = "not bold not italic underline grey84" _theme["log.time"] = "green1" _theme["log.message"] = f"{astromodels_config.logging.message_style}" _theme["logging.level.debug"] = f"{astromodels_config.logging.debug_style}" _theme["logging.level.error"] = f"{astromodels_config.logging.error_style}" _theme["logging.level.info"] = f"{astromodels_config.logging.info_style}" _theme["logging.level.warning"] = f"{astromodels_config.logging.warn_style}" # mytheme = Theme().read(_get_data_file_path("log_theme.ini")) mytheme = Theme(_theme) console = Console(theme=mytheme) threeML_console_log_handler = RichHandler( level="INFO", rich_tracebacks=True, markup=True, console=console ) threeML_console_log_handler.setFormatter(_console_formatter) threeML_console_log_handler.setLevel(threeML_config.logging.level) astromodels_console_log_handler.setLevel(threeML_config.logging.level) warning_filter = LogFilter(logging.WARNING) #### # These control the verbosity of 3ML ####
[docs] class LoggingState(object): def __init__( self, threeML_usr_log_handler, threeML_console_log_handler, astromodels_usr_log_handler, astromodels_console_log_handler, ): """ A container to store the stat of the logs """ # attach the log handlers self.threeML_usr_log_handler = threeML_usr_log_handler self.threeML_console_log_handler = threeML_console_log_handler self.astromodels_usr_log_handler = astromodels_usr_log_handler self.astromodels_console_log_handler = astromodels_console_log_handler # store their current states self.threeML_usr_log_handler_state = threeML_usr_log_handler.level self.threeML_console_log_handler_state = ( threeML_console_log_handler.level ) self.astromodels_usr_log_handler_state = ( astromodels_usr_log_handler.level ) self.astromodels_console_log_handler_state = ( astromodels_console_log_handler.level ) def _store_state(self): self.threeML_usr_log_handler_state = threeML_usr_log_handler.level self.threeML_console_log_handler_state = ( threeML_console_log_handler.level ) self.astromodels_usr_log_handler_state = ( astromodels_usr_log_handler.level ) self.astromodels_console_log_handler_state = ( astromodels_console_log_handler.level )
[docs] def restore_last_state(self): self.threeML_usr_log_handler.setLevel( self.threeML_usr_log_handler_state ) self.threeML_console_log_handler.setLevel( self.threeML_console_log_handler_state ) self.astromodels_usr_log_handler.setLevel( self.astromodels_usr_log_handler_state ) self.astromodels_console_log_handler.setLevel( self.astromodels_console_log_handler_state )
[docs] def silence_logs(self): # store the state self._store_state() # silence the logs self.threeML_usr_log_handler.setLevel(logging.CRITICAL) self.threeML_console_log_handler.setLevel(logging.CRITICAL) self.astromodels_usr_log_handler.setLevel(logging.CRITICAL) self.astromodels_console_log_handler.setLevel(logging.CRITICAL)
[docs] def loud_logs(self): # store the state self._store_state() # silence the logs self.threeML_usr_log_handler.setLevel(logging.INFO) self.threeML_console_log_handler.setLevel(logging.INFO) self.astromodels_usr_log_handler.setLevel(logging.INFO) self.astromodels_console_log_handler.setLevel(logging.INFO)
[docs] def debug_logs(self): # store the state self._store_state() # silence the logs self.threeML_console_log_handler.setLevel(logging.DEBUG) self.astromodels_console_log_handler.setLevel(logging.DEBUG)
_log_state = LoggingState( threeML_usr_log_handler, threeML_console_log_handler, astromodels_usr_log_handler, astromodels_console_log_handler, )
[docs] def silence_progress_bars(): """ Turn off the progress bars """ threeML_config["interface"]["progress_bars"] = "off"
[docs] def activate_progress_bars(): """ Turn on the progress bars """ threeML_config["interface"]["progress_bars"] = "on"
[docs] def toggle_progress_bars(): """ toggle the state of the progress bars """ state = threeML_config["interface"]["progress_bars"] threeML_config["interface"]["progress_bars"] = not state
[docs] def silence_warnings(): """ supress warning messages in console and file usr logs """ threeML_usr_log_handler.addFilter(warning_filter) threeML_console_log_handler.addFilter(warning_filter) astromodels_usr_log_handler.addFilter(warning_filter) astromodels_console_log_handler.addFilter(warning_filter)
[docs] def activate_warnings(): """ supress warning messages in console and file usr logs """ threeML_usr_log_handler.removeFilter(warning_filter) threeML_console_log_handler.removeFilter(warning_filter) astromodels_usr_log_handler.removeFilter(warning_filter) astromodels_console_log_handler.removeFilter(warning_filter)
[docs] def update_logging_level(level): """ update the logging level to the console """ threeML_console_log_handler.setLevel(level) astromodels_console_log_handler.setLevel(level)
[docs] def silence_logs(): """ Turn off all logging """ # handle dev logs independently threeML_dev_log_handler.setLevel(logging.CRITICAL) astromodels_dev_log_handler.setLevel(logging.CRITICAL) _log_state.silence_logs()
[docs] def quiet_mode(): """ turn off all logging and progress bars """ silence_progress_bars() # save state and silence silence_logs()
[docs] def loud_mode(): """ turn on all progress bars and logging """ activate_progress_bars() # save state and make loud _log_state.loud_logs()
[docs] def activate_logs(): """ re-activate silenced logs """ # handle dev logs independently threeML_dev_log_handler.setLevel(logging.DEBUG) astromodels_dev_log_handler.setLevel(logging.DEBUG) _log_state.restore_last_state()
[docs] def debug_mode(): """ activate debug in the console """ # store state and switch console to debug _log_state.debug_logs()
[docs] @contextmanager def silence_console_log(and_progress_bars=True): """ temporarily silence the console and progress bars """ current_console_logging_level = threeML_console_log_handler.level current_usr_logging_level = threeML_usr_log_handler.level threeML_console_log_handler.setLevel(logging.CRITICAL) threeML_usr_log_handler.setLevel(logging.CRITICAL) if and_progress_bars: progress_state = threeML_config.interface.progress_bars threeML_config.interface.progress_bars = "off" try: yield finally: threeML_console_log_handler.setLevel(current_console_logging_level) threeML_usr_log_handler.setLevel(current_usr_logging_level) if and_progress_bars: threeML_config.interface.progress_bars = progress_state
[docs] def setup_logger(name: str) -> logging.Logger: # A logger with name name will be created # and then add it to the print stream log = logging.getLogger(name) # this must be set to allow debug messages through log.setLevel(logging.DEBUG) # add the handlers if threeML_config["logging"]["developer"]: log.addHandler(threeML_dev_log_handler) else: # if we do not want to log developer # for 3ML, then lets not for astromodels astromodels_dev_log_handler.setLevel(logging.CRITICAL) if threeML_config["logging"]["console"]: log.addHandler(threeML_console_log_handler) if threeML_config["logging"]["usr"]: log.addHandler(threeML_usr_log_handler) # we do not want to duplicate teh messages in the parents log.propagate = False return log