"""
===============
Logging Manager
===============
"""
from __future__ import annotations
import loguru
from vivarium.engine.framework.logging.utilities import configure_logging_to_terminal
from vivarium.engine.manager import Manager
[docs]
class LoggingManager(Manager):
def __init__(self) -> None:
self._simulation_name: str | None = 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 loguru.logger._core.handlers # type: ignore[attr-defined]
@property
def name(self) -> str:
return "logging_manager"
[docs]
def get_logger(self, component_name: str | None = None) -> loguru.Logger:
bind_args = {"simulation": self._simulation_name}
if component_name:
bind_args["component"] = component_name
return loguru.logger.bind(**bind_args)