stats: convert error counters to normal counters 40/35640/10
authorDamjan Marion <damarion@cisco.com>
Mon, 14 Mar 2022 12:04:38 +0000 (13:04 +0100)
committerFlorin Coras <florin.coras@gmail.com>
Thu, 31 Mar 2022 15:51:26 +0000 (15:51 +0000)
Change-Id: I9794da718805b40cc922e4f3cf316255398029a9
Type: improvement
Signed-off-by: Damjan Marion <damarion@cisco.com>
Signed-off-by: Ole Troan <ot@cisco.com>
13 files changed:
src/plugins/prom/prom.c
src/vlib/error.c
src/vlib/error.h
src/vlib/stats/cli.c
src/vlib/stats/shared.h
src/vlib/stats/stats.c
src/vlib/stats/stats.h
src/vlib/threads.c
src/vpp-api/client/stat_client.c
src/vpp-api/client/test.c
src/vpp-api/python/vpp_papi/vpp_stats.py
src/vpp/app/vpp_get_stats.c
src/vpp/app/vpp_prometheus_export.c

index 0b03a7a..6db5020 100644 (file)
@@ -97,26 +97,6 @@ dump_counter_vector_combined (stat_segment_data_t *res, u8 *s, u8 used_only)
   return s;
 }
 
-static u8 *
-dump_error_index (stat_segment_data_t *res, u8 *s, u8 used_only)
-{
-  u8 *name;
-  int j;
-
-  name = make_stat_name (res->name);
-
-  for (j = 0; j < vec_len (res->error_vector); j++)
-    {
-      if (used_only && !res->error_vector[j])
-       continue;
-      s = format (s, "# TYPE %v counter\n", name);
-      s =
-       format (s, "%v{thread=\"%d\"} %lld\n", name, j, res->error_vector[j]);
-    }
-
-  return s;
-}
-
 static u8 *
 dump_scalar_index (stat_segment_data_t *res, u8 *s, u8 used_only)
 {
@@ -179,9 +159,6 @@ retry:
        case STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED:
          s = dump_counter_vector_combined (&res[i], s, used_only);
          break;
-       case STAT_DIR_TYPE_ERROR_INDEX:
-         s = dump_error_index (&res[i], s, used_only);
-         break;
 
        case STAT_DIR_TYPE_SCALAR_INDEX:
          s = dump_scalar_index (&res[i], s, used_only);
index e513a7d..f01e0b6 100644 (file)
@@ -112,6 +112,17 @@ vlib_error_drop_buffers (vlib_main_t * vm,
   return n_buffers;
 }
 
+static u8 *
+format_stats_counter_name (u8 *s, va_list *va)
+{
+  u8 *id = va_arg (*va, u8 *);
+
+  for (u32 i = 0; id[i] != 0; i++)
+    vec_add1 (s, id[i] == ' ' ? ' ' : id[i]);
+
+  return s;
+}
+
 /* Reserves given number of error codes for given node. */
 void
 vlib_register_errors (vlib_main_t *vm, u32 node_index, u32 n_errors,
@@ -119,92 +130,93 @@ vlib_register_errors (vlib_main_t *vm, u32 node_index, u32 n_errors,
 {
   vlib_error_main_t *em = &vm->error_main;
   vlib_node_main_t *nm = &vm->node_main;
-
   vlib_node_t *n = vlib_get_node (vm, node_index);
+  vlib_error_desc_t *cd;
+  u32 n_threads = vlib_get_n_threads ();
+  elog_event_type_t t = {};
   uword l;
-  void *oldheap;
+  u64 **sc;
 
   ASSERT (vlib_get_thread_index () == 0);
 
+  vlib_stats_segment_lock ();
+
   /* Free up any previous error strings. */
   if (n->n_errors > 0)
-    heap_dealloc (em->counters_heap, n->error_heap_handle);
+    {
+      cd = vec_elt_at_index (em->counters_heap, n->error_heap_index);
+      for (u32 i = 0; i < n->n_errors; i++)
+       vlib_stats_remove_entry (cd[i].stats_entry_index);
+      heap_dealloc (em->counters_heap, n->error_heap_handle);
+    }
 
   n->n_errors = n_errors;
   n->error_counters = counters;
 
   if (n_errors == 0)
-    return;
+    goto done;
+
+  n->error_heap_index =
+    heap_alloc (em->counters_heap, n_errors, n->error_heap_handle);
+  l = vec_len (em->counters_heap);
+  cd = vec_elt_at_index (em->counters_heap, n->error_heap_index);
 
   /*  Legacy node */
   if (!counters)
     {
-      counters = clib_mem_alloc (sizeof (counters[0]) * n_errors);
-      int i;
-      for (i = 0; i < n_errors; i++)
+      for (int i = 0; i < n_errors; i++)
        {
-         counters[i].name = error_strings[i];
-         counters[i].desc = error_strings[i];
-         counters[i].severity = VL_COUNTER_SEVERITY_ERROR;
+         cd[i].name = error_strings[i];
+         cd[i].desc = error_strings[i];
+         cd[i].severity = VL_COUNTER_SEVERITY_ERROR;
        }
     }
-
-  n->error_heap_index =
-    heap_alloc (em->counters_heap, n_errors, n->error_heap_handle);
-  l = vec_len (em->counters_heap);
-  clib_memcpy (vec_elt_at_index (em->counters_heap, n->error_heap_index),
-              counters, n_errors * sizeof (counters[0]));
+  else
+    clib_memcpy (cd, counters, n_errors * sizeof (counters[0]));
 
   vec_validate (vm->error_elog_event_types, l - 1);
 
-  /* Switch to the stats segment ... */
-  oldheap = vlib_stats_set_heap ();
+  if (em->stats_err_entry_index == 0)
+    em->stats_err_entry_index = vlib_stats_add_counter_vector ("/node/errors");
 
-  /* Allocate a counter/elog type for each error. */
-  vec_validate (em->counters, l - 1);
+  ASSERT (em->stats_err_entry_index != 0 && em->stats_err_entry_index != ~0);
 
-  /* Zero counters for re-registrations of errors. */
-  if (n->error_heap_index + n_errors <= vec_len (em->counters_last_clear))
-    clib_memcpy (em->counters + n->error_heap_index,
-                em->counters_last_clear + n->error_heap_index,
-                n_errors * sizeof (em->counters[0]));
-  else
-    clib_memset (em->counters + n->error_heap_index,
-                0, n_errors * sizeof (em->counters[0]));
+  vlib_stats_validate (em->stats_err_entry_index, n_threads - 1, l - 1);
+  sc = vlib_stats_get_entry_data_pointer (em->stats_err_entry_index);
 
-  oldheap = clib_mem_set_heap (oldheap);
+  for (int i = 0; i < n_threads; i++)
+    {
+      vlib_main_t *tvm = vlib_get_main_by_index (i);
+      vlib_error_main_t *tem = &tvm->error_main;
+      tem->counters = sc[i];
+
+      /* Zero counters for re-registrations of errors. */
+      if (n->error_heap_index + n_errors <= vec_len (tem->counters_last_clear))
+       clib_memcpy (tem->counters + n->error_heap_index,
+                    tem->counters_last_clear + n->error_heap_index,
+                    n_errors * sizeof (tem->counters[0]));
+      else
+       clib_memset (tem->counters + n->error_heap_index, 0,
+                    n_errors * sizeof (tem->counters[0]));
+    }
 
   /* Register counter indices in the stat segment directory */
-  {
-    int i;
-
-    for (i = 0; i < n_errors; i++)
-      {
-       vlib_stats_register_error_index (em->counters, n->error_heap_index + i,
-                                        "/err/%v/%s", n->name,
-                                        counters[i].name);
-      }
-
-  }
-
-  /* (re)register the em->counters base address, switch back to main heap */
-  vlib_stats_update_error_vector (em->counters, vm->thread_index, 1);
-
-  {
-    elog_event_type_t t;
-    uword i;
-
-    clib_memset (&t, 0, sizeof (t));
-    if (n_errors > 0)
-      vec_validate (nm->node_by_error, n->error_heap_index + n_errors - 1);
-    for (i = 0; i < n_errors; i++)
-      {
-       t.format = (char *) format (0, "%v %s: %%d",
-                                   n->name, counters[i].name);
-       vm->error_elog_event_types[n->error_heap_index + i] = t;
-       nm->node_by_error[n->error_heap_index + i] = n->index;
-      }
-  }
+  for (int i = 0; i < n_errors; i++)
+    cd[i].stats_entry_index = vlib_stats_add_symlink (
+      em->stats_err_entry_index, n->error_heap_index + i, "/err/%v/%U",
+      n->name, format_stats_counter_name, cd[i].name);
+
+  vec_validate (nm->node_by_error, n->error_heap_index + n_errors - 1);
+
+  for (u32 i = 0; i < n_errors; i++)
+    {
+      t.format = (char *) format (0, "%v %s: %%d", n->name, cd[i].name);
+      vm->error_elog_event_types[n->error_heap_index + i] = t;
+      nm->node_by_error[n->error_heap_index + i] = n->index;
+    }
+
+done:
+  vlib_stats_segment_unlock ();
 }
 
 uword
index b921067..c7e7ce4 100644 (file)
@@ -56,6 +56,7 @@ typedef struct
   char *name;
   char *desc;
   enum vl_counter_severity_e severity;
+  u32 stats_entry_index;
 } vlib_error_desc_t;
 
 typedef struct
@@ -69,6 +70,9 @@ typedef struct
   /* Counter structures in heap. Heap index
      indexes counter vector. */
   vlib_error_desc_t *counters_heap;
+
+  /* stats segment entry index */
+  u32 stats_err_entry_index;
 } vlib_error_main_t;
 
 /* Per node error registration. */
index 4d7026b..94a852a 100644 (file)
@@ -34,10 +34,6 @@ format_stat_dir_entry (u8 *s, va_list *args)
       type_name = "CMainPtr";
       break;
 
-    case STAT_DIR_TYPE_ERROR_INDEX:
-      type_name = "ErrIndex";
-      break;
-
     case STAT_DIR_TYPE_NAME_VECTOR:
       type_name = "NameVector";
       break;
index d2d5d49..8e44ce3 100644 (file)
@@ -11,7 +11,6 @@ typedef enum
   STAT_DIR_TYPE_SCALAR_INDEX,
   STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE,
   STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED,
-  STAT_DIR_TYPE_ERROR_INDEX,
   STAT_DIR_TYPE_NAME_VECTOR,
   STAT_DIR_TYPE_EMPTY,
   STAT_DIR_TYPE_SYMLINK,
@@ -46,7 +45,6 @@ typedef struct
   volatile uint64_t epoch;
   volatile uint64_t in_progress;
   volatile vlib_stats_entry_t *directory_vector;
-  volatile uint64_t **error_vector;
 } vlib_stats_shared_header_t;
 
 #endif /* included_stat_segment_shared_h */
index 61f6204..9063fa3 100644 (file)
@@ -243,64 +243,6 @@ vlib_stats_add_gauge (char *fmt, ...)
   return vlib_stats_new_entry_internal (STAT_DIR_TYPE_SCALAR_INDEX, name);
 }
 
-void
-vlib_stats_register_error_index (u64 *em_vec, u64 index, char *fmt, ...)
-{
-  vlib_stats_segment_t *sm = vlib_stats_get_segment ();
-  vlib_stats_shared_header_t *shared_header = sm->shared_header;
-  vlib_stats_entry_t e = {};
-  va_list va;
-  u8 *name;
-
-  va_start (va, fmt);
-  name = va_format (0, fmt, &va);
-  va_end (va);
-
-  ASSERT (shared_header);
-
-  vlib_stats_segment_lock ();
-  u32 vector_index = vlib_stats_find_entry_index ("%v", name);
-
-  if (vector_index == STAT_SEGMENT_INDEX_INVALID)
-    {
-      vec_add1 (name, 0);
-      vlib_stats_set_entry_name (&e, (char *) name);
-      e.type = STAT_DIR_TYPE_ERROR_INDEX;
-      e.index = index;
-      vector_index = vlib_stats_create_counter (&e);
-
-      /* Warn clients to refresh any pointers they might be holding */
-      shared_header->directory_vector = sm->directory_vector;
-    }
-
-  vlib_stats_segment_unlock ();
-  vec_free (name);
-}
-
-void
-vlib_stats_update_error_vector (u64 *error_vector, u32 thread_index, int lock)
-{
-  vlib_stats_segment_t *sm = vlib_stats_get_segment ();
-  vlib_stats_shared_header_t *shared_header = sm->shared_header;
-  void *oldheap = clib_mem_set_heap (sm->heap);
-
-  ASSERT (shared_header);
-
-  if (lock)
-    vlib_stats_segment_lock ();
-
-  /* Reset the client hash table pointer, since it WILL change! */
-  vec_validate (sm->error_vector, thread_index);
-  sm->error_vector[thread_index] = error_vector;
-
-  shared_header->error_vector = sm->error_vector;
-  shared_header->directory_vector = sm->directory_vector;
-
-  if (lock)
-    vlib_stats_segment_unlock ();
-  clib_mem_set_heap (oldheap);
-}
-
 void
 vlib_stats_set_gauge (u32 index, u64 value)
 {
index 6db9371..ef43510 100644 (file)
@@ -75,7 +75,6 @@ typedef struct
   /* statistics segment */
   uword *directory_vector_by_name;
   vlib_stats_entry_t *directory_vector;
-  volatile u64 **error_vector;
   u8 **nodes;
 
   /* Update interval */
@@ -129,9 +128,6 @@ vlib_stats_get_entry_data_pointer (u32 entry_index)
 
 clib_error_t *vlib_stats_init (vlib_main_t *vm);
 void *vlib_stats_set_heap ();
-void vlib_stats_register_error_index (u64 *em_vec, u64 index, char *fmt, ...);
-void vlib_stats_update_error_vector (u64 *error_vector, u32 thread_index,
-                                    int lock);
 void vlib_stats_segment_lock (void);
 void vlib_stats_segment_unlock (void);
 void vlib_stats_register_mem_heap (clib_mem_heap_t *);
index 4dba080..b470976 100644 (file)
@@ -522,6 +522,7 @@ static clib_error_t *
 start_workers (vlib_main_t * vm)
 {
   vlib_global_main_t *vgm = vlib_get_global_main ();
+  vlib_main_t *fvm = vlib_get_first_main ();
   int i, j;
   vlib_worker_thread_t *w;
   vlib_main_t *vm_clone;
@@ -531,6 +532,7 @@ start_workers (vlib_main_t * vm)
   vlib_node_runtime_t *rt;
   u32 n_vlib_mains = tm->n_vlib_mains;
   u32 worker_thread_index;
+  u32 stats_err_entry_index = fvm->error_main.stats_err_entry_index;
   clib_mem_heap_t *main_heap = clib_mem_get_per_cpu_heap ();
   vlib_stats_register_mem_heap (main_heap);
 
@@ -600,6 +602,7 @@ start_workers (vlib_main_t * vm)
          for (k = 0; k < tr->count; k++)
            {
              vlib_node_t *n;
+             u64 **c;
 
              vec_add2 (vlib_worker_threads, w, 1);
              /* Currently unused, may not really work */
@@ -748,13 +751,10 @@ start_workers (vlib_main_t * vm)
                                CLIB_CACHE_LINE_BYTES);
 
              /* Switch to the stats segment ... */
-             void *oldheap = vlib_stats_set_heap ();
-             vm_clone->error_main.counters =
-               vec_dup_aligned (vlib_get_first_main ()->error_main.counters,
-                                CLIB_CACHE_LINE_BYTES);
-             clib_mem_set_heap (oldheap);
-             vlib_stats_update_error_vector (vm_clone->error_main.counters,
-                                             worker_thread_index, 1);
+             vlib_stats_validate (stats_err_entry_index, worker_thread_index,
+                                  vec_len (fvm->error_main.counters) - 1);
+             c = vlib_stats_get_entry_data_pointer (stats_err_entry_index);
+             vm_clone->error_main.counters = c[worker_thread_index];
 
              vm_clone->error_main.counters_last_clear = vec_dup_aligned (
                vlib_get_first_main ()->error_main.counters_last_clear,
@@ -893,6 +893,7 @@ vlib_worker_thread_node_refork (void)
   vlib_node_main_t *nm, *nm_clone;
   vlib_node_t **old_nodes_clone;
   vlib_node_runtime_t *rt, *old_rt;
+  u64 **c;
 
   vlib_node_t *new_n_clone;
 
@@ -904,25 +905,18 @@ vlib_worker_thread_node_refork (void)
   nm_clone = &vm_clone->node_main;
 
   /* Re-clone error heap */
-  u64 *old_counters = vm_clone->error_main.counters;
   u64 *old_counters_all_clear = vm_clone->error_main.counters_last_clear;
 
   clib_memcpy_fast (&vm_clone->error_main, &vm->error_main,
                    sizeof (vm->error_main));
   j = vec_len (vm->error_main.counters) - 1;
 
-  /* Switch to the stats segment ... */
-  void *oldheap = vlib_stats_set_heap ();
-  vec_validate_aligned (old_counters, j, CLIB_CACHE_LINE_BYTES);
-  clib_mem_set_heap (oldheap);
-  vm_clone->error_main.counters = old_counters;
-  vlib_stats_update_error_vector (vm_clone->error_main.counters,
-                                 vm_clone->thread_index, 0);
+  c = vlib_stats_get_entry_data_pointer (vm->error_main.stats_err_entry_index);
+  vm_clone->error_main.counters = c[vm_clone->thread_index];
 
   vec_validate_aligned (old_counters_all_clear, j, CLIB_CACHE_LINE_BYTES);
   vm_clone->error_main.counters_last_clear = old_counters_all_clear;
 
-  nm_clone = &vm_clone->node_main;
   vec_free (nm_clone->next_frames);
   nm_clone->next_frames = vec_dup_aligned (nm->next_frames,
                                           CLIB_CACHE_LINE_BYTES);
index a5eafaf..2e8e1fa 100644 (file)
@@ -231,7 +231,6 @@ copy_data (vlib_stats_entry_t *ep, u32 index2, char *name,
   int i;
   vlib_counter_t **combined_c; /* Combined counter */
   counter_t **simple_c;                /* Simple counter */
-  uint64_t *error_vector;
 
   assert (sm->shared_header);
 
@@ -271,18 +270,6 @@ copy_data (vlib_stats_entry_t *ep, u32 index2, char *name,
        }
       break;
 
-    case STAT_DIR_TYPE_ERROR_INDEX:
-      /* Gather errors from all threads into a vector */
-      error_vector =
-       stat_segment_adjust (sm, (void *) sm->shared_header->error_vector);
-      vec_validate (result.error_vector, vec_len (error_vector) - 1);
-      for (i = 0; i < vec_len (error_vector); i++)
-       {
-         counter_t *cb = stat_segment_adjust (sm, (void *) error_vector[i]);
-         result.error_vector[i] = cb[ep->index];
-       }
-      break;
-
     case STAT_DIR_TYPE_NAME_VECTOR:
       {
        uint8_t **name_vector = stat_segment_adjust (sm, ep->data);
@@ -335,9 +322,6 @@ stat_segment_data_free (stat_segment_data_t * res)
            vec_free (res[i].name_vector[j]);
          vec_free (res[i].name_vector);
          break;
-       case STAT_DIR_TYPE_ERROR_INDEX:
-         vec_free (res[i].error_vector);
-         break;
        case STAT_DIR_TYPE_SCALAR_INDEX:
        case STAT_DIR_TYPE_EMPTY:
          break;
index 9855ffa..86d6aef 100644 (file)
@@ -142,7 +142,7 @@ test_stats (void)
   assert(rv == 0);
 
   u32 *dir;
-  int i, j, k;
+  int i, k;
   stat_segment_data_t *res;
   u8 **pattern = 0;
   vec_add1(pattern, (u8 *)"/if/names");
@@ -161,11 +161,6 @@ test_stats (void)
          fformat (stdout, "[%d]: %s %s\n", k, res[i].name_vector[k],
                   res[i].name);
       break;
-    case STAT_DIR_TYPE_ERROR_INDEX:
-      for (j = 0; j < vec_len (res[i].error_vector); j++)
-       fformat (stdout, "%llu %s\n", res[i].error_vector[j],
-                res[i].name);
-      break;
     default:
       assert(0);
     }
index 3831a82..0b1c701 100755 (executable)
@@ -117,7 +117,6 @@ class VPPStats():
         self.connected = False
         self.size = 0
         self.last_epoch = 0
-        self.error_vectors = 0
         self.statseg = 0
 
     def connect(self):
@@ -173,11 +172,6 @@ class VPPStats():
         '''Get pointer of directory vector'''
         return self.shared_headerfmt.unpack_from(self.statseg)[4]
 
-    @property
-    def error_vector(self):
-        '''Get pointer of error vector'''
-        return self.shared_headerfmt.unpack_from(self.statseg)[5]
-
     elementfmt = 'IQ128s'
 
     def refresh(self, blocking=True):
@@ -195,11 +189,6 @@ class VPPStats():
                         directory_by_idx[i] = path
                     self.directory = directory
                     self.directory_by_idx = directory_by_idx
-
-                    # Cache the error index vectors
-                    self.error_vectors = []
-                    for threads in StatsVector(self, self.error_vector, 'P'):
-                        self.error_vectors.append(StatsVector(self, threads[0], 'Q'))
                     return
             except IOError:
                 if not blocking:
@@ -221,29 +210,23 @@ class VPPStats():
     def __iter__(self):
         return iter(self.directory.items())
 
+
     def set_errors(self, blocking=True):
         '''Return dictionary of error counters > 0'''
         if not self.connected:
             self.connect()
 
-        errors = {k:v for k, v in self.directory.items() if k.startswith("/err/")}
+        errors = {k: v for k, v in self.directory.items()
+                  if k.startswith("/err/")}
         result = {}
-        while True:
+        for k in errors:
             try:
-                if self.last_epoch != self.epoch:
-                    self.refresh(blocking)
-                with self.lock:
-                    for k, entry in errors.items():
-                        total = 0
-                        i = entry.value
-                        for per_thread in self.error_vectors:
-                            total += per_thread[i]
-                        if total:
-                            result[k] = total
-                    return result
-            except IOError:
-                if not blocking:
-                    raise
+                total = self[k].sum()
+                if total:
+                    result[k] = total
+            except KeyError:
+                pass
+        return result
 
     def set_errors_str(self, blocking=True):
         '''Return all errors counters > 0 pretty printed'''
@@ -258,19 +241,8 @@ class VPPStats():
         return self.__getitem__(name, blocking)
 
     def get_err_counter(self, name, blocking=True):
-        '''Return a single value (sum of all threads)'''
-        if not self.connected:
-            self.connect()
-        if name.startswith("/err/"):
-            while True:
-                try:
-                    if self.last_epoch != self.epoch:
-                        self.refresh(blocking)
-                    with self.lock:
-                        return sum(self.directory[name].get_counter(self))
-                except IOError:
-                    if not blocking:
-                        raise
+        '''Alternative call to __getitem__'''
+        return self.__getitem__(name, blocking).sum()
 
     def ls(self, patterns):
         '''Returns list of counters matching pattern'''
@@ -407,10 +379,8 @@ class StatsEntry():
         elif stattype == 3:
             self.function = self.combined
         elif stattype == 4:
-            self.function = self.error
-        elif stattype == 5:
             self.function = self.name
-        elif stattype == 7:
+        elif stattype == 6:
             self.function = self.symlink
         else:
             self.function = self.illegal
@@ -439,13 +409,6 @@ class StatsEntry():
             counter.append(clist)
         return counter
 
-    def error(self, stats):
-        '''Error counter'''
-        counter = SimpleList()
-        for clist in stats.error_vectors:
-            counter.append(clist[self.value])
-        return counter
-
     def name(self, stats):
         '''Name counter'''
         counter = []
@@ -496,12 +459,11 @@ class TestStats(unittest.TestCase):
         print('/if/rx-miss', self.stat['/if/rx-miss'])
         print('/if/rx-miss', self.stat['/if/rx-miss'][1])
         print('/nat44-ed/out2in/slowpath/drops', self.stat['/nat44-ed/out2in/slowpath/drops'])
-        print('Set Errors', self.stat.set_errors())
         with self.assertRaises(KeyError):
             print('NO SUCH COUNTER', self.stat['foobar'])
         print('/if/rx', self.stat.get_counter('/if/rx'))
-        print('/err/ethernet-input/no error',
-              self.stat.get_err_counter('/err/ethernet-input/no error'))
+        print('/err/ethernet-input/no_error',
+              self.stat.get_counter('/err/ethernet-input/no_error'))
 
     def test_column(self):
         '''Test column slicing'''
@@ -519,14 +481,6 @@ class TestStats(unittest.TestCase):
         print('/if/rx-miss if_index #1 packets', self.stat['/if/rx-miss'][:, 1].sum())
         print('/if/rx if_index #1 packets', self.stat['/if/rx'][0][1]['packets'])
 
-    def test_error(self):
-        '''Test the error vector'''
-
-        print('/err/ethernet-input', self.stat['/err/ethernet-input/no error'])
-        print('/err/nat44-ei-ha/pkts-processed', self.stat['/err/nat44-ei-ha/pkts-processed'])
-        print('/err/ethernet-input', self.stat.get_err_counter('/err/ethernet-input/no error'))
-        print('/err/ethernet-input', self.stat['/err/ethernet-input/no error'].sum())
-
     def test_nat44(self):
         '''Test the nat counters'''
 
index d13e4d9..a37dfca 100644 (file)
@@ -79,12 +79,6 @@ stat_poll_loop (u8 ** patterns)
                           res[i].name);
              break;
 
-           case STAT_DIR_TYPE_ERROR_INDEX:
-             for (j = 0; j < vec_len (res[i].error_vector); j++)
-               fformat (stdout, "%llu %s\n", res[i].error_vector[j],
-                        res[i].name);
-             break;
-
            case STAT_DIR_TYPE_SCALAR_INDEX:
              fformat (stdout, "%.2f %s\n", res[i].scalar_value, res[i].name);
              break;
@@ -217,12 +211,6 @@ reconnect:
                           res[i].name);
              break;
 
-           case STAT_DIR_TYPE_ERROR_INDEX:
-             for (j = 0; j < vec_len (res[i].error_vector); j++)
-               fformat (stdout, "[@%d] %llu %s\n", j, res[i].error_vector[j],
-                        res[i].name);
-             break;
-
            case STAT_DIR_TYPE_SCALAR_INDEX:
              fformat (stdout, "%.2f %s\n", res[i].scalar_value, res[i].name);
              break;
index e2bd952..a08adee 100644 (file)
@@ -96,16 +96,6 @@ retry:
                         res[i].combined_counter_vec[k][j].bytes);
              }
          break;
-       case STAT_DIR_TYPE_ERROR_INDEX:
-         for (j = 0; j < vec_len (res[i].error_vector); j++)
-           {
-             fformat (stream, "# TYPE %s counter\n",
-                      prom_string (res[i].name));
-             fformat (stream, "%s{thread=\"%d\"} %lld\n",
-                      prom_string (res[i].name), j, res[i].error_vector[j]);
-           }
-         break;
-
        case STAT_DIR_TYPE_SCALAR_INDEX:
          fformat (stream, "# TYPE %s counter\n", prom_string (res[i].name));
          fformat (stream, "%s %.2f\n", prom_string (res[i].name),