ovsdb-client: Add optional timestamps to "monitor" command output.
authorBen Pfaff <blp@nicira.com>
Fri, 27 Jan 2012 20:48:21 +0000 (12:48 -0800)
committerBen Pfaff <blp@nicira.com>
Fri, 3 Feb 2012 00:24:51 +0000 (16:24 -0800)
Suggestion #9347.
Suggested-by: Alan Shieh <ashieh@nicira.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
NEWS
lib/table.c
lib/table.h
ovsdb/ovsdb-client.1.in
ovsdb/ovsdb-client.c

diff --git a/NEWS b/NEWS
index 592e01359e096bd67cf288651554f8bfa90cc5b4..682d83bd12cb2779fda1eafe7d0d3764cfb42c1c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,9 @@ post-v1.5.0
           should maintain by updating with ofproto_rule_update_used().
     - The default MAC learning timeout has been increased from 60 seconds
       to 300 seconds.  The MAC learning timeout is now configurable.
+    - ovsdb-client:
+        - The new option --timestamp causes the "monitor" command to print
+          a timestamp with every update.
 
 
 v1.5.0 - xx xxx xxxx
index 537fae97c32fbf6e8bf0e94eb46e6b005ebec810..8141677c3cfc5d21f95fc71db2740ba9b72e01a9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, 2011 Nicira Networks.
+ * Copyright (c) 2009, 2010, 2011, 2012 Nicira Networks.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@
 #include "json.h"
 #include "ovsdb-data.h"
 #include "ovsdb-error.h"
+#include "timeval.h"
 #include "util.h"
 
 struct column {
@@ -123,6 +124,14 @@ table_set_caption(struct table *table, char *caption)
     table->caption = caption;
 }
 
+/* Turns printing a timestamp along with 'table' on or off, according to
+ * 'timestamp'.  */
+void
+table_set_timestamp(struct table *table, bool timestamp)
+{
+    table->timestamp = timestamp;
+}
+
 /* Adds a new column to 'table' just to the right of any existing column, with
  * 'heading' as a title for the column.  'heading' must be a valid printf()
  * format specifier.
@@ -211,6 +220,24 @@ table_print_table_line__(struct ds *line)
     ds_clear(line);
 }
 
+static void
+table_format_timestamp__(char *s, size_t size)
+{
+    time_t now = time_wall();
+    strftime(s, size, "%Y-%m-%d %H:%M:%S", localtime(&now));
+}
+
+static void
+table_print_timestamp__(const struct table *table)
+{
+    if (table->timestamp) {
+        char s[32];
+
+        table_format_timestamp__(s, sizeof s);
+        puts(s);
+    }
+}
+
 static void
 table_print_table__(const struct table *table, const struct table_style *style)
 {
@@ -223,6 +250,8 @@ table_print_table__(const struct table *table, const struct table_style *style)
         putchar('\n');
     }
 
+    table_print_timestamp__(table);
+
     if (table->caption) {
         puts(table->caption);
     }
@@ -286,6 +315,8 @@ table_print_list__(const struct table *table, const struct table_style *style)
         putchar('\n');
     }
 
+    table_print_timestamp__(table);
+
     if (table->caption) {
         puts(table->caption);
     }
@@ -357,6 +388,8 @@ table_print_html__(const struct table *table, const struct table_style *style)
 {
     size_t x, y;
 
+    table_print_timestamp__(table);
+
     fputs("<table border=1>\n", stdout);
 
     if (table->caption) {
@@ -427,6 +460,8 @@ table_print_csv__(const struct table *table, const struct table_style *style)
         putchar('\n');
     }
 
+    table_print_timestamp__(table);
+
     if (table->caption) {
         puts(table->caption);
     }
@@ -465,6 +500,12 @@ table_print_json__(const struct table *table, const struct table_style *style)
     if (table->caption) {
         json_object_put_string(json, "caption", table->caption);
     }
+    if (table->timestamp) {
+        char s[32];
+
+        table_format_timestamp__(s, sizeof s);
+        json_object_put_string(json, "time", s);
+    }
 
     headings = json_array_create_empty();
     for (x = 0; x < table->n_columns; x++) {
index 146d4dfe32beda3cf730cdd0681c8348ff882d6c..c29d7e31f0e1a4466be63439d3dcc6bfeb49583e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, 2011 Nicira Networks.
+ * Copyright (c) 2009, 2010, 2011, 2012 Nicira Networks.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -32,11 +32,13 @@ struct table {
     size_t n_rows, allocated_rows;
     size_t current_column;
     char *caption;
+    bool timestamp;
 };
 
 void table_init(struct table *);
 void table_destroy(struct table *);
 void table_set_caption(struct table *, char *caption);
+void table_set_timestamp(struct table *, bool timestamp);
 
 void table_add_column(struct table *, const char *heading, ...)
     PRINTF_FORMAT(2, 3);
index e513a3bb118dee7d4abcc032712669da5f891d8d..0065ced3bcb4fd301a9fd1cd4173289444312ca4 100644 (file)
@@ -40,6 +40,7 @@ ovsdb\-client \- command-line interface to \fBovsdb-server\fR(1)
 [\fB\-\-pretty\fR]
 [\fB\-\-bare\fR]
 [\fB\-\-no\-heading\fR]
+[\fB\-\-timestamp\fR]
 .so lib/daemon-syn.man
 .so lib/vlog-syn.man
 .so lib/ssl-syn.man
@@ -137,6 +138,12 @@ The following options controlling output formatting:
 .ds TD (default)
 .so lib/table.man
 .
+.IP "\fB\-\-timestamp\fR"
+For the \fB\-\-monitor\fR command, adds a timestamp to each table
+update.  Most output formats add the timestamp on a line of its own
+just above the table.  The JSON output format puts the timestamp in a
+member of the top-level JSON object named \fBtime\fR.
+.
 .SS "Daemon Options"
 The daemon options apply only to the \fBmonitor\fR command.  With any
 other command, they have no effect.
index d2a9de10e22bf69c4bbfe563bea8d22b82887af0..afa61c3d2e6388ef9bda5d360ba1b995c10c79ac 100644 (file)
@@ -64,6 +64,9 @@ struct ovsdb_client_command {
                     int argc, char *argv[]);
 };
 
+/* --timestamp: Print a timestamp before each update on "monitor" command? */
+static bool timestamp;
+
 /* Format for table output. */
 static struct table_style table_style = TABLE_STYLE_DEFAULT;
 
@@ -160,6 +163,7 @@ parse_options(int argc, char *argv[])
 {
     enum {
         OPT_BOOTSTRAP_CA_CERT = UCHAR_MAX + 1,
+        OPT_TIMESTAMP,
         DAEMON_OPTION_ENUMS,
         TABLE_OPTION_ENUMS
     };
@@ -167,6 +171,7 @@ parse_options(int argc, char *argv[])
         {"verbose", optional_argument, NULL, 'v'},
         {"help", no_argument, NULL, 'h'},
         {"version", no_argument, NULL, 'V'},
+        {"timestamp", no_argument, NULL, OPT_TIMESTAMP},
         DAEMON_LONG_OPTIONS,
 #ifdef HAVE_OPENSSL
         {"bootstrap-ca-cert", required_argument, NULL, OPT_BOOTSTRAP_CA_CERT},
@@ -207,6 +212,10 @@ parse_options(int argc, char *argv[])
             stream_ssl_set_ca_cert_file(optarg, true);
             break;
 
+        case OPT_TIMESTAMP:
+            timestamp = true;
+            break;
+
         case '?':
             exit(EXIT_FAILURE);
 
@@ -256,7 +265,8 @@ usage(void)
            "                              (\"table\", \"html\", \"csv\", "
            "or \"json\")\n"
            "  --no-headings               omit table heading row\n"
-           "  --pretty                    pretty-print JSON in output");
+           "  --pretty                    pretty-print JSON in output\n"
+           "  --timestamp                 timestamp \"monitor\" output");
     daemon_usage();
     vlog_usage();
     printf("\nOther options:\n"
@@ -532,6 +542,7 @@ monitor_print(struct json *table_updates,
     size_t i;
 
     table_init(&t);
+    table_set_timestamp(&t, timestamp);
 
     if (table_updates->type != JSON_OBJECT) {
         ovs_error(0, "<table-updates> is not object");