Source code for pyisyox.logging

"""Logging helper functions.

The ``VERBOSE`` level (numeric ``5``) sits below ``DEBUG`` and is used for
high-volume wire-shape diagnostics:

* Full ``/api/*`` JSON payloads on initial load (``IoXClient._get_json``).
* Raw WebSocket frames before they're parsed (``WebSocketEventStream``).

``DEBUG`` keeps the higher-signal lifecycle and one-line summaries; flip
to ``VERBOSE`` only when chasing a wire-protocol bug. The level name is
registered at import time so consumers like Home Assistant (which never
calls :func:`enable_logging`) can still set ``pyisyox: verbose`` in
``configuration.yaml`` and see the level rendered correctly in logs.
"""

import logging

_LOGGER = logging.getLogger(__package__)
LOG_LEVEL = logging.DEBUG
LOG_VERBOSE = 5
LOG_FORMAT = "%(asctime)s %(levelname)s [%(name)s] %(message)s"
LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
LOG_PRINT_TO_FILE = False

# Register the "VERBOSE" name at import time so it's available regardless
# of whether the consumer calls enable_logging() — HA reads pyisyox via
# its own logging stack and never invokes ours.
logging.addLevelName(LOG_VERBOSE, "VERBOSE")


[docs] def enable_logging( level: int = LOG_LEVEL, add_null_handler: bool = False, log_no_color: bool = False, ) -> None: """Set up the logging.""" # Adapted from home-assistant/core/homeassistant/bootstrap.py if not log_no_color and not add_null_handler: try: # pylint: disable=import-outside-toplevel from colorlog import ColoredFormatter # basicConfig must be called after importing colorlog in order to # ensure that the handlers it sets up wraps the correct streams. logging.basicConfig(level=level) colorfmt = f"%(log_color)s{LOG_FORMAT}%(reset)s" logging.getLogger().handlers[0].setFormatter( ColoredFormatter( colorfmt, datefmt=LOG_DATE_FORMAT, reset=True, log_colors={ "VERBOSE": "blue", "DEBUG": "cyan", "INFO": "green", "WARNING": "yellow", "ERROR": "red", "CRITICAL": "red", }, ) ) except ImportError: pass # If the above initialization failed for any reason, setup the default # formatting. If the above succeeds, this will result in a no-op. logging.basicConfig(format=LOG_FORMAT, datefmt=LOG_DATE_FORMAT, level=level) if add_null_handler: _LOGGER.addHandler(logging.NullHandler()) # Suppress overly verbose logs from libraries that aren't helpful logging.getLogger("aiohttp.access").setLevel(logging.WARNING)