diff mbox series

[ovs-dev,v2,08/13] ofproto-dpif-lsample: Show stats via unixctl.

Message ID 20240711233238.1038670-9-amorenoz@redhat.com
State Superseded
Headers show
Series Introduce local sampling with NXAST_SAMPLE action. | expand

Checks

Context Check Description
ovsrobot/apply-robot warning apply and check: warning

Commit Message

Adrián Moreno July 11, 2024, 11:32 p.m. UTC
Add a command to dump statistics per exporter.

Signed-off-by: Adrian Moreno <amorenoz@redhat.com>
---
 NEWS                           |   2 +
 ofproto/ofproto-dpif-lsample.c | 111 +++++++++++++++++++++++++++++++++
 ofproto/ofproto-dpif-lsample.h |   2 +
 ofproto/ofproto-dpif.c         |   1 +
 4 files changed, 116 insertions(+)

Comments

Eelco Chaudron July 12, 2024, 2:32 p.m. UTC | #1
On 12 Jul 2024, at 1:32, Adrian Moreno wrote:

> Add a command to dump statistics per exporter.
>
> Signed-off-by: Adrian Moreno <amorenoz@redhat.com>

Changes look good to me. Small nit below, but I'm fine either way so;

Acked-by: Eelco Chaudron <echaudro@redhat.com>

> ---
>  NEWS                           |   2 +
>  ofproto/ofproto-dpif-lsample.c | 111 +++++++++++++++++++++++++++++++++
>  ofproto/ofproto-dpif-lsample.h |   2 +
>  ofproto/ofproto-dpif.c         |   1 +
>  4 files changed, 116 insertions(+)
>
> diff --git a/NEWS b/NEWS
> index 5f5871ef0..096ff4d7d 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -20,6 +20,8 @@ Post-v3.3.0
>       allows samples to be emitted locally (instead of via IPFIX) in a
>       datapath-specific manner.  The Linux kernel datapath is the first to
>       support this feature by using the new datapath "psample" action.
> +   - A new unixctl command 'lsample/show' shows packet and bytes statistics

Should we maybe move this to the '- ovs-appctl:' section above?

> +     per local sample exporter.

<SNIP>
diff mbox series

Patch

diff --git a/NEWS b/NEWS
index 5f5871ef0..096ff4d7d 100644
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,8 @@  Post-v3.3.0
      allows samples to be emitted locally (instead of via IPFIX) in a
      datapath-specific manner.  The Linux kernel datapath is the first to
      support this feature by using the new datapath "psample" action.
+   - A new unixctl command 'lsample/show' shows packet and bytes statistics
+     per local sample exporter.
 
 
 v3.3.0 - 16 Feb 2024
diff --git a/ofproto/ofproto-dpif-lsample.c b/ofproto/ofproto-dpif-lsample.c
index f4bf49a7a..926f88c4e 100644
--- a/ofproto/ofproto-dpif-lsample.c
+++ b/ofproto/ofproto-dpif-lsample.c
@@ -21,7 +21,10 @@ 
 #include "dpif.h"
 #include "hash.h"
 #include "ofproto.h"
+#include "ofproto-dpif.h"
+#include "openvswitch/dynamic-string.h"
 #include "openvswitch/thread.h"
+#include "unixctl.h"
 
 /* Dpif local sampling.
  *
@@ -219,3 +222,111 @@  dpif_lsample_unref(struct dpif_lsample *lsample)
         dpif_lsample_destroy(lsample);
     }
 }
+
+static int
+comp_exporter_collector_id(const void *a_, const void *b_)
+{
+    const struct lsample_exporter_node *a, *b;
+
+    a = *(struct lsample_exporter_node **) a_;
+    b = *(struct lsample_exporter_node **) b_;
+
+    if (a->exporter.options.collector_set_id >
+        b->exporter.options.collector_set_id) {
+        return 1;
+    }
+    if (a->exporter.options.collector_set_id <
+        b->exporter.options.collector_set_id) {
+        return -1;
+    }
+    return 0;
+}
+
+static void
+lsample_exporter_list(struct dpif_lsample *lsample,
+                      struct lsample_exporter_node ***list,
+                      size_t *num_exporters)
+{
+    struct lsample_exporter_node **exporter_list;
+    struct lsample_exporter_node *node;
+    size_t k = 0, n;
+
+    n = cmap_count(&lsample->exporters);
+
+    exporter_list = xcalloc(n, sizeof *exporter_list);
+
+    CMAP_FOR_EACH (node, node, &lsample->exporters) {
+        if (k >= n) {
+            break;
+        }
+        exporter_list[k++] = node;
+    }
+
+    qsort(exporter_list, k, sizeof *exporter_list, comp_exporter_collector_id);
+
+    *list = exporter_list;
+    *num_exporters = k;
+}
+
+static void
+lsample_unixctl_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
+                     const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
+{
+    struct lsample_exporter_node **node_list = NULL;
+    struct ds ds = DS_EMPTY_INITIALIZER;
+    const struct ofproto_dpif *ofproto;
+    size_t i, num;
+
+    ofproto = ofproto_dpif_lookup_by_name(argv[1]);
+    if (!ofproto) {
+        unixctl_command_reply_error(conn, "no such bridge");
+        return;
+    }
+
+    if (!ofproto->lsample) {
+        unixctl_command_reply_error(conn,
+                                    "no local sampling exporters configured");
+        return;
+    }
+
+    ds_put_format(&ds, "Local sample statistics for bridge \"%s\":\n",
+                  argv[1]);
+
+    lsample_exporter_list(ofproto->lsample, &node_list, &num);
+
+    for (i = 0; i < num; i++) {
+        uint64_t n_bytes;
+        uint64_t n_packets;
+
+        struct lsample_exporter_node *node = node_list[i];
+
+        atomic_read_relaxed(&node->exporter.n_packets, &n_packets);
+        atomic_read_relaxed(&node->exporter.n_bytes, &n_bytes);
+
+        if (i) {
+            ds_put_cstr(&ds, "\n");
+        }
+
+        ds_put_format(&ds, "Collector Set ID: %"PRIu32":\n",
+                    node->exporter.options.collector_set_id);
+        ds_put_format(&ds, "  Group ID     : %"PRIu32"\n",
+                    node->exporter.options.group_id);
+        ds_put_format(&ds, "  Total packets: %"PRIu64"\n", n_packets);
+        ds_put_format(&ds, "  Total bytes  : %"PRIu64"\n", n_bytes);
+    }
+
+    free(node_list);
+    unixctl_command_reply(conn, ds_cstr(&ds));
+    ds_destroy(&ds);
+}
+
+void dpif_lsample_init(void)
+{
+    static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
+
+    if (ovsthread_once_start(&once)) {
+        unixctl_command_register("lsample/show", "bridge", 1, 1,
+                                 lsample_unixctl_show, NULL);
+        ovsthread_once_done(&once);
+    }
+}
diff --git a/ofproto/ofproto-dpif-lsample.h b/ofproto/ofproto-dpif-lsample.h
index dbf7237bd..6ac7580ac 100644
--- a/ofproto/ofproto-dpif-lsample.h
+++ b/ofproto/ofproto-dpif-lsample.h
@@ -25,6 +25,8 @@  struct dpif_lsample;
 struct ofproto_lsample_options;
 struct dpif_flow_stats;
 
+void dpif_lsample_init(void);
+
 struct dpif_lsample *dpif_lsample_create(void);
 
 struct dpif_lsample *dpif_lsample_ref(const struct dpif_lsample *);
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 726383e96..b81e59667 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -286,6 +286,7 @@  init(const struct shash *iface_hints)
     ofproto_unixctl_init();
     ofproto_dpif_trace_init();
     udpif_init();
+    dpif_lsample_init();
 }
 
 static void