STATS: Add more hierarchy to counters.

Put error counters under node_index.
/err/<node-name>/<error-name>

E.g:
/err/ip4-lookup/Hash table collisions
/err/ip6-rewrite/Buffer allocation error

Error names are not globally unique, and this allows
for walking all errors for a particular node.

Put interface counters under the directory /if.
E.g. /if/rx

Put system counters under the directory /sys.
E.g. /sys/vector_rate

Change-Id: I5b794d16698f61bcb2063a8cd77a7c4ae36419b8
Signed-off-by: Ole Troan <ot@cisco.com>
diff --git a/src/vlib/error.c b/src/vlib/error.c
index 3681182..3ea62e5 100644
--- a/src/vlib/error.c
+++ b/src/vlib/error.c
@@ -208,7 +208,7 @@
 
     for (i = 0; i < n_errors; i++)
       {
-	error_name = format (0, "/err/%s%c", error_strings[i], 0);
+	error_name = format (0, "/err/%s/%s%c", n->name, error_strings[i], 0);
 	/* Note: error_name consumed by the following call */
 	vlib_stats_register_error_index (error_name, n->error_heap_index + i);
       }
diff --git a/src/vnet/interface.c b/src/vnet/interface.c
index 7a2c3ab..34ad292 100644
--- a/src/vnet/interface.c
+++ b/src/vnet/interface.c
@@ -1297,38 +1297,20 @@
 						   CLIB_CACHE_LINE_BYTES);
   im->sw_if_counter_lock[0] = 1;	/* should be no need */
 
-  /*
-   * $$$$ add stat segment name(s) if desired
-   * set xxx.stat_segment_name = "whatever"...
-   */
   vec_validate (im->sw_if_counters, VNET_N_SIMPLE_INTERFACE_COUNTER - 1);
-  im->sw_if_counters[VNET_INTERFACE_COUNTER_DROP].name = "drops";
-  im->sw_if_counters[VNET_INTERFACE_COUNTER_PUNT].name = "punts";
-  im->sw_if_counters[VNET_INTERFACE_COUNTER_IP4].name = "ip4";
-  im->sw_if_counters[VNET_INTERFACE_COUNTER_IP6].name = "ip6";
-  im->sw_if_counters[VNET_INTERFACE_COUNTER_RX_NO_BUF].name = "rx-no-buf";
-  im->sw_if_counters[VNET_INTERFACE_COUNTER_RX_MISS].name = "rx-miss";
-  im->sw_if_counters[VNET_INTERFACE_COUNTER_RX_ERROR].name = "rx-error";
-  im->sw_if_counters[VNET_INTERFACE_COUNTER_TX_ERROR].name = "tx-error";
-
-  vec_validate (im->combined_sw_if_counters,
-		VNET_N_COMBINED_INTERFACE_COUNTER - 1);
-  im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_RX].name = "rx";
-  im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_RX_UNICAST].name =
-    "rx-unicast";
-  im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_RX_MULTICAST].name =
-    "rx-multicast";
-  im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_RX_BROADCAST].name =
-    "rx-broadcast";
-  im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_TX].name = "tx";
-  im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_TX_UNICAST].name =
-    "tx-unicast";
-  im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_TX_MULTICAST].name =
-    "tx-multicast";
-  im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_TX_BROADCAST].name =
-    "tx-broadcast";
-
-  im->sw_if_counter_lock[0] = 0;
+#define _(E,n,p)							\
+  im->sw_if_counters[VNET_INTERFACE_COUNTER_##E].name = #n;		\
+  im->sw_if_counters[VNET_INTERFACE_COUNTER_##E].stat_segment_name = "/" #p "/" #n;
+  foreach_simple_interface_counter_name
+#undef _
+    vec_validate (im->combined_sw_if_counters,
+		  VNET_N_COMBINED_INTERFACE_COUNTER - 1);
+#define _(E,n,p)							\
+  im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_##E].name = #n;	\
+  im->combined_sw_if_counters[VNET_INTERFACE_COUNTER_##E].stat_segment_name = "/" #p "/" #n;
+  foreach_combined_interface_counter_name
+#undef _
+    im->sw_if_counter_lock[0] = 0;
 
   im->device_class_by_name = hash_create_string ( /* size */ 0,
 						 sizeof (uword));
diff --git a/src/vnet/interface.h b/src/vnet/interface.h
index b582dba..1181c34 100644
--- a/src/vnet/interface.h
+++ b/src/vnet/interface.h
@@ -737,6 +737,26 @@
        _x <= VNET_INTERFACE_COUNTER_TX_BROADCAST;               \
        _x++)
 
+#define foreach_simple_interface_counter_name	\
+  _(DROP, drops, if)				\
+  _(PUNT, punt, if)				\
+  _(IP4, ip4, if)				\
+  _(IP6, ip6, if)				\
+  _(RX_NO_BUF, rx-no-buf, if)			\
+  _(RX_MISS, rx-miss, if)			\
+  _(RX_ERROR, rx-error, if)			\
+  _(TX_ERROR, tx-error, if)
+
+#define foreach_combined_interface_counter_name	\
+  _(RX, rx, if)					\
+  _(RX_UNICAST, rx-unicast, if)			\
+  _(RX_MULTICAST, rx-multicast, if)		\
+  _(RX_BROADCAST, rx-broadcast, if)		\
+  _(TX, tx, if)					\
+  _(TX_UNICAST, tx-unicast-miss, if)		\
+  _(TX_MULTICAST, tx-multicast, if)		\
+  _(TX_BROADCAST, tx-broadcast, if)
+
 typedef enum
 {
   COLLECT_SIMPLE_STATS = 0,
diff --git a/src/vpp/app/stat_client.c b/src/vpp/app/stat_client.c
index 96c1bda..b3dee53 100644
--- a/src/vpp/app/stat_client.c
+++ b/src/vpp/app/stat_client.c
@@ -142,17 +142,15 @@
 }
 
 #define foreach_cached_pointer                                          \
-_(vector_rate, SCALAR_POINTER, &stat_client_main.vector_rate_ptr)       \
-_(input_rate, SCALAR_POINTER, &stat_client_main.input_rate_ptr)         \
-_(last_update, SCALAR_POINTER, &stat_client_main.last_runtime_ptr)      \
-_(last_stats_clear, SCALAR_POINTER,                                     \
+_(/sys/vector_rate, SCALAR_POINTER, &stat_client_main.vector_rate_ptr)	\
+_(/sys/input_rate, SCALAR_POINTER, &stat_client_main.input_rate_ptr)	\
+_(/sys/last_update, SCALAR_POINTER, &stat_client_main.last_runtime_ptr)	\
+_(/sys/last_stats_clear, SCALAR_POINTER,				\
   &stat_client_main.last_runtime_stats_clear_ptr)                       \
-_(rx, COUNTER_VECTOR, &stat_client_main.intfc_rx_counters)              \
-_(tx, COUNTER_VECTOR, &stat_client_main.intfc_tx_counters)              \
+_(/if/rx, COUNTER_VECTOR, &stat_client_main.intfc_rx_counters)		\
+_(/if/tx, COUNTER_VECTOR, &stat_client_main.intfc_tx_counters)		\
 _(/err/0/counter_vector, VECTOR_POINTER,                                \
   &stat_client_main.thread_0_error_counts)                              \
-_(/err/IP4 source address matches local interface, ERROR_INDEX,         \
-  &stat_client_main.source_address_match_error_index)                   \
 _(serialized_nodes, SERIALIZED_NODES,                                   \
   &stat_client_main.serialized_nodes)
 
diff --git a/src/vpp/stats/stat_segment.c b/src/vpp/stats/stat_segment.c
index 16a727d..08f1d30 100644
--- a/src/vpp/stats/stat_segment.c
+++ b/src/vpp/stats/stat_segment.c
@@ -232,28 +232,28 @@
   sm->last_runtime_ptr = (scalar_data + 2);
   sm->last_runtime_stats_clear_ptr = (scalar_data + 3);
 
-  name = format (0, "vector_rate%c", 0);
+  name = format (0, "/sys/vector_rate%c", 0);
   ep = clib_mem_alloc (sizeof (*ep));
   ep->type = STAT_DIR_TYPE_SCALAR_POINTER;
   ep->value = sm->vector_rate_ptr;
 
   hash_set_mem (sm->counter_vector_by_name, name, ep);
 
-  name = format (0, "input_rate%c", 0);
+  name = format (0, "/sys/input_rate%c", 0);
   ep = clib_mem_alloc (sizeof (*ep));
   ep->type = STAT_DIR_TYPE_SCALAR_POINTER;
   ep->value = sm->input_rate_ptr;
 
   hash_set_mem (sm->counter_vector_by_name, name, ep);
 
-  name = format (0, "last_update%c", 0);
+  name = format (0, "/sys/last_update%c", 0);
   ep = clib_mem_alloc (sizeof (*ep));
   ep->type = STAT_DIR_TYPE_SCALAR_POINTER;
   ep->value = sm->last_runtime_ptr;
 
   hash_set_mem (sm->counter_vector_by_name, name, ep);
 
-  name = format (0, "last_stats_clear%c", 0);
+  name = format (0, "/sys/last_stats_clear%c", 0);
   ep = clib_mem_alloc (sizeof (*ep));
   ep->type = STAT_DIR_TYPE_SCALAR_POINTER;
   ep->value = sm->last_runtime_stats_clear_ptr;