From e734b64355938c6542246afabe921dbc8578773e Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Tue, 27 Sep 2022 08:06:24 -0700 Subject: [PATCH 1/5] WARN -> WARNING --- octodns/cmds/args.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/octodns/cmds/args.py b/octodns/cmds/args.py index 170c852..9229d41 100644 --- a/octodns/cmds/args.py +++ b/octodns/cmds/args.py @@ -3,7 +3,7 @@ # from argparse import ArgumentParser as _Base -from logging import DEBUG, INFO, WARN, Formatter, StreamHandler, getLogger +from logging import DEBUG, INFO, WARNING, Formatter, StreamHandler, getLogger from logging.handlers import SysLogHandler from sys import stderr, stdout @@ -77,6 +77,6 @@ class ArgumentParser(_Base): logger.level = DEBUG if args.debug else default_log_level # boto is noisy, set it to warn - getLogger('botocore').level = WARN + getLogger('botocore').level = WARNING # DynectSession is noisy too - getLogger('DynectSession').level = WARN + getLogger('DynectSession').level = WARNING From 3967c273f88b13692413eeba23cf8aed4f686ba8 Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Tue, 27 Sep 2022 08:06:30 -0700 Subject: [PATCH 2/5] --debug flag to commands, work-around to ensure PlanLogger plan always prints --- octodns/cmds/args.py | 11 ++++++++++- octodns/provider/plan.py | 17 ++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/octodns/cmds/args.py b/octodns/cmds/args.py index 9229d41..9b804ae 100644 --- a/octodns/cmds/args.py +++ b/octodns/cmds/args.py @@ -50,6 +50,11 @@ class ArgumentParser(_Base): '--debug', action='store_true', default=False, help=_help ) + _help = 'Decrease verbosity to show only warnings, errors, and the plan' + self.add_argument( + '--quiet', action='store_true', default=False, help=_help + ) + args = super().parse_args() self._setup_logging(args, default_log_level) return args @@ -74,7 +79,11 @@ class ArgumentParser(_Base): handler.setFormatter(Formatter(fmt=fmt)) logger.addHandler(handler) - logger.level = DEBUG if args.debug else default_log_level + logger.level = default_log_level + if args.debug: + logger.level = DEBUG + elif args.quiet: + logger.level = WARNING # boto is noisy, set it to warn getLogger('botocore').level = WARNING diff --git a/octodns/provider/plan.py b/octodns/provider/plan.py index 5e38749..30c0ff6 100644 --- a/octodns/provider/plan.py +++ b/octodns/provider/plan.py @@ -134,6 +134,19 @@ class _PlanOutput(object): self.name = name +class _LogLevelSetter: + def __init__(self, logger, level): + self.logger = getLogger() + self.level = level + + def __enter__(self, *args, **kwargs): + self.original_level = self.logger.level + self.logger.setLevel(self.level) + + def __exit__(self, *args, **kwargs): + self.logger.setLevel(self.original_level) + + class PlanLogger(_PlanOutput): def __init__(self, name, level='info'): super().__init__(name) @@ -189,7 +202,9 @@ class PlanLogger(_PlanOutput): buf.write('No changes were planned\n') buf.write(hr) buf.write('\n') - log.log(self.level, buf.getvalue()) + + with _LogLevelSetter(log, INFO): + log.log(self.level, buf.getvalue()) def _value_stringifier(record, sep): From 7e3857fe1fc36ed3f9d69c3c1b41e8601e934a98 Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Thu, 29 Sep 2022 12:39:04 -0700 Subject: [PATCH 3/5] Pass plan_output a dedicated logger rather than use the Manager's --- octodns/manager.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/octodns/manager.py b/octodns/manager.py index 5677e6d..addcbe1 100644 --- a/octodns/manager.py +++ b/octodns/manager.py @@ -5,9 +5,9 @@ from collections import deque from concurrent.futures import ThreadPoolExecutor from importlib import import_module +from logging import getLogger from os import environ from sys import stdout -import logging from . import __VERSION__ from .idna import IdnaDict, idna_decode, idna_encode @@ -90,7 +90,8 @@ class ManagerException(Exception): class Manager(object): - log = logging.getLogger('Manager') + log = getLogger('Manager') + plan_log = getLogger('Plan') @classmethod def _plan_keyer(cls, p): @@ -629,7 +630,7 @@ class Manager(object): plans.sort(key=self._plan_keyer, reverse=True) for output in self.plan_outputs.values(): - output.run(plans=plans, log=self.log, fh=plan_output_fh) + output.run(plans=plans, log=self.plan_log, fh=plan_output_fh) if not force: self.log.debug('sync: checking safety') From a1e54c2bbf8500bf38f8b82ea8978f551c9ba7d4 Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Thu, 29 Sep 2022 14:27:05 -0700 Subject: [PATCH 4/5] Remove hacky _LogLevelSetter and just setLevel on Plan logger --- octodns/cmds/args.py | 4 ++++ octodns/provider/plan.py | 16 +--------------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/octodns/cmds/args.py b/octodns/cmds/args.py index 9b804ae..865a8a1 100644 --- a/octodns/cmds/args.py +++ b/octodns/cmds/args.py @@ -84,7 +84,11 @@ class ArgumentParser(_Base): logger.level = DEBUG elif args.quiet: logger.level = WARNING + # we still want plans to come out during quite so set the plan + # logger output to info in case the PlanLogger is being used + getLogger('Plan').setLevel(INFO) + # TODO: these should move out of octoDNS core... # boto is noisy, set it to warn getLogger('botocore').level = WARNING # DynectSession is noisy too diff --git a/octodns/provider/plan.py b/octodns/provider/plan.py index 30c0ff6..bc9723d 100644 --- a/octodns/provider/plan.py +++ b/octodns/provider/plan.py @@ -134,19 +134,6 @@ class _PlanOutput(object): self.name = name -class _LogLevelSetter: - def __init__(self, logger, level): - self.logger = getLogger() - self.level = level - - def __enter__(self, *args, **kwargs): - self.original_level = self.logger.level - self.logger.setLevel(self.level) - - def __exit__(self, *args, **kwargs): - self.logger.setLevel(self.original_level) - - class PlanLogger(_PlanOutput): def __init__(self, name, level='info'): super().__init__(name) @@ -203,8 +190,7 @@ class PlanLogger(_PlanOutput): buf.write(hr) buf.write('\n') - with _LogLevelSetter(log, INFO): - log.log(self.level, buf.getvalue()) + log.log(self.level, buf.getvalue()) def _value_stringifier(record, sep): From cadeada955cb17d7776d0f3f5002ccb03c1a34bd Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Thu, 29 Sep 2022 14:29:32 -0700 Subject: [PATCH 5/5] Add --logging-config command line option --- octodns/cmds/args.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/octodns/cmds/args.py b/octodns/cmds/args.py index 865a8a1..f0f0e89 100644 --- a/octodns/cmds/args.py +++ b/octodns/cmds/args.py @@ -4,8 +4,10 @@ from argparse import ArgumentParser as _Base from logging import DEBUG, INFO, WARNING, Formatter, StreamHandler, getLogger +from logging.config import dictConfig from logging.handlers import SysLogHandler from sys import stderr, stdout +from yaml import safe_load from octodns import __VERSION__ @@ -55,11 +57,22 @@ class ArgumentParser(_Base): '--quiet', action='store_true', default=False, help=_help ) + _help = 'Configure logging with a YAML file, see https://docs.python.org/3/library/logging.config.html#logging-config-dictschema for schema details' + self.add_argument('--logging-config', default=False, help=_help) + args = super().parse_args() self._setup_logging(args, default_log_level) return args def _setup_logging(self, args, default_log_level): + if args.logging_config: + with open(args.logging_config) as fh: + config = safe_load(fh.read()) + dictConfig(config) + # if we're provided a logging_config we won't do any of our normal + # configuration + return + fmt = '%(asctime)s [%(thread)d] %(levelname)-5s %(name)s %(message)s' formatter = Formatter(fmt=fmt, datefmt='%Y-%m-%dT%H:%M:%S ') stream = stdout if args.log_stream_stdout else stderr