diff --git a/docs/configuration.rst b/docs/configuration.rst index 2e454134..4db8281f 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -1518,7 +1518,7 @@ Logging Configuration =========== ===== Type ``object`` -Example .. code:: +Examples .. code:: { "format": "{asctime} {name}: {message}", @@ -1527,10 +1527,21 @@ Example .. code:: "encoding": "ascii" } + { + "level": "debug", + "format": { + "debug" : "debug: {message}", + "info" : "[{name}] {message}", + "warning": "Warning: {message}", + "error" : "ERROR: {message}" + } + } + Description Extended logging output configuration. * format - * Format string for logging messages + * General format string for logging messages + or a dictionary with format strings for each loglevel. In addition to the default `LogRecord attributes `__, diff --git a/docs/gallery-dl-example.conf b/docs/gallery-dl-example.conf index a5270d21..04be5e6c 100644 --- a/docs/gallery-dl-example.conf +++ b/docs/gallery-dl-example.conf @@ -148,8 +148,13 @@ { "mode": "terminal", "log": { - "format": "{name}: {message}", - "level": "info" + "level": "info", + "format": { + "debug" : "\u001b[0;37m{name}: {message}\u001b[0m", + "info" : "\u001b[1;37m{name}: {message}\u001b[0m", + "warning": "\u001b[1;33m{name}: {message}\u001b[0m", + "error" : "\u001b[1;31m{name}: {message}\u001b[0m" + } }, "logfile": { "path": "~/gallery-dl/log.txt", diff --git a/docs/gallery-dl.conf b/docs/gallery-dl.conf index 754f5f5a..d956f961 100644 --- a/docs/gallery-dl.conf +++ b/docs/gallery-dl.conf @@ -175,6 +175,7 @@ "mode": "auto", "progress": true, "shorten": true, + "log": "[{name}][{levelname}] {message}", "logfile": null, "unsupportedfile": null }, diff --git a/gallery_dl/output.py b/gallery_dl/output.py index 327b69a0..87c50069 100644 --- a/gallery_dl/output.py +++ b/gallery_dl/output.py @@ -35,6 +35,30 @@ class Logger(logging.Logger): return rv +class Formatter(logging.Formatter): + """Custom formatter that supports different formats per loglevel""" + + def __init__(self, fmt, datefmt): + if not isinstance(fmt, dict): + fmt = {"debug": fmt, "info": fmt, "warning": fmt, "error": fmt} + self.formats = fmt + self.datefmt = datefmt + + def format(self, record): + record.message = record.getMessage() + fmt = self.formats[record.levelname] + if "{asctime" in fmt: + record.asctime = self.formatTime(record, self.datefmt) + msg = fmt.format_map(record.__dict__) + if record.exc_info and not record.exc_text: + record.exc_text = self.formatException(record.exc_info) + if record.exc_text: + msg = msg + "\n" + record.exc_text + if record.stack_info: + msg = msg + "\n" + record.stack_info + return msg + + def initialize_logging(loglevel): """Setup basic logging functionality before configfiles have been loaded""" # convert levelnames to lowercase @@ -46,7 +70,7 @@ def initialize_logging(loglevel): logging.Logger.manager.setLoggerClass(Logger) # setup basic logging to stderr - formatter = logging.Formatter(LOG_FORMAT, LOG_FORMAT_DATE, "{") + formatter = Formatter(LOG_FORMAT, LOG_FORMAT_DATE) handler = logging.StreamHandler() handler.setFormatter(formatter) handler.setLevel(loglevel) @@ -80,13 +104,11 @@ def setup_logging_handler(key, fmt=LOG_FORMAT, lvl=LOG_LEVEL): "%s: missing or invalid path (%s)", key, exc) return None - level = opts.get("level", lvl) - logfmt = opts.get("format", fmt) - datefmt = opts.get("format-date", LOG_FORMAT_DATE) - formatter = logging.Formatter(logfmt, datefmt, "{") - handler.setFormatter(formatter) - handler.setLevel(level) - + handler.setLevel(opts.get("level", lvl)) + handler.setFormatter(Formatter( + opts.get("format", fmt), + opts.get("format-date", LOG_FORMAT_DATE), + )) return handler @@ -100,10 +122,10 @@ def configure_logging_handler(key, handler): if handler.level == LOG_LEVEL and "level" in opts: handler.setLevel(opts["level"]) if "format" in opts or "format-date" in opts: - logfmt = opts.get("format", LOG_FORMAT) - datefmt = opts.get("format-date", LOG_FORMAT_DATE) - formatter = logging.Formatter(logfmt, datefmt, "{") - handler.setFormatter(formatter) + handler.setFormatter(Formatter( + opts.get("format", LOG_FORMAT), + opts.get("format-date", LOG_FORMAT_DATE), + )) # --------------------------------------------------------------------