"""
=====================
The Logging Subsystem
=====================
"""
from loguru import logger
from loguru._logger import Logger
from vivarium.framework.logging.utilities import configure_logging_to_terminal
from vivarium.manager import Manager
[docs]
class LoggingManager(Manager):
def __init__(self):
self._simulation_name = None
@staticmethod
def _terminal_logging_not_configured() -> bool:
# This hacks into the internals of loguru to see if we've already configured a
# terminal sink. Loguru maintains a global increment of the loggers it has generated
# and has a default logger configured with id 0. All code paths in this library that
# configure logging handlers delete the default handler with id 0, add a terminal
# logging handler (with id 1) and potentially have a file logging handler with id 2.
# This behavior is based on sequencing of the handle definition. This is a bit
# fragile since it depends on a loguru's internals as well as the stability of code
# paths in vivarium, but both are quite stable at this point, so I think it's pretty,
# low risk.
return 1 not in logger._core.handlers
@property
def name(self):
return "logging_manager"
[docs]
def get_logger(self, component_name: str = None) -> Logger:
bind_args = {"simulation": self._simulation_name}
if component_name:
bind_args["component"] = component_name
return logger.bind(**bind_args)
[docs]
class LoggingInterface:
def __init__(self, manager: LoggingManager):
self._manager = manager
[docs]
def get_logger(self, component_name: str = None) -> Logger:
return self._manager.get_logger(component_name)