logging: add opt-in quiet_vips_logging() helper

pyvips redirects all GLib messages ("VIPS: threadpool completed ..."
per operation) onto the 'pyvips' logger at INFO. The helper caps that
logger at WARNING while keeping 'pyvips.voperation' (deprecated-argument
notices) at INFO. Library import remains free of logging side effects;
the CLI and worker entry points call the helper instead of their old
bare setLevel, which also hid the deprecation notices.
This commit is contained in:
2026-09-18 03:42:36 +00:00
parent c15e964e6d
commit 720c4f06e5
3 changed files with 19 additions and 6 deletions
+2 -3
View File
@@ -32,15 +32,14 @@ from docopt import docopt
from mediapreview.backends import dispatch from mediapreview.backends import dispatch
from mediapreview.exceptions import PreviewError from mediapreview.exceptions import PreviewError
from mediapreview.util.logformat import EmojiFormatter from mediapreview.util.logformat import EmojiFormatter, quiet_vips_logging
def _configure_logging() -> None: def _configure_logging() -> None:
handler = logging.StreamHandler(sys.stderr) handler = logging.StreamHandler(sys.stderr)
handler.setFormatter(EmojiFormatter()) handler.setFormatter(EmojiFormatter())
logging.basicConfig(level=logging.INFO, handlers=[handler]) logging.basicConfig(level=logging.INFO, handlers=[handler])
# pyvips is chatty at INFO ("threadpool completed ..." per operation). quiet_vips_logging()
logging.getLogger("pyvips").setLevel(logging.WARNING)
def _oosetup(name: str) -> None: def _oosetup(name: str) -> None:
+15
View File
@@ -31,3 +31,18 @@ class EmojiFormatter(logging.Formatter):
def format(self, record: logging.LogRecord) -> str: def format(self, record: logging.LogRecord) -> str:
return format_level_prefix(record.levelno) + record.getMessage() return format_level_prefix(record.levelno) + record.getMessage()
def quiet_vips_logging() -> None:
"""Silence libvips per-operation chatter without hiding deprecations.
pyvips redirects every GLib message ("VIPS: threadpool completed ...")
onto the ``pyvips`` logger at INFO; cap that logger at WARNING. pyvips's
own diagnostics (e.g. deprecated-argument notices) are logged on the
``pyvips.voperation`` child logger and stay at the default INFO.
Opt-in: applications that want quiet vips output call this once during
their own logging setup. mediapreview never calls it on import.
"""
logging.getLogger("pyvips").setLevel(logging.WARNING)
logging.getLogger("pyvips.voperation").setLevel(logging.INFO)
+2 -3
View File
@@ -40,7 +40,7 @@ except ImportError: # pragma: no cover - optional worker extra
from mediapreview.backends import dispatch from mediapreview.backends import dispatch
from mediapreview.exceptions import PreviewError from mediapreview.exceptions import PreviewError
from mediapreview.protocol import PreviewRequest, PreviewResponse from mediapreview.protocol import PreviewRequest, PreviewResponse
from mediapreview.util.logformat import format_level_prefix from mediapreview.util.logformat import format_level_prefix, quiet_vips_logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -171,8 +171,7 @@ def main() -> None:
handler = logging.StreamHandler(sys.stderr) handler = logging.StreamHandler(sys.stderr)
handler.setFormatter(_WorkerLogFormatter()) handler.setFormatter(_WorkerLogFormatter())
logging.basicConfig(level=logging.INFO, handlers=[handler]) logging.basicConfig(level=logging.INFO, handlers=[handler])
# pyvips is chatty at INFO ("threadpool completed ..." per operation). quiet_vips_logging()
logging.getLogger("pyvips").setLevel(logging.WARNING)
# NOTE: standalone package no longer depends on cista config loading. # NOTE: standalone package no longer depends on cista config loading.
# Consumers can load their own configuration before starting workers. # Consumers can load their own configuration before starting workers.
if len(sys.argv) > 1: if len(sys.argv) > 1: