Add a configurable "significant error" metric

Change-Id: Idda59272a029ffcbc029f9bb167508d7bd5e6e21
Signed-off-by: Dave Barach <dave@barachs.net>
This commit is contained in:
Dave Barach
2016-03-31 15:32:54 -04:00
committed by Gerrit Code Review
parent ecec279029
commit cbed90c8cb
5 changed files with 163 additions and 16 deletions

View File

@ -70,7 +70,7 @@ static g_val_t vpp_metric_handler (int metric_index)
{ {
g_val_t val; g_val_t val;
pid_t *vpp_pidp; pid_t *vpp_pidp;
f64 *vector_ratep, *vpp_rx_ratep; f64 *vector_ratep, *vpp_rx_ratep, *sig_error_ratep;
switch (metric_index) { switch (metric_index) {
case 0: case 0:
@ -108,6 +108,16 @@ static g_val_t vpp_metric_handler (int metric_index)
val.d = 0.0; val.d = 0.0;
break; break;
case 3:
sig_error_ratep = svmdb_local_get_vec_variable
(svmdb_client, "vpp_sig_error_rate", sizeof (*vector_ratep));
if (sig_error_ratep) {
val.d = *sig_error_ratep;
vec_free (sig_error_ratep);
} else
val.d = 0.0;
break;
default: default:
val.d = 0.0; val.d = 0.0;
} }
@ -125,6 +135,10 @@ static Ganglia_25metric vpp_metric_info[] =
{0, "Input_Rate", 100, GANGLIA_VALUE_DOUBLE, "5 sec RX rate", {0, "Input_Rate", 100, GANGLIA_VALUE_DOUBLE, "5 sec RX rate",
"both", "%.1f", "both", "%.1f",
UDP_HEADER_SIZE+8, "VPP Aggregate RX Rate"}, UDP_HEADER_SIZE+8, "VPP Aggregate RX Rate"},
{0, "Sig_Error_Rate", 100, GANGLIA_VALUE_DOUBLE,
"5 sec significant error rate",
"both", "%.1f",
UDP_HEADER_SIZE+8, "VPP Significant Error Rate"},
{0, NULL} {0, NULL}
}; };

View File

@ -21,6 +21,11 @@ collection_group {
metric { metric {
name = "Input_Rate" name = "Input_Rate"
value_threshold = 10000.0 value_threshold = 10000.0
title = "VPP Aggregate RX rate" title = "VPP Aggregate RX Rate"
}
metric {
name = "Sig_Error_Rate"
value_threshold = 10.0
title = "VPP Significant Error Rate"
} }
} }

View File

@ -472,9 +472,9 @@ void svmdb_local_dump_vecs (svmdb_client_t *client)
hash_foreach_mem(key, value, h, hash_foreach_mem(key, value, h,
({ ({
svmdb_value_t *v = pool_elt_at_index (shm->values, value); svmdb_value_t *v = pool_elt_at_index (shm->values, value);
(void) fformat(stdout, "%s:\n %U\n", key, (void) fformat(stdout, "%s:\n %U (%.2f)\n", key,
format_hex_bytes, v->value, format_hex_bytes, v->value,
vec_len(v->value)*v->elsize); vec_len(v->value)*v->elsize, ((f64 *)(v->value))[0]);
})); }));
region_unlock (client->db_rp); region_unlock (client->db_rp);

View File

@ -215,12 +215,18 @@ show_errors (vlib_main_t * vm,
int verbose = 0; int verbose = 0;
u64 * sums = 0; u64 * sums = 0;
if (unformat (input, "verbose")) if (unformat (input, "verbose %d", &verbose))
;
else if (unformat (input, "verbose"))
verbose = 1; verbose = 1;
vec_validate(sums, vec_len(em->counters)); vec_validate(sums, vec_len(em->counters));
vlib_cli_output (vm, "%=16s%=40s%=20s", "Count", "Node", "Reason"); if (verbose)
vlib_cli_output (vm, "%=10s%=40s%=20s%=6s", "Count", "Node", "Reason",
"Index");
else
vlib_cli_output (vm, "%=10s%=40s%=6s", "Count", "Node", "Reason");
foreach_vlib_main(({ foreach_vlib_main(({
em = &this_vlib_main->error_main; em = &this_vlib_main->error_main;
@ -239,10 +245,15 @@ show_errors (vlib_main_t * vm,
c -= em->counters_last_clear[i]; c -= em->counters_last_clear[i];
sums[i] += c; sums[i] += c;
if (c == 0 || !verbose) if (c == 0 && verbose < 2)
continue; continue;
vlib_cli_output (vm, "%16Ld%=40v%s", c, n->name, em->error_strings_heap[i]); if (verbose)
vlib_cli_output (vm, "%10Ld%=40v%=20s%=6d", c, n->name,
em->error_strings_heap[i], i);
else
vlib_cli_output (vm, "%10d%=40v%s", c, n->name,
em->error_strings_heap[i]);
} }
} }
index++; index++;
@ -258,7 +269,11 @@ show_errors (vlib_main_t * vm,
{ {
i = n->error_heap_index + code; i = n->error_heap_index + code;
if (sums[i]) if (sums[i])
vlib_cli_output (vm, "%16Ld%=40v%s", sums[i], n->name, em->error_strings_heap[i]); {
if (verbose)
vlib_cli_output (vm, "%10Ld%=40v%=20s%=10d", sums[i], n->name,
em->error_strings_heap[i], i);
}
} }
} }

View File

@ -40,37 +40,69 @@
#include <vlib/vlib.h> #include <vlib/vlib.h>
#include <vlib/unix/unix.h> #include <vlib/unix/unix.h>
#include <vnet/api_errno.h>
#include <svmdb.h> #include <svmdb.h>
typedef struct { typedef struct {
svmdb_client_t *svmdb_client; svmdb_client_t *svmdb_client;
f64 *vector_rate_ptr; f64 *vector_rate_ptr;
f64 *input_rate_ptr; f64 *input_rate_ptr;
pid_t *vpef_pid_ptr; f64 *sig_error_rate_ptr;
vlib_main_t *vlib_main; pid_t *vpef_pid_ptr;
u64 last_sig_errors;
u64 current_sig_errors;
u64 * sig_error_bitmap;
vlib_main_t *vlib_main;
vlib_main_t ** my_vlib_mains;
} gmon_main_t; } gmon_main_t;
#if DPDK == 0 #if DPDK == 0
static inline u64 vnet_get_aggregate_rx_packets (void) static inline u64 vnet_get_aggregate_rx_packets (void)
{ return 0; } { return 0; }
#else #else
#include <vlib/vlib.h>
#include <vnet/vnet.h> #include <vnet/vnet.h>
#include <vnet/devices/dpdk/dpdk.h> #include <vnet/devices/dpdk/dpdk.h>
#endif #endif
gmon_main_t gmon_main; gmon_main_t gmon_main;
static u64 get_significant_errors(gmon_main_t * gm)
{
vlib_main_t * this_vlib_main;
vlib_error_main_t * em;
uword code;
int vm_index;
u64 significant_errors = 0;
clib_bitmap_foreach (code, gm->sig_error_bitmap,
({
for (vm_index = 0; vm_index < vec_len (gm->my_vlib_mains); vm_index++)
{
this_vlib_main = gm->my_vlib_mains[vm_index];
em = &this_vlib_main->error_main;
significant_errors += em->counters[code] -
((vec_len(em->counters_last_clear) > code) ?
em->counters_last_clear[code] : 0);
}
}));
return (significant_errors);
}
static uword static uword
gmon_process (vlib_main_t * vm, gmon_process (vlib_main_t * vm,
vlib_node_runtime_t * rt, vlib_node_runtime_t * rt,
vlib_frame_t * f) vlib_frame_t * f)
{ {
f64 vector_rate; f64 vector_rate;
u64 input_packets, last_input_packets; u64 input_packets, last_input_packets, new_sig_errors;
f64 last_runtime, dt, now; f64 last_runtime, dt, now;
gmon_main_t *gm = &gmon_main; gmon_main_t *gm = &gmon_main;
pid_t vpefpid; pid_t vpefpid;
int i;
vpefpid = getpid(); vpefpid = getpid();
*gm->vpef_pid_ptr = vpefpid; *gm->vpef_pid_ptr = vpefpid;
@ -81,6 +113,17 @@ gmon_process (vlib_main_t * vm,
last_runtime = 0.0; last_runtime = 0.0;
last_input_packets = 0; last_input_packets = 0;
/* Initial wait for the world to settle down */
vlib_process_suspend (vm, 5.0);
if (vec_len(vlib_mains) == 0)
vec_add1(gm->my_vlib_mains, &vlib_global_main);
else
{
for (i = 0; i < vec_len(vlib_mains); i++)
vec_add1 (gm->my_vlib_mains, vlib_mains[i]);
}
while (1) { while (1) {
vlib_process_suspend (vm, 5.0); vlib_process_suspend (vm, 5.0);
vector_rate = vlib_last_vector_length_per_node (vm); vector_rate = vlib_last_vector_length_per_node (vm);
@ -91,6 +134,11 @@ gmon_process (vlib_main_t * vm,
*gm->input_rate_ptr = (f64)(input_packets - last_input_packets) / dt; *gm->input_rate_ptr = (f64)(input_packets - last_input_packets) / dt;
last_runtime = now; last_runtime = now;
last_input_packets = input_packets; last_input_packets = input_packets;
new_sig_errors = get_significant_errors(gm);
*gm->sig_error_rate_ptr =
((f64)(new_sig_errors - gm->last_sig_errors)) / dt;
gm->last_sig_errors = new_sig_errors;
} }
return 0; /* not so much */ return 0; /* not so much */
@ -124,6 +172,11 @@ gmon_init (vlib_main_t *vm)
"vpp_input_rate", "vpp_input_rate",
(char *)v, sizeof (*v)); (char *)v, sizeof (*v));
vec_free(v); vec_free(v);
vec_add1 (v, 0.0);
svmdb_local_set_vec_variable(gm->svmdb_client,
"vpp_sig_error_rate",
(char *)v, sizeof (*v));
vec_free(v);
vec_add1 (swp, 0.0); vec_add1 (swp, 0.0);
svmdb_local_set_vec_variable(gm->svmdb_client, svmdb_local_set_vec_variable(gm->svmdb_client,
@ -131,7 +184,7 @@ gmon_init (vlib_main_t *vm)
(char *)swp, sizeof (*swp)); (char *)swp, sizeof (*swp));
vec_free(swp); vec_free(swp);
/* the value cell will never move, so acquire a reference to it */ /* the value cells will never move, so acquire references to them */
gm->vector_rate_ptr = gm->vector_rate_ptr =
svmdb_local_get_variable_reference (gm->svmdb_client, svmdb_local_get_variable_reference (gm->svmdb_client,
SVMDB_NAMESPACE_VEC, SVMDB_NAMESPACE_VEC,
@ -140,6 +193,10 @@ gmon_init (vlib_main_t *vm)
svmdb_local_get_variable_reference (gm->svmdb_client, svmdb_local_get_variable_reference (gm->svmdb_client,
SVMDB_NAMESPACE_VEC, SVMDB_NAMESPACE_VEC,
"vpp_input_rate"); "vpp_input_rate");
gm->sig_error_rate_ptr =
svmdb_local_get_variable_reference (gm->svmdb_client,
SVMDB_NAMESPACE_VEC,
"vpp_sig_error_rate");
gm->vpef_pid_ptr = gm->vpef_pid_ptr =
svmdb_local_get_variable_reference (gm->svmdb_client, svmdb_local_get_variable_reference (gm->svmdb_client,
SVMDB_NAMESPACE_VEC, SVMDB_NAMESPACE_VEC,
@ -157,8 +214,64 @@ static clib_error_t *gmon_exit (vlib_main_t *vm)
*gm->vector_rate_ptr = 0.0; *gm->vector_rate_ptr = 0.0;
*gm->vpef_pid_ptr = 0; *gm->vpef_pid_ptr = 0;
*gm->input_rate_ptr = 0.0; *gm->input_rate_ptr = 0.0;
*gm->sig_error_rate_ptr = 0.0;
svmdb_unmap (gm->svmdb_client); svmdb_unmap (gm->svmdb_client);
} }
return 0; return 0;
} }
VLIB_MAIN_LOOP_EXIT_FUNCTION (gmon_exit); VLIB_MAIN_LOOP_EXIT_FUNCTION (gmon_exit);
static int
significant_error_enable_disable (gmon_main_t * gm,
u32 index, int enable)
{
vlib_main_t * vm = gm->vlib_main;
vlib_error_main_t * em = &vm->error_main;
if (index >= vec_len (em->counters))
return VNET_API_ERROR_NO_SUCH_ENTRY;
gm->sig_error_bitmap = clib_bitmap_set (gm->sig_error_bitmap, index, enable);
return 0;
}
static clib_error_t *
set_significant_error_command_fn (vlib_main_t * vm,
unformat_input_t * input,
vlib_cli_command_t * cmd)
{
u32 index;
int enable = 1;
int rv;
gmon_main_t *gm = &gmon_main;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
if (unformat (input, "%d", &index))
;
else if (unformat (input, "disable"))
enable = 0;
else
return clib_error_return (0, "unknown input `%U'",
format_unformat_error, input);
}
rv = significant_error_enable_disable (gm, index, enable);
switch (rv)
{
case 0:
break;
default:
return clib_error_return
(0, "significant_error_enable_disable returned %d", rv);
}
return 0;
}
VLIB_CLI_COMMAND (set_significant_error_command, static) = {
.path = "set significant error",
.short_help = "set significant error <counter-index-nnn>",
.function = set_significant_error_command_fn,
};