import datetime
import logging
import logging.handlers
+import re
import socket
import sys
ovs.unixctl.command_register("vlog/reopen", "", 0, 0,
Vlog._unixctl_vlog_reopen, None)
+ ovs.unixctl.command_register("vlog/set", "spec", 1, sys.maxint,
+ Vlog._unixctl_vlog_set, None)
+ ovs.unixctl.command_register("vlog/list", "", 0, 0,
+ Vlog._unixctl_vlog_list, None)
@staticmethod
def set_level(module, facility, level):
for f in facilities:
Vlog.__mfl[m][f] = level
+ @staticmethod
+ def set_levels_from_string(s):
+ module = None
+ level = None
+ facility = None
+
+ for word in [w.lower() for w in re.split('[ :]', s)]:
+ if word == "any":
+ pass
+ elif word in FACILITIES:
+ if facility:
+ return "cannot specify multiple facilities"
+ facility = word
+ elif word in LEVELS:
+ if level:
+ return "cannot specify multiple levels"
+ level = word
+ elif word in Vlog.__mfl:
+ if module:
+ return "cannot specify multiple modules"
+ module = word
+ else:
+ return "no facility, level, or module \"%s\"" % word
+
+ Vlog.set_level(module or "any", facility or "any", level or "any")
+
+ @staticmethod
+ def get_levels():
+ lines = [" console syslog file\n",
+ " ------- ------ ------\n"]
+ lines.extend(sorted(["%-16s %4s %4s %4s\n"
+ % (m,
+ Vlog.__mfl[m]["console"],
+ Vlog.__mfl[m]["syslog"],
+ Vlog.__mfl[m]["file"]) for m in Vlog.__mfl]))
+ return ''.join(lines)
+
@staticmethod
def reopen_log_file():
"""Closes and then attempts to re-open the current log file. (This is
else:
conn.reply("Logging to file not configured")
+ @staticmethod
+ def _unixctl_vlog_set(conn, argv, unused_aux):
+ for arg in argv:
+ msg = Vlog.set_levels_from_string(arg)
+ if msg:
+ conn.reply(msg)
+ return
+ conn.reply(None)
+
+ @staticmethod
+ def _unixctl_vlog_list(conn, unused_argv, unused_aux):
+ conn.reply(Vlog.get_levels())
+
def add_args(parser):
"""Adds vlog related options to 'parser', an ArgumentParser object. The
resulting arguments parsed by 'parser' should be passed to handle_args."""
" is used if LOG_FILE is omitted.")
group.add_argument("-v", "--verbose", nargs="*",
help="Sets logging levels, see ovs-vswitchd(8)."
- " Defaults to ANY:ANY:dbg.")
+ " Defaults to dbg.")
def handle_args(args):
args.verbose = ["any:any:dbg"]
for verbose in args.verbose:
- args = verbose.split(':')
-
- if len(args) >= 3:
- level = args[2]
- else:
- level = "dbg"
-
- if len(args) >= 2:
- facility = args[1]
- else:
- facility = "any"
-
- if len(args) >= 1:
- module = args[0]
- else:
- module = "any"
-
- Vlog.set_level(module, facility, level)
+ msg = Vlog.set_levels_from_string(verbose)
+ if msg:
+ ovs.util.ovs_fatal(0, "processing \"%s\": %s" % (verbose, msg))
Vlog.init(log_file)
message3
])
AT_CLEANUP
+
+AT_SETUP([vlog - vlog/set and vlog/list - Python])
+AT_SKIP_IF([test $HAVE_PYTHON = no])
+OVS_RUNDIR=`pwd`; export OVS_RUNDIR
+OVS_LOGDIR=`pwd`; export OVS_LOGDIR
+OVS_SYSCONFDIR=`pwd`; export OVS_SYSCONFDIR
+trap 'kill `cat test-unixctl.py.pid`' 0
+
+AT_CAPTURE_FILE([log])
+AT_CHECK([$PYTHON $srcdir/test-unixctl.py --log-file=`pwd`/log --pidfile --detach])
+
+AT_CHECK([APPCTL -t test-unixctl.py vlog/list], [0], [dnl
+ console syslog file
+ ------- ------ ------
+daemon info info info
+fatal-signal info info info
+jsonrpc info info info
+poller info info info
+reconnect info info info
+socket_util info info info
+stream info info info
+test-unixctl info info info
+unixctl_server info info info
+])
+
+AT_CHECK([APPCTL -t test-unixctl.py vlog/set daemon:syslog:err])
+AT_CHECK([APPCTL -t test-unixctl.py vlog/set file:dbg])
+AT_CHECK([APPCTL -t test-unixctl.py vlog/set nonexistent], [0],
+ [no facility, level, or module "nonexistent"
+])
+AT_CHECK([APPCTL -t test-unixctl.py vlog/list], [0], [dnl
+ console syslog file
+ ------- ------ ------
+daemon info err dbg
+fatal-signal info info dbg
+jsonrpc info info dbg
+poller info info dbg
+reconnect info info dbg
+socket_util info info dbg
+stream info info dbg
+test-unixctl info info dbg
+unixctl_server info info dbg
+])
+AT_CLEANUP
The default pattern for console and file output is \fB%D{%Y-%m-%dT
%H:%M:%SZ}|%05N|%c|%p|%m\fR; for syslog output, \fB%05N|%c|%p|%m\fR.
.
+.IP
+Daemons written in Python (e.g. \fBovs\-xapi\-sync\fR,
+\fBovs\-monitor\-ipsec) do not allow control over the log pattern.
+.
.IP "\fBvlog/reopen\fR"
Causes the daemon to close and reopen its log file. (This
is useful after rotating log files, to cause a new log file to be
.
.SH "SEE ALSO"
.
-\fBovs\-appctl\fR can control the following daemons:
+\fBovs\-appctl\fR can control all Open vSwitch daemons, including:
.BR ovs\-vswitchd (8),
-.BR ovs\-controller (8),
-.BR ovs\-brcompatd (8).
+and
+.BR ovsdb\-server (8).