summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2012-05-01 14:13:00 -0700
committerBen Pfaff <blp@nicira.com>2012-05-22 10:17:05 -0700
commit8ba37945d690d0b7179b4aaf21a54fb300f574b0 (patch)
tree82d2e538c9f11f17b35964e870a38c646e980265
parent53cf9963ccc60b443d738b31fbb446bc79170693 (diff)
downloadopenvswitch-8ba37945d690d0b7179b4aaf21a54fb300f574b0.tar.gz
python: Implement "vlog/reopen" unixctl command in Python vlog.
Signed-off-by: Ben Pfaff <blp@nicira.com>
-rw-r--r--python/ovs/vlog.py33
-rw-r--r--tests/test-unixctl.py6
-rw-r--r--tests/unixctl-py.at2
-rw-r--r--tests/vlog.at77
4 files changed, 115 insertions, 3 deletions
diff --git a/python/ovs/vlog.py b/python/ovs/vlog.py
index b585591b6..b3a8b813f 100644
--- a/python/ovs/vlog.py
+++ b/python/ovs/vlog.py
@@ -1,5 +1,5 @@
-# Copyright (c) 2011 Nicira, Inc.
+# Copyright (c) 2011, 2012 Nicira, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ import socket
import sys
import ovs.dirs
+import ovs.unixctl
import ovs.util
FACILITIES = {"console": "info", "file": "info", "syslog": "info"}
@@ -41,6 +42,8 @@ class Vlog:
__inited = False
__msg_num = 0
__mfl = {} # Module -> facility -> level
+ __log_file = None
+ __file_handler = None
def __init__(self, name):
"""Creates a new Vlog object representing a module called 'name'. The
@@ -99,6 +102,7 @@ class Vlog:
Vlog.__inited = True
logging.raiseExceptions = False
+ Vlog.__log_file = log_file
for f in FACILITIES:
logger = logging.getLogger(f)
logger.setLevel(logging.DEBUG)
@@ -110,11 +114,15 @@ class Vlog:
logger.addHandler(logging.handlers.SysLogHandler(
address="/dev/log",
facility=logging.handlers.SysLogHandler.LOG_DAEMON))
- elif f == "file" and log_file:
- logger.addHandler(logging.FileHandler(log_file))
+ elif f == "file" and Vlog.__log_file:
+ Vlog.__file_handler = logging.FileHandler(Vlog.__log_file)
+ logger.addHandler(Vlog.__file_handler)
except (IOError, socket.error):
logger.setLevel(logging.CRITICAL)
+ ovs.unixctl.command_register("vlog/reopen", "", 0, 0,
+ Vlog._unixctl_vlog_reopen, None)
+
@staticmethod
def set_level(module, facility, level):
""" Sets the log level of the 'module'-'facility' tuple to 'level'.
@@ -149,6 +157,25 @@ class Vlog:
for f in facilities:
Vlog.__mfl[m][f] = level
+ @staticmethod
+ def reopen_log_file():
+ """Closes and then attempts to re-open the current log file. (This is
+ useful just after log rotation, to ensure that the new log file starts
+ being used.)"""
+
+ if Vlog.__log_file:
+ logger = logging.getLogger("file")
+ logger.removeHandler(Vlog.__file_handler)
+ Vlog.__file_handler = logging.FileHandler(Vlog.__log_file)
+ logger.addHandler(Vlog.__file_handler)
+
+ @staticmethod
+ def _unixctl_vlog_reopen(conn, unused_argv, unused_aux):
+ if Vlog.__log_file:
+ Vlog.reopen_log_file()
+ conn.reply(None)
+ else:
+ conn.reply("Logging to file not configured")
def add_args(parser):
"""Adds vlog related options to 'parser', an ArgumentParser object. The
diff --git a/tests/test-unixctl.py b/tests/test-unixctl.py
index 3d86db17d..ab03479be 100644
--- a/tests/test-unixctl.py
+++ b/tests/test-unixctl.py
@@ -40,6 +40,11 @@ def unixctl_echo_error(conn, argv, aux):
conn.reply_error(str(argv))
+def unixctl_log(conn, argv, unused_aux):
+ vlog.info(str(argv[0]))
+ conn.reply(None)
+
+
def unixctl_block(conn, unused_argv, unused_aux):
pass
@@ -64,6 +69,7 @@ def main():
ovs.unixctl.command_register("exit", "", 0, 0, unixctl_exit, "aux_exit")
ovs.unixctl.command_register("echo", "[arg ...]", 1, 2, unixctl_echo,
"aux_echo")
+ ovs.unixctl.command_register("log", "[arg ...]", 1, 2, unixctl_log, None)
ovs.unixctl.command_register("echo_error", "[arg ...]", 1, 2,
unixctl_echo_error, "aux_echo_error")
ovs.unixctl.command_register("block", "", 0, 0, unixctl_block, None)
diff --git a/tests/unixctl-py.at b/tests/unixctl-py.at
index f9caa60f7..37070c918 100644
--- a/tests/unixctl-py.at
+++ b/tests/unixctl-py.at
@@ -104,7 +104,9 @@ The available commands are:
echo_error [[arg ...]]
exit
help
+ log [[arg ...]]
version
+ vlog/reopen
])
mv stdout expout
AT_CHECK([PYAPPCTL -t test-unixctl.py help], [0], [expout])
diff --git a/tests/vlog.at b/tests/vlog.at
index 597c27acd..a1afb10f0 100644
--- a/tests/vlog.at
+++ b/tests/vlog.at
@@ -103,3 +103,80 @@ AssertionError
])
AT_CLEANUP
+
+AT_SETUP([vlog - vlog/reopen - 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_CAPTURE_FILE([log.old])
+AT_CHECK([$PYTHON $srcdir/test-unixctl.py --log-file=`pwd`/log --pidfile --detach])
+
+AT_CHECK([APPCTL -t test-unixctl.py log message])
+mv log log.old
+AT_CHECK([APPCTL -t test-unixctl.py log message2])
+AT_CHECK([APPCTL -t test-unixctl.py vlog/reopen])
+AT_CHECK([APPCTL -t test-unixctl.py log message3])
+AT_CHECK([APPCTL -t test-unixctl.py exit])
+trap '' 0
+
+AT_CHECK([sed 's/.*|//' log.old], [0], [dnl
+Entering run loop.
+message
+message2
+])
+AT_CHECK([sed 's/.*|//' log], [0], [dnl
+message3
+])
+AT_CLEANUP
+
+AT_SETUP([vlog - vlog/reopen without log file - 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_CHECK([$PYTHON $srcdir/test-unixctl.py --pidfile --detach])
+
+AT_CHECK([APPCTL -t test-unixctl.py vlog/reopen], [0],
+ [Logging to file not configured
+])
+AT_CLEANUP
+
+dnl This checks that if vlog/reopen can't reopen the log file,
+dnl nothing particularly bad (e.g. Python throws an exception and
+dnl aborts the program) happens.
+AT_SETUP([vlog - vlog/reopen can't reopen log file - Python])
+AT_SKIP_IF([test $HAVE_PYTHON = no])
+
+# Verify that /dev/full is a character device that fails writes.
+AT_SKIP_IF([test ! -c /dev/full])
+AT_SKIP_IF([echo > /dev/full])
+
+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_CHECK([$PYTHON $srcdir/test-unixctl.py --log-file=`pwd`/log --pidfile --detach])
+AT_CHECK([APPCTL -t test-unixctl.py log message])
+mv log log.old
+ln -s /dev/full log
+AT_CHECK([APPCTL -t test-unixctl.py vlog/reopen])
+AT_CHECK([APPCTL -t test-unixctl.py log message2])
+rm log
+AT_CHECK([APPCTL -t test-unixctl.py vlog/reopen])
+AT_CHECK([APPCTL -t test-unixctl.py log message3])
+AT_CHECK([APPCTL -t test-unixctl.py exit])
+AT_CHECK([sed 's/.*|//' log.old], [0], [dnl
+Entering run loop.
+message
+])
+AT_CHECK([sed 's/.*|//' log], [0], [dnl
+message3
+])
+AT_CLEANUP