ovsdb-tool: Make show-log command offer more verbose output.
authorBen Pfaff <blp@nicira.com>
Mon, 11 Jan 2010 21:47:35 +0000 (13:47 -0800)
committerBen Pfaff <blp@nicira.com>
Mon, 11 Jan 2010 21:47:35 +0000 (13:47 -0800)
This may be useful for debugging.

With fixes suggested by Justin Pettit.

ovsdb/ovsdb-tool.1.in
ovsdb/ovsdb-tool.c

index b96bdd738fa2423c0e0a2ee04ae8ae30b40d711e..04e6296860893f9c4820febee2ea50e9d0f17f00 100644 (file)
@@ -18,7 +18,7 @@ ovsdb\-tool \- Open vSwitch database management utility
 .br
 \fBovsdb\-tool \fR[\fIoptions\fR] \fBtransact\fI db transaction\fR
 .br
-\fBovsdb\-tool \fR[\fIoptions\fR] \fBshow\-log\fI db\fR
+\fBovsdb\-tool \fR[\fIoptions\fR] [\fB-m\fR | \fB--more\fR]... \fBshow\-log\fI db\fR
 .br
 \fBovsdb\-tool help\fR
 .so lib/vlog-syn.man
@@ -68,6 +68,13 @@ instead, to write to a database that is served by
 Prints a summary of the records in \fBdb\fR's log, including the time
 and date at which each database change occurred and any associated
 comment.  This may be useful for debugging.
+.PP
+To increase the verbosity of output, add \fB-m\fR (or \fB--more\fR)
+one or more times to the command line.  With one \fB-m\fR,
+\fBshow\-log\fR prints a summary of the records added, deleted, or
+modified by each transaction.  With two \fB-m\fRs, \fBshow\-log\fR
+also prints the values of the columns modified by each change to a
+record.
 .
 .SH OPTIONS
 .SS "Logging Options"
index c318be5f3c25b882ed64358d3008bb5f59eaba4b..d506aae334dc56a11f5ca66cb22c78b83b318ebc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Nicira Networks.
+ * Copyright (c) 2009, 2010 Nicira Networks.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -36,6 +36,9 @@
 #include "vlog.h"
 #define THIS_MODULE VLM_ovsdb_tool
 
+/* -m, --more: Verbosity level for "show-log" command output. */
+static int show_log_verbosity;
+
 static const struct command all_commands[];
 
 static void usage(void) NO_RETURN;
@@ -57,6 +60,7 @@ static void
 parse_options(int argc, char *argv[])
 {
     static struct option long_options[] = {
+        {"more", no_argument, 0, 'm'},
         {"verbose", optional_argument, 0, 'v'},
         {"help", no_argument, 0, 'h'},
         {"version", no_argument, 0, 'V'},
@@ -73,6 +77,10 @@ parse_options(int argc, char *argv[])
         }
 
         switch (c) {
+        case 'm':
+            show_log_verbosity++;
+            break;
+
         case 'h':
             usage();
 
@@ -108,6 +116,7 @@ usage(void)
            program_name, program_name);
     vlog_usage();
     printf("\nOther options:\n"
+           "  -m, --more                  increase show-log verbosity\n"
            "  -h, --help                  display this help message\n"
            "  -V, --version               display version information\n");
     exit(EXIT_SUCCESS);
@@ -191,14 +200,95 @@ do_transact(int argc UNUSED, char *argv[])
     transact(false, argv[1], argv[2]);
 }
 
+static void
+print_db_changes(struct shash *tables, struct shash *names)
+{
+    struct shash_node *n1;
+
+    SHASH_FOR_EACH (n1, tables) {
+        const char *table = n1->name;
+        struct json *rows = n1->data;
+        struct shash_node *n2;
+
+        if (n1->name[0] == '_' || rows->type != JSON_OBJECT) {
+            continue;
+        }
+
+        SHASH_FOR_EACH (n2, json_object(rows)) {
+            const char *row_uuid = n2->name;
+            struct json *columns = n2->data;
+            struct shash_node *n3;
+            char *old_name, *new_name;
+            bool free_new_name = false;
+
+            old_name = new_name = shash_find_data(names, row_uuid);
+            if (columns->type == JSON_OBJECT) {
+                struct json *new_name_json;
+
+                new_name_json = shash_find_data(json_object(columns), "name");
+                if (new_name_json) {
+                    new_name = json_to_string(new_name_json, JSSF_SORT);
+                    free_new_name = true;
+                }
+            }
+
+            printf("\ttable %s", table);
+
+            if (!old_name) {
+                if (new_name) {
+                    printf(" insert row %s:\n", new_name);
+                } else {
+                    printf(" insert row %.8s:\n", row_uuid);
+                }
+            } else {
+                printf(" row %s:\n", old_name);
+            }
+
+            if (columns->type == JSON_OBJECT) {
+                if (show_log_verbosity > 1) {
+                    SHASH_FOR_EACH (n3, json_object(columns)) {
+                        const char *column = n3->name;
+                        struct json *value = n3->data;
+                        char *value_string;
+
+                        value_string = json_to_string(value, JSSF_SORT);
+                        printf("\t\t%s=%s\n", column, value_string);
+                        free(value_string);
+                    }
+                }
+                if (!old_name
+                    || (new_name != old_name && strcmp(old_name, new_name))) {
+                    if (old_name) {
+                        shash_delete(names, shash_find(names, row_uuid));
+                        free(old_name);
+                    }
+                    shash_add(names, row_uuid, (new_name
+                                                ? xstrdup(new_name)
+                                                : xmemdup0(row_uuid, 8)));
+                }
+            } else if (columns->type == JSON_NULL) {
+                printf("\t\tdelete row\n");
+                shash_delete(names, shash_find(names, row_uuid));
+                free(old_name);
+            }
+
+            if (free_new_name) {
+                free(new_name);
+            }
+        }
+    }
+}
+
 static void
 do_show_log(int argc UNUSED, char *argv[])
 {
     const char *db_file_name = argv[1];
+    struct shash names;
     struct ovsdb_log *log;
     unsigned int i;
 
     check_ovsdb_error(ovsdb_log_open(db_file_name, O_RDONLY, &log));
+    shash_init(&names);
     for (i = 0; ; i++) {
         struct json *json;
 
@@ -224,10 +314,17 @@ do_show_log(int argc UNUSED, char *argv[])
             if (comment && comment->type == JSON_STRING) {
                 printf(" \"%s\"", json_string(comment));
             }
+
+            if (i > 0 && show_log_verbosity > 0) {
+                putchar('\n');
+                print_db_changes(json_object(json), &names);
+            }
         }
         json_destroy(json);
         putchar('\n');
     }
+
+    /* XXX free 'names'. */
 }
 
 static void