add 'hooks' option

Very much a work in progress.

At the moment, it allows to
- wait and restart an extractor (#3338)
- change the exit code (#3630)
- change the log level of a logging message
based on the contents of a logging message
This commit is contained in:
Mike Fährmann
2023-02-13 13:33:42 +01:00
parent 8fb043e8ff
commit d37e7f4898
2 changed files with 54 additions and 3 deletions

View File

@@ -6,6 +6,7 @@
# it under the terms of the GNU General Public License version 2 as # it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation. # published by the Free Software Foundation.
import re
import sys import sys
import errno import errno
import logging import logging
@@ -32,6 +33,16 @@ class Job():
self.kwdict = {} self.kwdict = {}
self.status = 0 self.status = 0
hooks = extr.config("hooks")
if hooks:
if isinstance(hooks, dict):
hooks = hooks.items()
self._wrap_logger = self._wrap_logger_hooks
self._logger_hooks = [
(re.compile(pattern).search, hook)
for pattern, hook in hooks
]
path_proxy = output.PathfmtProxy(self) path_proxy = output.PathfmtProxy(self)
self._logger_extra = { self._logger_extra = {
"job" : self, "job" : self,
@@ -202,6 +213,10 @@ class Job():
def _wrap_logger(self, logger): def _wrap_logger(self, logger):
return output.LoggerAdapter(logger, self._logger_extra) return output.LoggerAdapter(logger, self._logger_extra)
def _wrap_logger_hooks(self, logger):
return output.LoggerAdapterEx(
logger, self._logger_extra, self)
def _write_unsupported(self, url): def _write_unsupported(self, url):
if self.ulog: if self.ulog:
self.ulog.info(url) self.ulog.info(url)

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2015-2022 Mike Fährmann # Copyright 2015-2023 Mike Fährmann
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as # it under the terms of the GNU General Public License version 2 as
@@ -10,8 +10,9 @@ import os
import sys import sys
import shutil import shutil
import logging import logging
import functools
import unicodedata import unicodedata
from . import config, util, formatter from . import config, util, formatter, exception
# -------------------------------------------------------------------- # --------------------------------------------------------------------
@@ -23,7 +24,7 @@ LOG_LEVEL = logging.INFO
class Logger(logging.Logger): class Logger(logging.Logger):
"""Custom logger that includes extra info in log records""" """Custom Logger that includes extra info in log records"""
def makeRecord(self, name, level, fn, lno, msg, args, exc_info, def makeRecord(self, name, level, fn, lno, msg, args, exc_info,
func=None, extra=None, sinfo=None, func=None, extra=None, sinfo=None,
@@ -63,6 +64,41 @@ class LoggerAdapter():
self.logger._log(logging.ERROR, msg, args, **kwargs) self.logger._log(logging.ERROR, msg, args, **kwargs)
class LoggerAdapterEx():
def __init__(self, logger, extra, job):
self.logger = logger
self.extra = extra
self.job = job
self.debug = functools.partial(self.log, logging.DEBUG)
self.info = functools.partial(self.log, logging.INFO)
self.warning = functools.partial(self.log, logging.WARNING)
self.error = functools.partial(self.log, logging.ERROR)
def log(self, level, msg, *args, **kwargs):
if args:
msg = msg % args
args = None
for search, action in self.job._logger_hooks:
match = search(msg)
if match:
if action == "wait+restart":
kwargs["extra"] = self.extra
self.logger._log(level, msg, args, **kwargs)
input("Press Enter to continue")
raise exception.RestartExtraction()
elif action.startswith("~"):
level = logging._nameToLevel[action[1:]]
elif action.startswith("|"):
self.job.status |= int(action[1:])
if self.logger.isEnabledFor(level):
kwargs["extra"] = self.extra
self.logger._log(level, msg, args, **kwargs)
class PathfmtProxy(): class PathfmtProxy():
__slots__ = ("job",) __slots__ = ("job",)