"""Logging utilities."""
import logging
import logging.config
from contextlib import contextmanager
from copy import deepcopy
from time import process_time
__all__ = [
    "Formatter",
    "make_formatter",
    "setup",
    "silence_log",
]
[docs]@contextmanager
def silence_log():
    """Context manager to temporarily silence log output.
    Examples
    --------
    >>> with silence_log():
    >>>     log.warning("This message is not recorded.")
    """
    # Restore the log level at the end of the context
    with preserve_log_level():
        # Set the level to a very high value
        logging.getLogger(__name__.split(".")[0]).setLevel(100)
        yield 
@contextmanager
def preserve_log_level():
    """Context manager to preserve the level of the ``message_ix_models`` logger."""
    # Get the top-level logger for the package containing this file
    main_log = logging.getLogger(__name__.split(".")[0])
    try:
        # Store the current level
        level = main_log.getEffectiveLevel()
        yield
    finally:
        # Restore the level
        main_log.setLevel(level)
_TIMES = []
def mark_time(quiet=False):
    """Record and log (if `quiet` is :obj:`True`) a time mark."""
    _TIMES.append(process_time())
    if not quiet and len(_TIMES) > 1:
        logging.getLogger(__name__).info(
            f" +{_TIMES[-1] - _TIMES[-2]:.1f} = {_TIMES[-1]:.1f} seconds"
        )
CONFIG = dict(
    version=1,
    disable_existing_loggers=False,
    formatters=dict(simple={"()": "message_ix_models.util._logging.make_formatter"}),
    handlers=dict(
        console={
            "class": "logging.StreamHandler",
            "level": "NOTSET",
            "formatter": "simple",
            "stream": "ext://sys.stdout",
        },
        # commented: needs code in setup() to choose an appropriate file path
        # file_handler={
        #    "class": "logging.handlers.RotatingFileHandler",
        #    "level": "DEBUG",
        #    "formatter": "simple",
        #    "backupCount": "100",
        #    "delay": True,
        # },
    ),
    loggers=dict(
        message_ix_models=dict(
            level="NOTSET",
            # propagate=False,
            # handlers=[],
        ),
        message_data=dict(
            level="NOTSET",
            # propagate=False,
            # handlers=[],
        ),
    ),
    root=dict(
        handlers=[],
    ),
)
[docs]def setup(
    level="NOTSET",
    console=True,
    # file=False,
):
    """Initialize logging.
    Parameters
    ----------
    level : str, optional
        Log level for :mod:`message_ix_models` and :mod:`message_data`.
    console : bool, optional
        If :obj:`True`, print all messages to console using a :class:`Formatter`.
    """
    # Copy to avoid modifying with the operations below
    config = deepcopy(CONFIG)
    config["root"].setdefault("level", level)
    if console:
        config["root"]["handlers"].append("console")
    # if file:
    #     config["loggers"]["message_data"]["handlers"].append("file")
    # Apply the configuration
    logging.config.dictConfig(config)