]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/lib/topolog.py
Merge pull request #7199 from donaldsharp/nhg_reasons
[mirror_frr.git] / tests / topotests / lib / topolog.py
1 #
2 # topolog.py
3 # Library of helper functions for NetDEF Topology Tests
4 #
5 # Copyright (c) 2017 by
6 # Network Device Education Foundation, Inc. ("NetDEF")
7 #
8 # Permission to use, copy, modify, and/or distribute this software
9 # for any purpose with or without fee is hereby granted, provided
10 # that the above copyright notice and this permission notice appear
11 # in all copies.
12 #
13 # THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
14 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
16 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
17 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
19 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20 # OF THIS SOFTWARE.
21 #
22
23 """
24 Logging utilities for topology tests.
25
26 This file defines our logging abstraction.
27 """
28
29 import sys
30 import logging
31
32 # Helper dictionary to convert Topogen logging levels to Python's logging.
33 DEBUG_TOPO2LOGGING = {
34 "debug": logging.DEBUG,
35 "info": logging.INFO,
36 "output": logging.INFO,
37 "warning": logging.WARNING,
38 "error": logging.ERROR,
39 "critical": logging.CRITICAL,
40 }
41
42
43 class InfoFilter(logging.Filter):
44 def filter(self, rec):
45 return rec.levelno in (logging.DEBUG, logging.INFO)
46
47
48 #
49 # Logger class definition
50 #
51
52
53 class Logger(object):
54 """
55 Logger class that encapsulates logging functions, internaly it uses Python
56 logging module with a separated instance instead of global.
57
58 Default logging level is 'info'.
59 """
60
61 def __init__(self):
62 # Create default global logger
63 self.log_level = logging.INFO
64 self.logger = logging.Logger("topolog", level=self.log_level)
65
66 handler_stdout = logging.StreamHandler(sys.stdout)
67 handler_stdout.setLevel(logging.DEBUG)
68 handler_stdout.addFilter(InfoFilter())
69 handler_stdout.setFormatter(
70 logging.Formatter(fmt="%(asctime)s %(levelname)s: %(message)s")
71 )
72 handler_stderr = logging.StreamHandler()
73 handler_stderr.setLevel(logging.WARNING)
74 handler_stderr.setFormatter(
75 logging.Formatter(fmt="%(asctime)s %(levelname)s: %(message)s")
76 )
77
78 self.logger.addHandler(handler_stdout)
79 self.logger.addHandler(handler_stderr)
80
81 # Handle more loggers
82 self.loggers = {"topolog": self.logger}
83
84 def set_log_level(self, level):
85 "Set the logging level"
86 self.log_level = DEBUG_TOPO2LOGGING.get(level)
87 self.logger.setLevel(self.log_level)
88
89 def get_logger(self, name="topolog", log_level=None, target=sys.stdout):
90 """
91 Get a new logger entry. Allows creating different loggers for formating,
92 filtering or handling (file, stream or stdout/stderr).
93 """
94 if log_level is None:
95 log_level = self.log_level
96 if name in self.loggers:
97 return self.loggers[name]
98
99 nlogger = logging.Logger(name, level=log_level)
100 if isinstance(target, str):
101 handler = logging.FileHandler(filename=target)
102 else:
103 handler = logging.StreamHandler(stream=target)
104
105 handler.setFormatter(
106 logging.Formatter(fmt="%(asctime)s %(levelname)s: %(message)s")
107 )
108 nlogger.addHandler(handler)
109 self.loggers[name] = nlogger
110 return nlogger
111
112
113 #
114 # Global variables
115 #
116
117 logger_config = Logger()
118 logger = logger_config.logger