aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2014-05-30 17:08:31 +0000
committerRob Austein <sra@hactrn.net>2014-05-30 17:08:31 +0000
commit3519e8117e959ec35fa701986215d5fb18e553f1 (patch)
tree6defac145f43d1fe1a6ab90bdef36d25a66b6d09
parent6cacde4474719bae1a1e6ba0876b9d3327054ae9 (diff)
Move all the complexity of configuring the ten zillion kinds of
logging handlers up front to the argparse stage, thereby also giving the application more control over the default logging configuration. svn path=/trunk/; revision=5851
-rw-r--r--ca/tests/smoketest.py3
-rw-r--r--ca/tests/yamlconf.py3
-rw-r--r--ca/tests/yamltest.py3
-rw-r--r--rpki/log.py119
4 files changed, 72 insertions, 56 deletions
diff --git a/ca/tests/smoketest.py b/ca/tests/smoketest.py
index 64fd6173..04b43f07 100644
--- a/ca/tests/smoketest.py
+++ b/ca/tests/smoketest.py
@@ -159,7 +159,8 @@ def main():
Main program.
"""
- rpki.log.init(smoketest_name, argparse.Namespace(log_level = logging.DEBUG, log_stream = sys.stdout))
+ rpki.log.init(smoketest_name, argparse.Namespace(log_level = logging.DEBUG,
+ log_handler = lambda: logging.StreamHandler(sys.stdout)))
logger.info("Starting")
pubd_process = None
diff --git a/ca/tests/yamlconf.py b/ca/tests/yamlconf.py
index 5025ef61..e9b6e391 100644
--- a/ca/tests/yamlconf.py
+++ b/ca/tests/yamlconf.py
@@ -673,7 +673,8 @@ def main():
quiet = args.quiet
yaml_file = args.yaml_file
- rpki.log.init("yamlconf", argparse.Namespace(log_level = logging.DEBUG, log_stream = sys.stdout))
+ rpki.log.init("yamlconf", argparse.Namespace(log_level = logging.DEBUG,
+ log_handler = lambda: logging.StreamHandler(sys.stdout)))
# Allow optional config file for this tool to override default
# passwords: this is mostly so that I can show a complete working
diff --git a/ca/tests/yamltest.py b/ca/tests/yamltest.py
index 5d6686b4..59d58cd9 100644
--- a/ca/tests/yamltest.py
+++ b/ca/tests/yamltest.py
@@ -666,7 +666,8 @@ try:
if args.pidfile is not None:
open(args.pidfile, "w").write("%s\n" % os.getpid())
- rpki.log.init("yamltest", argparse.Namespace(log_level = logging.DEBUG, log_stream = sys.stdout))
+ rpki.log.init("yamltest", argparse.Namespace(log_level = logging.DEBUG,
+ log_handler = lambda: logging.StreamHandler(sys.stdout)))
# Allow optional config file for this tool to override default
# passwords: this is mostly so that I can show a complete working
diff --git a/rpki/log.py b/rpki/log.py
index 9d837858..53cd0df7 100644
--- a/rpki/log.py
+++ b/rpki/log.py
@@ -110,87 +110,100 @@ class Formatter(object):
for line in lines:
yield line
-def argparse_setup(parser):
+
+def argparse_setup(parser, default_thunk = None):
"""
Set up argparse stuff for functionality in this module.
- Default logging destination is syslog, but also see rpki.log.init().
+ Default logging destination is syslog, but you can change this
+ by setting default_thunk to a callable which takes no arguments
+ and which returns a instance of a logging.Handler subclass.
+
+ Also see rpki.log.init().
"""
- class LogLevel(argparse.Action):
+ class LogLevelAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string = None):
setattr(namespace, self.dest, getattr(logging, values.upper()))
- class RotatingFile(argparse.Action):
- def __call__(self, parser, namespace, values, option_string = None):
- setattr(namespace, self.dest, values[0])
- setattr(namespace, self.dest + "_maxBytes", int(values[1]) * 1024)
- setattr(namespace, self.dest + "_backupCount", int(values[2]))
-
- class TimedRotatingFile(argparse.Action):
- def __call__(self, parser, namespace, values, option_string = None):
- setattr(namespace, self.dest, values[0])
- setattr(namespace, self.dest + "_interval", int(values[1]))
- setattr(namespace, self.dest + "_backupCount", int(values[2]))
-
- parser.add_argument("--log-level", default = logging.WARNING, action = LogLevel,
+ parser.add_argument("--log-level", default = logging.WARNING, action = LogLevelAction,
choices = ("debug", "info", "warning", "error", "critical"),
help = "how verbosely to log")
+
group = parser.add_mutually_exclusive_group()
- group.add_argument("--log-syslog", nargs = "?", default = "daemon",
+
+ syslog_address = "/dev/log" if os.path.exists("/dev/log") else ("localhost", logging.handlers.SYSLOG_UDP_PORT)
+
+ class SyslogAction(argparse.Action):
+ def __call__(self, parser, namespace, values, option_string = None):
+ namespace.log_handler = lambda: logging.handlers.SysLogHandler(address = syslog_address, facility = values)
+
+ group.add_argument("--log-syslog", nargs = "?", const = "daemon", action = SyslogAction,
choices = sorted(logging.handlers.SysLogHandler.facility_names.keys()),
help = "send logging to syslog")
- group.add_argument("--log-stderr", dest = "log_stream", action = "store_const", const = sys.stderr,
+
+ class StreamAction(argparse.Action):
+ def __call__(self, parser, namespace, values, option_string = None):
+ namespace.log_handler = lambda: logging.StreamHandler(stream = self.const)
+
+ group.add_argument("--log-stderr", nargs = 0, action = StreamAction, const = sys.stderr,
help = "send logging to standard error")
- group.add_argument("--log-stdout", dest = "log_stream", action = "store_const", const = sys.stdout,
+
+ group.add_argument("--log-stdout", nargs = 0, action = StreamAction, const = sys.stdout,
help = "send logging to standard output")
- group.add_argument("--log-file",
- help = "send logging to a plain old file")
- group.add_argument("--log-rotating-file", action = RotatingFile,
+
+ class WatchedFileAction(argparse.Action):
+ def __call__(self, parser, namespace, values, option_string = None):
+ namespace.log_handler = lambda: logging.handlers.WatchedFileHandler(filename = values)
+
+ group.add_argument("--log-file", action = WatchedFileAction,
+ help = "send logging to a file, reopening if newsyslog rotates it away")
+
+ class RotatingFileAction(argparse.Action):
+ def __call__(self, parser, namespace, values, option_string = None):
+ namespace.log_handler = lambda: logging.handlers.RotatingFileHandler(
+ filename = values[0],
+ maxBytes = int(values[1]) * 1024,
+ backupCount = int(values[2]))
+
+ group.add_argument("--log-rotating-file", action = RotatingFileAction,
nargs = 3, metavar = ("FILENAME", "KBYTES", "COUNT"),
help = "send logging to rotating file")
- group.add_argument("--log-timed-rotating-file", action = TimedRotatingFile,
+
+ class TimedRotatingFileAction(argparse.Action):
+ def __call__(self, parser, namespace, values, option_string = None):
+ namespace.log_handler = logging.handlers.RotatingFileHandler(
+ filename = values[0],
+ interval = int(values[1]),
+ backupCount = int(values[2]),
+ when = "H",
+ utc = True)
+
+ group.add_argument("--log-timed-rotating-file", action = TimedRotatingFileAction,
nargs = 3, metavar = ("FILENAME", "HOURS", "COUNT"),
help = "send logging to timed rotating file")
+ if default_thunk is None:
+ default_thunk = lambda: logging.handlers.SysLogHandler(address = syslog_address, facility = "daemon")
+
+ parser.set_defaults(log_handler = default_thunk)
-def init(ident = "rpki", args = argparse.Namespace(log_level = logging.WARNING, log_stream = sys.stderr)):
+
+def init(ident = None, args = None):
"""
Initialize logging system.
- Default logging destination is syslog if "args" is specified, stderr otherwise.
+ Default logging destination is stderr if "args" is not specified.
"""
- assert isinstance(args, argparse.Namespace)
-
- # pylint: disable=E1103
-
- if args.log_stream:
- handler = logging.StreamHandler(stream = args.log_stream)
-
- elif args.log_file:
- handler = logging.FileHandler(filename = args.log_file)
-
- elif args.log_rotating_file:
- handler = logging.handlers.RotatingFileHandler(
- filename = args.log_rotating_file,
- maxBytes = args.log_rotating_file_maxBytes,
- backupCount = args.log_rotating_file_backupCount)
-
- elif args.log_timed_rotating_file:
- handler = logging.handlers.TimedRotatingFileHandler(
- filename = args.log_timed_rotating_file,
- interval = args.log_timed_rotating_file_interval,
- backupCount = args.log_timed_rotating_file_backupCount)
-
- elif args.log_syslog:
- handler = logging.handlers.SysLogHandler(
- address = "/dev/log" if os.path.exists("/dev/log") else ("localhost", logging.handlers.SYSLOG_UDP_PORT),
- facility = args.log_syslog)
+ if ident is None:
+ ident = os.path.basename(sys.argv[0])
- else:
- raise ValueError
+ if args is None:
+ args = argparse.Namespace(log_level = logging.WARNING,
+ log_handler = logging.StreamHandler)
+ handler = args.log_handler()
handler.setFormatter(Formatter(ident, handler))
root_logger = logging.getLogger()