laforge has submitted this change. ( https://gerrit.osmocom.org/c/libosmocore/+/27822 )
Change subject: vty: Add a 'skip-zero' version of 'show stats' and 'show rate-counters' ......................................................................
vty: Add a 'skip-zero' version of 'show stats' and 'show rate-counters'
In many cases, a lot of the counters are zero, and we're likely not interested in those, but only the non-zero counters. Add a version of the 'show stats' command which dumps only those items with a non-zero total value.
Change-Id: Ie4df1c139e3c82deca1dd3cdab5d3909e0513684 --- M include/osmocom/vty/misc.h M src/vty/stats_vty.c M src/vty/utils.c 3 files changed, 102 insertions(+), 34 deletions(-)
Approvals: fixeria: Looks good to me, approved pespin: Looks good to me, but someone else must approve Jenkins Builder: Verified
diff --git a/include/osmocom/vty/misc.h b/include/osmocom/vty/misc.h index ea31c5b..f031c4a 100644 --- a/include/osmocom/vty/misc.h +++ b/include/osmocom/vty/misc.h @@ -14,15 +14,23 @@
void vty_out_rate_ctr_group(struct vty *vty, const char *prefix, struct rate_ctr_group *ctrg); +void vty_out_rate_ctr_group2(struct vty *vty, const char *prefix, + struct rate_ctr_group *ctrg, bool skip_zero); void vty_out_rate_ctr_group_fmt(struct vty *vty, const char *fmt, struct rate_ctr_group *ctrg); +void vty_out_rate_ctr_group_fmt2(struct vty *vty, const char *fmt, + struct rate_ctr_group *ctrg, bool skip_zero); +
void vty_out_stat_item_group(struct vty *vty, const char *prefix, struct osmo_stat_item_group *statg); +void vty_out_stat_item_group2(struct vty *vty, const char *prefix, + struct osmo_stat_item_group *statg, bool skip_zero);
void vty_out_statistics_full(struct vty *vty, const char *prefix); -void vty_out_statistics_partial(struct vty *vty, const char *prefix, - int max_level); +void vty_out_statistics_full2(struct vty *vty, const char *prefix, bool skip_zero); +void vty_out_statistics_partial(struct vty *vty, const char *prefix, int max_level); +void vty_out_statistics_partial2(struct vty *vty, const char *prefix, int max_level, bool skip_zero);
struct osmo_fsm; diff --git a/src/vty/stats_vty.c b/src/vty/stats_vty.c index a73fafb..a4e4fce 100644 --- a/src/vty/stats_vty.c +++ b/src/vty/stats_vty.c @@ -1,5 +1,5 @@ /* - * (C) 2009-2010 by Harald Welte laforge@gnumonks.org + * (C) 2009-2022 by Harald Welte laforge@gnumonks.org * (C) 2009-2014 by Holger Hans Peter Freyther * (C) 2015 by sysmocom - s.f.m.c. GmbH * All Rights Reserved @@ -39,6 +39,7 @@ #define CFG_REPORTER_STR "Configure a stats reporter\n"
#define SHOW_STATS_STR "Show statistical values\n" +#define SKIP_ZERO_STR "Skip items with total count zero\n"
#define STATS_STR "Stats related commands\n"
@@ -418,25 +419,32 @@
DEFUN(show_stats, show_stats_cmd, - "show stats", - SHOW_STR SHOW_STATS_STR) + "show stats [skip-zero]", + SHOW_STR SHOW_STATS_STR SKIP_ZERO_STR) { - vty_out_statistics_full(vty, ""); + bool skip_zero = false; + if (argc > 0) + skip_zero = true; + + vty_out_statistics_full2(vty, "", skip_zero);
return CMD_SUCCESS; }
DEFUN(show_stats_level, show_stats_level_cmd, - "show stats level (global|peer|subscriber)", + "show stats level (global|peer|subscriber) [skip-zero]", SHOW_STR SHOW_STATS_STR "Set the maximum group level\n" "Show global groups only\n" "Show global and network peer related groups\n" - "Show global, peer, and subscriber groups\n") + "Show global, peer, and subscriber groups\n" SKIP_ZERO_STR) { int level = get_string_value(stats_class_strs, argv[0]); - vty_out_statistics_partial(vty, "", level); + bool skip_zero = false; + if (argc > 1) + skip_zero = true; + vty_out_statistics_partial2(vty, "", level, skip_zero);
return CMD_SUCCESS; } @@ -599,23 +607,32 @@ return CMD_SUCCESS; }
+struct rctr_vty_ctx { + struct vty *vty; + bool skip_zero; +}; + static int rate_ctr_group_handler(struct rate_ctr_group *ctrg, void *sctx_) { - struct vty *vty = sctx_; + struct rctr_vty_ctx *sctx = sctx_; + struct vty *vty = sctx->vty; vty_out(vty, "%s %u", ctrg->desc->group_description, ctrg->idx); if (ctrg->name != NULL) vty_out(vty, " (%s)", ctrg->name); vty_out(vty, ":%s", VTY_NEWLINE); - vty_out_rate_ctr_group_fmt(vty, "%25n: %10c (%S/s %M/m %H/h %D/d) %d", ctrg); + vty_out_rate_ctr_group_fmt2(vty, "%25n: %10c (%S/s %M/m %H/h %D/d) %d", ctrg, sctx->skip_zero); return 0; }
DEFUN(show_rate_counters, show_rate_counters_cmd, - "show rate-counters", - SHOW_STR "Show all rate counters\n") + "show rate-counters [skip-zero]", + SHOW_STR "Show all rate counters\n" SKIP_ZERO_STR) { - rate_ctr_for_each_group(rate_ctr_group_handler, vty); + struct rctr_vty_ctx rctx = { .vty = vty, .skip_zero = false }; + if (argc > 0) + rctx.skip_zero = true; + rate_ctr_for_each_group(rate_ctr_group_handler, &rctx); return CMD_SUCCESS; }
diff --git a/src/vty/utils.c b/src/vty/utils.c index 696a519..a651515 100644 --- a/src/vty/utils.c +++ b/src/vty/utils.c @@ -21,6 +21,7 @@ */
#include <stdint.h> +#include <stdbool.h> #include <inttypes.h> #include <string.h> #include <ctype.h> @@ -44,6 +45,7 @@ struct vty *vty; const char *prefix; int max_level; + bool skip_zero; };
static int rate_ctr_handler( @@ -53,6 +55,9 @@ struct vty_out_context *vctx = vctx_; struct vty *vty = vctx->vty;
+ if (vctx->skip_zero && ctr->current == 0) + return 0; + vty_out(vty, " %s%s: %8" PRIu64 " " "(%" PRIu64 "/s %" PRIu64 "/m %" PRIu64 "/h %" PRIu64 "/d)%s", vctx->prefix, desc->description, ctr->current, @@ -69,17 +74,24 @@ * \param[in] vty The VTY to which it should be printed * \param[in] prefix Any additional log prefix ahead of each line * \param[in] ctrg Rate counter group to be printed + * \param[in] skip_zero Skip all zero-valued counters */ -void vty_out_rate_ctr_group(struct vty *vty, const char *prefix, - struct rate_ctr_group *ctrg) +void vty_out_rate_ctr_group2(struct vty *vty, const char *prefix, + struct rate_ctr_group *ctrg, bool skip_zero) { - struct vty_out_context vctx = {vty, prefix}; + struct vty_out_context vctx = {vty, prefix, 0, skip_zero};
vty_out(vty, "%s%s:%s", prefix, ctrg->desc->group_description, VTY_NEWLINE);
rate_ctr_for_each_counter(ctrg, rate_ctr_handler, &vctx); }
+void vty_out_rate_ctr_group(struct vty *vty, const char *prefix, + struct rate_ctr_group *ctrg) +{ + vty_out_rate_ctr_group2(vty, prefix, ctrg, false); +} + static char * pad_append_str(char *s, const char *a, int minwidth) { @@ -103,7 +115,12 @@ struct vty_out_context *vctx = vctx_; struct vty *vty = vctx->vty; const char *fmt = vctx->prefix; - char *s = talloc_strdup(vty, ""); + char *s; + + if (vctx->skip_zero && ctr->current == 0) + return 0; + + s = talloc_strdup(vty, ""); OSMO_ASSERT(s);
while (*fmt) { @@ -205,14 +222,20 @@ * \param[in] vty The VTY to which it should be printed * \param[in] ctrg Rate counter group to be printed * \param[in] fmt A format which may contain the above directives. + * \param[in] skip_zero Skip all zero-valued counters */ -void vty_out_rate_ctr_group_fmt(struct vty *vty, const char *fmt, - struct rate_ctr_group *ctrg) +void vty_out_rate_ctr_group_fmt2(struct vty *vty, const char *fmt, + struct rate_ctr_group *ctrg, bool skip_zero) { - struct vty_out_context vctx = {vty, fmt}; + struct vty_out_context vctx = {vty, fmt, 0, skip_zero}; rate_ctr_for_each_counter(ctrg, rate_ctr_handler_fmt, &vctx); }
+void vty_out_rate_ctr_group_fmt(struct vty *vty, const char *fmt, + struct rate_ctr_group *ctrg) +{ + vty_out_rate_ctr_group_fmt2(vty, fmt, ctrg, false); +} static int rate_ctr_group_handler(struct rate_ctr_group *ctrg, void *vctx_) { struct vty_out_context *vctx = vctx_; @@ -244,12 +267,14 @@ struct vty_out_context *vctx = vctx_; struct vty *vty = vctx->vty; const struct osmo_stat_item_desc *desc = osmo_stat_item_get_desc(item); + int32_t value = osmo_stat_item_get_last(item); const char *unit = (desc->unit != OSMO_STAT_ITEM_NO_UNIT) ? desc->unit : "";
+ if (vctx->skip_zero && value == 0) + return 0; + vty_out(vty, " %s%s: %8" PRIi32 " %s%s", - vctx->prefix, desc->description, - osmo_stat_item_get_last(item), - unit, VTY_NEWLINE); + vctx->prefix, desc->description, value, unit, VTY_NEWLINE);
return 0; } @@ -258,17 +283,24 @@ * \param[in] vty The VTY to which it should be printed * \param[in] prefix Any additional log prefix ahead of each line * \param[in] statg Stat item group to be printed + * \param[in] skip_zero Skip all zero-valued counters */ -void vty_out_stat_item_group(struct vty *vty, const char *prefix, - struct osmo_stat_item_group *statg) +void vty_out_stat_item_group2(struct vty *vty, const char *prefix, + struct osmo_stat_item_group *statg, bool skip_zero) { - struct vty_out_context vctx = {vty, prefix}; + struct vty_out_context vctx = {vty, prefix, 0, skip_zero};
vty_out(vty, "%s%s:%s", prefix, statg->desc->group_description, VTY_NEWLINE); osmo_stat_item_for_each_item(statg, osmo_stat_item_handler, &vctx); }
+void vty_out_stat_item_group(struct vty *vty, const char *prefix, + struct osmo_stat_item_group *statg) +{ + return vty_out_stat_item_group2(vty, prefix, statg, false); +} + static int osmo_stat_item_group_handler(struct osmo_stat_item_group *statg, void *vctx_) { struct vty_out_context *vctx = vctx_; @@ -298,21 +330,22 @@ struct vty_out_context *vctx = vctx_; struct vty *vty = vctx->vty; const char *description = counter->description; + unsigned long value = osmo_counter_get(counter); + + if (vctx->skip_zero && value == 0) + return 0;
if (!counter->description) description = counter->name;
- vty_out(vty, " %s%s: %8lu%s", - vctx->prefix, description, - osmo_counter_get(counter), VTY_NEWLINE); + vty_out(vty, " %s%s: %8lu%s", vctx->prefix, description, value, VTY_NEWLINE);
return 0; }
-void vty_out_statistics_partial(struct vty *vty, const char *prefix, - int max_level) +void vty_out_statistics_partial2(struct vty *vty, const char *prefix, int max_level, bool skip_zero) { - struct vty_out_context vctx = {vty, prefix, max_level}; + struct vty_out_context vctx = {vty, prefix, max_level, skip_zero};
vty_out(vty, "%sUngrouped counters:%s", prefix, VTY_NEWLINE); osmo_counters_for_each(handle_counter, &vctx); @@ -320,9 +353,19 @@ osmo_stat_item_for_each_group(osmo_stat_item_group_handler, &vctx); }
+void vty_out_statistics_partial(struct vty *vty, const char *prefix, int max_level) +{ + return vty_out_statistics_partial2(vty, prefix, max_level, false); +} + +void vty_out_statistics_full2(struct vty *vty, const char *prefix, bool skip_zero) +{ + vty_out_statistics_partial2(vty, prefix, INT_MAX, skip_zero); +} + void vty_out_statistics_full(struct vty *vty, const char *prefix) { - vty_out_statistics_partial(vty, prefix, INT_MAX); + vty_out_statistics_full2(vty, prefix, false); }
/*! Generate a VTY command string from value_string */