When Open vSwitch is run in hundreds of hypervisors, it is
useful to collect log messages through log collectors. To
collect log messages like this, it is useful to log them
in a particular RFC5424 facility in the local system. The
log collectors can then be used to collect logs anytime
desired.

This commit provides a sysadmin the ability to specify the
facility through which the log messages are logged.

Signed-off-by: Gurucharan Shetty <[email protected]>
---
 include/openvswitch/vlog.h |   12 +++++++--
 lib/vlog.c                 |   59 +++++++++++++++++++++++++++++++++++++++++---
 lib/vlog.man               |   10 ++++++++
 python/ovs/vlog.py         |   12 ++++++++-
 tests/vlog.at              |   26 +++++++++++++++++++
 5 files changed, 113 insertions(+), 6 deletions(-)

diff --git a/include/openvswitch/vlog.h b/include/openvswitch/vlog.h
index b1c7aa7..0b69259 100644
--- a/include/openvswitch/vlog.h
+++ b/include/openvswitch/vlog.h
@@ -146,6 +146,9 @@ int vlog_reopen_log_file(void);
 /* Configure syslog target. */
 void vlog_set_syslog_target(const char *target);
 
+/* Configure log facility. */
+void vlog_set_log_facility(const char *facility);
+
 /* Initialization. */
 void vlog_init(void);
 void vlog_enable_async(void);
@@ -229,12 +232,14 @@ void vlog_rate_limit(const struct vlog_module *, enum 
vlog_level,
 /* Command line processing. */
 #define VLOG_OPTION_ENUMS                       \
         OPT_LOG_FILE,                           \
-        OPT_SYSLOG_TARGET
+        OPT_SYSLOG_TARGET,                      \
+        OPT_LOG_FACILITY
 
 #define VLOG_LONG_OPTIONS                                               \
         {"verbose",       optional_argument, NULL, 'v'},                \
         {"log-file",      optional_argument, NULL, OPT_LOG_FILE},       \
-        {"syslog-target", optional_argument, NULL, OPT_SYSLOG_TARGET}
+        {"syslog-target", optional_argument, NULL, OPT_SYSLOG_TARGET},  \
+        {"log-facility",  required_argument, NULL, OPT_LOG_FACILITY}
 
 #define VLOG_OPTION_HANDLERS                    \
         case 'v':                               \
@@ -245,6 +250,9 @@ void vlog_rate_limit(const struct vlog_module *, enum 
vlog_level,
             break;                              \
         case OPT_SYSLOG_TARGET:                 \
             vlog_set_syslog_target(optarg);     \
+            break;                              \
+        case OPT_LOG_FACILITY:                  \
+            vlog_set_log_facility(optarg);      \
             break;
 
 void vlog_usage(void);
diff --git a/lib/vlog.c b/lib/vlog.c
index c680027..355bfe4 100644
--- a/lib/vlog.c
+++ b/lib/vlog.c
@@ -110,6 +110,40 @@ static bool log_async OVS_GUARDED_BY(log_file_mutex);
 /* Syslog export configuration. */
 static int syslog_fd OVS_GUARDED_BY(pattern_rwlock) = -1;
 
+/* Log facility configuration. */
+static unsigned int log_facility;
+
+/* Facility name and its value. */
+struct vlog_facility {
+    char *name;           /* Name. */
+    unsigned int value;   /* Facility associated with 'name'. */
+};
+static struct vlog_facility vlog_facilities[] = {
+    {"kern", LOG_KERN},
+    {"user", LOG_USER},
+    {"mail", LOG_MAIL},
+    {"daemon", LOG_DAEMON},
+    {"auth", LOG_AUTH},
+    {"syslog", LOG_SYSLOG},
+    {"lpr", LOG_LPR},
+    {"news", LOG_NEWS},
+    {"uucp", LOG_UUCP},
+    {"clock", LOG_CRON},
+    {"ftp", LOG_FTP},
+    {"ntp", 12<<3},
+    {"audit", 13<<3},
+    {"alert", 14<<3},
+    {"clock2", 15<<3},
+    {"local0", LOG_LOCAL0},
+    {"local1", LOG_LOCAL1},
+    {"local2", LOG_LOCAL2},
+    {"local3", LOG_LOCAL3},
+    {"local4", LOG_LOCAL4},
+    {"local5", LOG_LOCAL5},
+    {"local6", LOG_LOCAL6},
+    {"local7", LOG_LOCAL7}
+};
+
 static void format_log_message(const struct vlog_module *, enum vlog_level,
                                const char *pattern,
                                const char *message, va_list, struct ds *)
@@ -507,6 +541,22 @@ vlog_set_syslog_target(const char *target)
     ovs_rwlock_unlock(&pattern_rwlock);
 }
 
+void
+vlog_set_log_facility(const char* facility)
+{
+    size_t i;
+    for (i = 0; i < ARRAY_SIZE(vlog_facilities); i++) {
+        if (!strcasecmp(vlog_facilities[i].name, facility)) {
+            log_facility = vlog_facilities[i].value;
+            break;
+        }
+    }
+
+    if (!log_facility) {
+        ovs_fatal(0, "processing \"%s\" : invalid string", facility);
+    }
+}
+
 static void
 vlog_unixctl_set(struct unixctl_conn *conn, int argc, const char *argv[],
                  void *aux OVS_UNUSED)
@@ -625,7 +675,8 @@ vlog_init(void)
          * a pointer to the private copy to suppress memory leak warnings in
          * case openlog() does make its own copy.) */
         program_name_copy = program_name ? xstrdup(program_name) : NULL;
-        openlog(program_name_copy, LOG_NDELAY, LOG_DAEMON);
+        openlog(program_name_copy, LOG_NDELAY,
+                log_facility ? log_facility : LOG_DAEMON);
         ovsthread_once_done(&once);
 
         /* Now do anything that we want to happen only once but doesn't have to
@@ -739,6 +790,7 @@ format_log_message(const struct vlog_module *module, enum 
vlog_level level,
     char tmp[128];
     va_list args;
     const char *p;
+    unsigned int facility;
 
     ds_clear(s);
     for (p = pattern; *p != '\0'; ) {
@@ -773,7 +825,8 @@ format_log_message(const struct vlog_module *module, enum 
vlog_level level,
             ds_put_cstr(s, program_name);
             break;
         case 'B':
-            ds_put_format(s, "%d", LOG_LOCAL0 + syslog_levels[level]);
+            facility = log_facility ? log_facility : LOG_LOCAL0;
+            ds_put_format(s, "%d", facility + syslog_levels[level]);
             break;
         case 'c':
             p = fetch_braces(p, "", tmp, sizeof tmp);
@@ -902,7 +955,7 @@ vlog_valist(const struct vlog_module *module, enum 
vlog_level level,
                                message, args, &s);
             for (line = strtok_r(s.string, "\n", &save_ptr); line;
                  line = strtok_r(NULL, "\n", &save_ptr)) {
-                syslog(syslog_level, "%s", line);
+                syslog(syslog_level|log_facility, "%s", line);
             }
 
             if (syslog_fd >= 0) {
diff --git a/lib/vlog.man b/lib/vlog.man
index ddf14d8..569d5fd 100644
--- a/lib/vlog.man
+++ b/lib/vlog.man
@@ -54,6 +54,16 @@ Sets the maximum logging verbosity level, equivalent to
 Sets the log pattern for \fIdestination\fR to \fIpattern\fR.  Refer to
 \fBovs\-appctl\fR(8) for a description of the valid syntax for \fIpattern\fR.
 .
+.IP "\fB\-\-log\-facility=\fIfacility\fR"
+Sets the RFC5424 facility of the log message. \fIfacility\fR can be one of
+\fBkern\fR, \fBuser\fR, \fBmail\fR, \fBdaemon\fR, \fBauth\fR, \fBsyslog\fR,
+\fBlpr\fR, \fBnews\fR, \fBuucp\fR, \fBclock\fR, \fBftp\fR, \fBntp\fR,
+\fBaudit\fR, \fBalert\fR, \fBclock2\fR, \fBlocal0\fR, \fBlocal1\fR,
+\fBlocal2\fR, \fBlocal3\fR, \fBlocal4\fR, \fBlocal5\fR, \fBlocal6\fR or
+\fBlocal7\fR. If this option is not specified, \fBdaemon\fR is used as
+the default for the local system syslog and \fBlocal0\fR is used while sending
+a message to the target provided via the \fB\-\-syslog\-target\fR option.
+.
 .TP
 \fB\-\-log\-file\fR[\fB=\fIfile\fR]
 Enables logging to a file.  If \fIfile\fR is specified, then it is
diff --git a/python/ovs/vlog.py b/python/ovs/vlog.py
index 105d126..924c83e 100644
--- a/python/ovs/vlog.py
+++ b/python/ovs/vlog.py
@@ -40,6 +40,7 @@ LEVELS = {
     "emer": logging.CRITICAL,
     "off": logging.CRITICAL
 }
+log_facility = 0
 
 
 def get_level(level_str):
@@ -226,7 +227,7 @@ class Vlog:
                 elif f == "syslog":
                     logger.addHandler(logging.handlers.SysLogHandler(
                         address="/dev/log",
-                        facility=logging.handlers.SysLogHandler.LOG_DAEMON))
+                        facility=log_facility))
                 elif f == "file" and Vlog.__log_file:
                     Vlog.__file_handler = logging.FileHandler(Vlog.__log_file)
                     logger.addHandler(Vlog.__file_handler)
@@ -372,6 +373,12 @@ def add_args(parser):
     group.add_argument("--log-file", nargs="?", const="default",
                        help="Enables logging to a file.  Default log file"
                        " is used if LOG_FILE is omitted.")
+    group.add_argument("--log-facility", nargs='?', const="daemon",
+                       default="daemon", choices=['auth', 'authpriv', 'cron',
+                       'daemon', 'ftp', 'kern', 'lpr', 'mail', 'news',
+                       'syslog', 'user', 'uucp', 'local0', 'local1', 'local2',
+                       'local3', 'local4', 'local5', 'local6', 'local7'],
+                       help="Sets the facility of the log message.")
     group.add_argument("-v", "--verbose", nargs="*",
                        help="Sets logging levels, see ovs-vswitchd(8)."
                        "  Defaults to dbg.")
@@ -386,6 +393,9 @@ def handle_args(args):
     if log_file == "default":
         log_file = "%s/%s.log" % (ovs.dirs.LOGDIR, ovs.util.PROGRAM_NAME)
 
+    global log_facility
+    log_facility = args.log_facility
+
     if args.verbose is None:
         args.verbose = []
     elif args.verbose == []:
diff --git a/tests/vlog.at b/tests/vlog.at
index 4a143cd..604224c 100644
--- a/tests/vlog.at
+++ b/tests/vlog.at
@@ -234,3 +234,29 @@ AT_CHECK([APPCTL -t test-unixctl.py vlog/set 
pattern:file:'I<3OVS|%m'])
 AT_CHECK([APPCTL -t test-unixctl.py log patterntest])
 AT_CHECK([grep -q 'I<3OVS' log])
 AT_CLEANUP
+
+AT_SETUP([vlog - RFC5424 facility])
+OVS_RUNDIR=`pwd`; export OVS_RUNDIR
+OVS_LOGDIR=`pwd`; export OVS_LOGDIR
+OVS_DBDIR=`pwd`; export OVS_DBDIR
+OVS_SYSCONFDIR=`pwd`; export OVS_SYSCONFDIR
+ON_EXIT([kill `cat ovsdb-server.pid`])
+
+dnl Create database.
+touch .conf.db.~lock~
+AT_CHECK([ovsdb-tool create conf.db 
$abs_top_srcdir/vswitchd/vswitch.ovsschema])
+
+AT_CHECK([ovsdb-server --detach --no-chdir --pidfile 
--remote=punix:$OVS_RUNDIR/db.sock -vPATTERN:file:"<%B>1 %A %m" --log-file], 
[0], [], [stderr])
+AT_CHECK([ovs-appctl -t ovsdb-server exit])
+
+# A default facility of LOG_LOCAL0 while writing to file.
+AT_CHECK([cat ovsdb-server.log | head -1 | awk '{print $1}'], [0], [<133>1
+])
+rm ovsdb-server.log
+
+AT_CHECK([ovsdb-server --detach --no-chdir --pidfile 
--remote=punix:$OVS_RUNDIR/db.sock -vPATTERN:file:"<%B>1 %A %m" 
--log-facility=daemon --log-file], [0], [], [stderr])
+AT_CHECK([ovs-appctl -t ovsdb-server exit])
+
+AT_CHECK([cat ovsdb-server.log | head -1 | awk '{print $1}'], [0], [<29>1
+])
+AT_CLEANUP
-- 
1.7.9.5

_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev

Reply via email to