2 # Copyright (c) 2011 Nicira Networks
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
18 import logging.handlers
25 FACILITIES = {"console": "info", "file": "info", "syslog": "info"}
29 "warn": logging.WARNING,
31 "emer": logging.CRITICAL,
32 "off": logging.CRITICAL
36 def get_level(level_str):
37 return LEVELS.get(level_str.lower())
43 __mfl = {} # Module -> facility -> level
45 def __init__(self, name):
46 """Creates a new Vlog object representing a module called 'name'. The
47 created Vlog object will do nothing until the Vlog.init() static method
48 is called. Once called, no more Vlog objects may be created."""
50 assert not Vlog.__inited
51 self.name = name.lower()
52 if name not in Vlog.__mfl:
53 Vlog.__mfl[self.name] = FACILITIES.copy()
55 def __log(self, level, message, **kwargs):
59 now = datetime.datetime.now().strftime("%b %d %H:%M:%S")
60 message = ("%s|%s|%s|%s|%s"
61 % (now, Vlog.__msg_num, self.name, level, message))
63 level = LEVELS.get(level.lower(), logging.DEBUG)
66 for f, f_level in Vlog.__mfl[self.name].iteritems():
67 f_level = LEVELS.get(f_level, logging.CRITICAL)
69 logging.getLogger(f).log(level, message, **kwargs)
71 def emer(self, message, **kwargs):
72 self.__log("EMER", message, **kwargs)
74 def err(self, message, **kwargs):
75 self.__log("ERR", message, **kwargs)
77 def warn(self, message, **kwargs):
78 self.__log("WARN", message, **kwargs)
80 def info(self, message, **kwargs):
81 self.__log("INFO", message, **kwargs)
83 def dbg(self, message, **kwargs):
84 self.__log("DBG", message, **kwargs)
86 def exception(self, message):
87 """Logs 'message' at ERR log level. Includes a backtrace when in
89 self.err(message, exc_info=True)
92 def init(log_file=None):
93 """Intializes the Vlog module. Causes Vlog to write to 'log_file' if
94 not None. Should be called after all Vlog objects have been created.
95 No logging will occur until this function is called."""
101 logging.raiseExceptions = False
103 logger = logging.getLogger(f)
104 logger.setLevel(logging.DEBUG)
108 logger.addHandler(logging.StreamHandler(sys.stderr))
110 logger.addHandler(logging.handlers.SysLogHandler(
112 facility=logging.handlers.SysLogHandler.LOG_DAEMON))
113 elif f == "file" and log_file:
114 logger.addHandler(logging.FileHandler(log_file))
115 except (IOError, socket.error):
116 logger.setLevel(logging.CRITICAL)
119 def set_level(module, facility, level):
120 """ Sets the log level of the 'module'-'facility' tuple to 'level'.
121 All three arguments are strings which are interpreted the same as
122 arguments to the --verbose flag. Should be called after all Vlog
123 objects have already been created."""
125 module = module.lower()
126 facility = facility.lower()
127 level = level.lower()
129 if facility != "any" and facility not in FACILITIES:
132 if module != "any" and module not in Vlog.__mfl:
135 if level not in LEVELS:
139 modules = Vlog.__mfl.keys()
143 if facility == "any":
144 facilities = FACILITIES.keys()
146 facilities = [facility]
150 Vlog.__mfl[m][f] = level
153 def add_args(parser):
154 """Adds vlog related options to 'parser', an ArgumentParser object. The
155 resulting arguments parsed by 'parser' should be passed to handle_args."""
157 group = parser.add_argument_group(title="Logging Options")
158 group.add_argument("--log-file", nargs="?", const="default",
159 help="Enables logging to a file. Default log file"
160 " is used if LOG_FILE is omitted.")
161 group.add_argument("-v", "--verbose", nargs="*",
162 help="Sets logging levels, see ovs-vswitchd(8)."
163 " Defaults to ANY:ANY:dbg.")
166 def handle_args(args):
167 """ Handles command line arguments ('args') parsed by an ArgumentParser.
168 The ArgumentParser should have been primed by add_args(). Also takes care
169 of initializing the Vlog module."""
171 log_file = args.log_file
172 if log_file == "default":
173 log_file = "%s/%s.log" % (ovs.dirs.LOGDIR, ovs.util.PROGRAM_NAME)
175 if args.verbose is None:
177 elif args.verbose == []:
178 args.verbose = ["any:any:dbg"]
180 for verbose in args.verbose:
181 args = verbose.split(':')
198 Vlog.set_level(module, facility, level)