spacr.logging_util
==================

.. py:module:: spacr.logging_util

.. autoapi-nested-parse::

   Package-scope Python `logging` setup for spacr.

   Central configuration for every spacr subsystem — core pipelines,
   I/O, measure, utilities, and the Qt GUI all funnel through the same
   rotating file handler at ``~/.spacr/logs/spacr.log``.

   Two ways to opt in:

   - Automatic — the Qt GUI calls :func:`setup_logging` at launch, so
     once you run ``spacr-qt`` the log file is populated for the life
     of the session.
   - Manual — for headless scripts and notebooks:

     .. code-block:: python

        from spacr.logging_util import setup_logging, get_logger
        setup_logging()                # once, at program start
        LOG = get_logger(__name__)     # in every module that logs
        LOG.info("started")

   The log level can be overridden by ``SPACR_LOG_LEVEL`` in the env
   (``DEBUG``, ``INFO``, ``WARNING``, …). :func:`enable_debug` and
   :func:`disable_debug` are convenience toggles for interactive use.

   Third-party libraries that spam INFO records during a spacr pipeline
   (torch, cellpose, matplotlib, PIL, urllib3, botocore, tensorflow,
   asyncio) are pinned to WARNING so the log stays useful. Add more to
   :data:`QUIET_LOGGERS` if a new dependency starts spamming.

   Public API:
       setup_logging(level=INFO, log_file=None) — call once early.
       get_logger(name)                          — module-scoped logger.
       enable_debug()                             — crank spacr.* to DEBUG.
       disable_debug()                            — revert to session level.
       log_dir()                                  — folder holding the log.
       log_path()                                 — absolute log file path.







Module Contents
---------------

.. py:data:: DEFAULT_LOG_FILENAME
   :value: 'spacr.log'


.. py:data:: MAX_BYTES
   :value: 5242880


.. py:data:: BACKUP_COUNT
   :value: 3


.. py:data:: FILE_FORMAT
   :value: '%(asctime)s [%(levelname)s] %(name)s:%(filename)s:%(lineno)d — %(message)s'


.. py:data:: STREAM_FORMAT
   :value: '%(levelname)s %(name)s: %(message)s'


.. py:data:: QUIET_LOGGERS
   :type:  tuple[str, Ellipsis]
   :value: ('PIL', 'matplotlib', 'urllib3', 'asyncio', 'torch', 'torchvision', 'cellpose', 'tensorflow',...


.. py:function:: log_dir() -> pathlib.Path

   Return the folder where spacr log files live.

   :returns: ``~/.spacr/logs`` — created if it does not exist.


.. py:function:: log_path() -> pathlib.Path

   Return the absolute path of the rotating log file.

   Uses whatever was passed to :func:`setup_logging` last, or the
   default under :func:`log_dir` when never set.


.. py:function:: setup_logging(level: Optional[int] = None, log_file: Optional[pathlib.Path] = None, stream: bool = False, quiet: Iterable[str] = QUIET_LOGGERS) -> pathlib.Path

   Install the rotating file handler on the root logger.

   Idempotent — subsequent calls only re-apply the level, they don't
   stack additional handlers. Honours the ``SPACR_LOG_LEVEL``
   environment variable when ``level`` is not given.

   :param level: minimum record level for the log file. Defaults to
       ``SPACR_LOG_LEVEL`` env var (any of ``DEBUG``/``INFO``/…) or
       :data:`logging.INFO`.
   :param log_file: override for where the file lands. Defaults to
       :func:`log_path`.
   :param stream: also attach a StreamHandler to stderr — handy for
       headless / CI runs where the log file isn't inspected.
   :param quiet: iterable of logger names to pin at WARNING. Defaults
       to :data:`QUIET_LOGGERS`.
   :returns: the resolved log-file path.


.. py:function:: get_logger(name: str) -> logging.Logger

   Return a spacr-scoped :class:`logging.Logger`.

   Idiomatic usage from any module:

   .. code-block:: python

      from spacr.logging_util import get_logger
      LOG = get_logger(__name__)

   :param name: logger name — typically ``__name__`` so the log
       stream shows which module the record came from.


.. py:function:: enable_debug() -> None

   Crank every ``spacr.*`` logger to DEBUG.

   Useful when debugging interactively:

   .. code-block:: pycon

      >>> from spacr.logging_util import enable_debug
      >>> enable_debug()

   Third-party loggers listed in :data:`QUIET_LOGGERS` are left at
   WARNING to keep the log readable.


.. py:function:: disable_debug() -> None

   Revert every ``spacr.*`` logger to the level chosen at setup.

   Inverse of :func:`enable_debug`.


