[ovs-dev] [PATCH 2/3] Save performance stats to database.

Mark Michelson mmichels at redhat.com
Mon Dec 18 22:51:38 UTC 2017


This commit builds on the performance library by storing compiled
statistics in the OVS vswitchd database.

This can make it more useful for administrators to keep tabs on
performance in real time and make adjustments if necessary.

Signed-off-by: Mark Michelson <mmichels at redhat.com>
---
 lib/performance.c          | 69 ++++++++++++++++++++++++++++++++++++++++++++--
 lib/performance.h          |  8 ++++--
 vswitchd/vswitch.ovsschema | 39 ++++++++++++++++++++++++--
 vswitchd/vswitch.xml       | 69 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 179 insertions(+), 6 deletions(-)

diff --git a/lib/performance.c b/lib/performance.c
index 0d0de3645..b71901d78 100644
--- a/lib/performance.c
+++ b/lib/performance.c
@@ -23,6 +23,7 @@
 #include "unixctl.h"
 #include "openvswitch/dynamic-string.h"
 #include "openvswitch/poll-loop.h"
+#include "vswitch-idl.h"
 
 VLOG_DEFINE_THIS_MODULE(performance);
 
@@ -189,12 +190,14 @@ performance_init(void)
 }
 
 void
-performance_create(const char *name, long long int sample_rate)
+performance_create(const char *name, long long int sample_rate,
+    struct ovsdb_idl *idl)
 {
     performance_init();
 
     struct performance *perf = xcalloc(1, sizeof *perf);
     perf->sample_rate = sample_rate;
+    perf->idl = idl;
     timer_set_duration(&perf->timer, perf->sample_rate);
     shash_add(&performances, name, perf);
 }
@@ -207,6 +210,15 @@ performance_destroy(const char *name)
         free(perf->vec.samples);
     }
 
+    const struct ovsrec_performance *performance;
+    const struct ovsrec_performance *next;
+
+    OVSREC_PERFORMANCE_FOR_EACH_SAFE (performance, next, perf->idl) {
+        if (!strcmp(performance->name, name)) {
+            ovsrec_performance_delete(performance);
+        }
+    }
+
     free(perf);
 }
 
@@ -313,8 +325,59 @@ get_stats(const struct sample_vec *vec, long long int age_ms,
     return 0;
 }
 
+static void
+save_stats_to_db(const struct performance *perf, const char *name,
+    struct ovsdb_idl_txn *txn)
+{
+    if (!txn) {
+        return;
+    }
+
+    const struct ovsrec_performance *performance;
+
+    OVSREC_PERFORMANCE_FOR_EACH (performance, perf->idl) {
+        if (!strcmp(performance->name, name)) {
+            break;
+        }
+    }
+
+    if (!performance) {
+        struct ovsrec_performance *new_performance;
+        new_performance = ovsrec_performance_insert(txn);
+        ovsrec_performance_set_name(new_performance, name);
+        performance = new_performance;
+    }
+
+    ovsrec_performance_set_one_minute_samples(performance,
+        perf->one_min.num_samples);
+    ovsrec_performance_set_one_minute_max(performance, perf->one_min.max);
+    ovsrec_performance_set_one_minute_min(performance, perf->one_min.min);
+    ovsrec_performance_set_one_minute_average(performance,
+        perf->one_min.average);
+    ovsrec_performance_set_one_minute_ninety_five_percentile(performance,
+        perf->one_min.percentile);
+
+    ovsrec_performance_set_five_minute_samples(performance,
+        perf->five_min.num_samples);
+    ovsrec_performance_set_five_minute_max(performance, perf->five_min.max);
+    ovsrec_performance_set_five_minute_min(performance, perf->five_min.min);
+    ovsrec_performance_set_five_minute_average(performance,
+        perf->five_min.average);
+    ovsrec_performance_set_five_minute_ninety_five_percentile(performance,
+        perf->five_min.percentile);
+
+    ovsrec_performance_set_ten_minute_samples(performance,
+        perf->ten_min.num_samples);
+    ovsrec_performance_set_ten_minute_max(performance, perf->ten_min.max);
+    ovsrec_performance_set_ten_minute_min(performance, perf->ten_min.min);
+    ovsrec_performance_set_ten_minute_average(performance,
+        perf->ten_min.average);
+    ovsrec_performance_set_ten_minute_ninety_five_percentile(performance,
+        perf->ten_min.percentile);
+}
+
 void
-performance_run(const char *name)
+performance_run(const char *name, struct ovsdb_idl_txn *txn)
 {
     struct performance *perf = shash_find_data(&performances, name);
     if (!perf) {
@@ -329,6 +392,8 @@ performance_run(const char *name)
     get_stats(&perf->vec, 300000, &perf->five_min);
     get_stats(&perf->vec, 600000, &perf->ten_min);
 
+    save_stats_to_db(perf, name, txn);
+
     cull_old_times(&perf->vec, 600000);
     timer_set_duration(&perf->timer, perf->sample_rate);
     timer_wait(&perf->timer);
diff --git a/lib/performance.h b/lib/performance.h
index 64d460708..3d86bf7de 100644
--- a/lib/performance.h
+++ b/lib/performance.h
@@ -31,11 +31,15 @@
  * 4) When complete, call performance_destroy() to clean up.
  */
 
-void performance_create(const char *name, long long int sample_rate);
+struct ovsdb_idl;
+struct ovsdb_idl_txn;
+
+void performance_create(const char *name, long long int sample_rate,
+                        struct ovsdb_idl *idl);
 void performance_destroy(const char *name);
 void performance_set_sample_rate(const char * name, long long int sample_rate);
 bool start_sample(const char *name);
 bool end_sample(const char *name);
-void performance_run(const char *name);
+void performance_run(const char *name, struct ovsdb_idl_txn *txn);
 
 #endif /* performance.h */
diff --git a/vswitchd/vswitch.ovsschema b/vswitchd/vswitch.ovsschema
index 90e50b626..579483fdf 100644
--- a/vswitchd/vswitch.ovsschema
+++ b/vswitchd/vswitch.ovsschema
@@ -1,6 +1,6 @@
 {"name": "Open_vSwitch",
  "version": "7.15.1",
- "cksum": "3682332033 23608",
+ "cksum": "1712487757 24640",
  "tables": {
    "Open_vSwitch": {
      "columns": {
@@ -648,4 +648,39 @@
                   "value": {"type": "integer",
                           "minInteger": 0,
                           "maxInteger": 4095},
-                  "min": 0, "max": "unlimited"}}}}}}
+                  "min": 0, "max": "unlimited"}}}},
+   "Performance": {
+     "columns": {
+       "name": {
+         "type": "string"},
+       "one_minute_samples": {
+         "type": "integer"},
+       "one_minute_min": {
+         "type": "integer"},
+       "one_minute_max": {
+         "type": "integer"},
+       "one_minute_average": {
+         "type": "integer"},
+       "one_minute_ninety_five_percentile": {
+         "type": "integer"},
+       "five_minute_samples": {
+         "type": "integer"},
+       "five_minute_min": {
+         "type": "integer"},
+       "five_minute_max": {
+         "type": "integer"},
+       "five_minute_average": {
+         "type": "integer"},
+       "five_minute_ninety_five_percentile": {
+         "type": "integer"},
+       "ten_minute_samples": {
+         "type": "integer"},
+       "ten_minute_min": {
+         "type": "integer"},
+       "ten_minute_max": {
+         "type": "integer"},
+       "ten_minute_average": {
+         "type": "integer"},
+       "ten_minute_ninety_five_percentile": {
+         "type": "integer"}},
+     "isRoot": true}}}
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
index 21ffaf541..045d9b049 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -5399,4 +5399,73 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch options:peer=p1 \
       id.
     </column>
   </table>
+
+  <table name="Performance">
+    <p>
+      Performance measurements for operations within OVS.
+    </p>
+
+    <p>
+      OVS and OVN perform repeated operations during their lifetimes. Some of
+      these operations are timed and have their measurements saved. From those
+      saved measurements, statistics are written to the
+      <ref table="Performance"/> table at regular intervals.
+    </p>
+
+    <p>
+      All times are measured in milliseconds.
+    </p>
+    <column name="name">
+      Performance identifier. Must be unique amongst other performance
+      measurements.
+    </column>
+    <column name="one_minute_samples">
+      The number of performance measurements taken over the past minute.
+    </column>
+    <column name="one_minute_min">
+      The minimum performance measurement taken over the past minute.
+    </column>
+    <column name="one_minute_max">
+      The maximum performance measurement taken over the past minute.
+    </column>
+    <column name="one_minute_average">
+      The average performance measurement taken over the past minute.
+    </column>
+    <column name="one_minute_ninety_five_percentile">
+      The ninety-fifth percentile  performance measurement taken over the past
+      minute.
+    </column>
+    <column name="five_minute_samples">
+      The number of performance measurements taken over the past five minutes.
+    </column>
+    <column name="five_minute_min">
+      The minimum performance measurement taken over the past five minutes.
+    </column>
+    <column name="five_minute_max">
+      The maximum performance measurement taken over the past five minutes.
+    </column>
+    <column name="five_minute_average">
+      The average performance measurement taken over the past five minutes.
+    </column>
+    <column name="five_minute_ninety_five_percentile">
+      The ninety-fifth percentile  performance measurement taken over the past
+      five minutes.
+    </column>
+    <column name="ten_minute_samples">
+      The number of performance measurements taken over the past ten minutes.
+    </column>
+    <column name="ten_minute_min">
+      The minimum performance measurement taken over the past ten minutes.
+    </column>
+    <column name="ten_minute_max">
+      The maximum performance measurement taken over the past ten minutes.
+    </column>
+    <column name="ten_minute_average">
+      The average performance measurement taken over the past ten minutes.
+    </column>
+    <column name="ten_minute_ninety_five_percentile">
+      The ninety-fifth percentile  performance measurement taken over the past
+      ten minutes.
+    </column>
+  </table>
 </database>
-- 
2.13.5



More information about the dev mailing list