Browse Source

TT#101150 generalise ng command stats into array/list

Change-Id: I43c7074237ae70d9bcb12b4946ce2c751d135bc8
pull/1373/head
Richard Fuchs 4 years ago
parent
commit
3fa16c6ab1
7 changed files with 3414 additions and 206 deletions
  1. +2
    -17
      daemon/control_ng.c
  2. +20
    -34
      daemon/graphite.c
  3. +27
    -43
      daemon/statistics.c
  4. +1
    -3
      include/counter_stats_fields.inc
  5. +2
    -3
      include/gauge_stats_fields.inc
  6. +26
    -4
      include/statistics.h
  7. +3336
    -102
      t/test-stats.c

+ 2
- 17
daemon/control_ng.c View File

@ -323,23 +323,8 @@ int control_ng_process(str *buf, const endpoint_t *sin, char *addr,
bencode_dictionary_add_string(resp, "result", resultstr);
// update interval statistics
// XXX could generalise these, same as above
switch (command) {
case NGC_OFFER:
RTPE_STATS_INC(offers);
RTPE_GAUGE_SET(offer_time, timeval_us(&cmd_process_time));
break;
case NGC_ANSWER:
RTPE_STATS_INC(answers);
RTPE_GAUGE_SET(answer_time, timeval_us(&cmd_process_time));
break;
case NGC_DELETE:
RTPE_STATS_INC(deletes);
RTPE_GAUGE_SET(delete_time, timeval_us(&cmd_process_time));
break;
default:
break;
}
RTPE_STATS_INC(ng_commands[command]);
RTPE_GAUGE_SET(ng_command_times[command], timeval_us(&cmd_process_time));
goto send_resp;


+ 20
- 34
daemon/graphite.c View File

@ -116,17 +116,14 @@ GString *print_graphite_data(struct totalstats *sent_data) {
g_string_append(graph_str, graphite_prefix); \
g_string_append_printf(graph_str, fmt " %llu\n", ##__VA_ARGS__, (unsigned long long)rtpe_now.tv_sec)
GPF("offer_time_min %.6f", (double) atomic64_get_na(&rtpe_stats_gauge_graphite_min_max_interval.min.offer_time) / 1000000.0);
GPF("offer_time_max %.6f", (double) atomic64_get_na(&rtpe_stats_gauge_graphite_min_max_interval.max.offer_time) / 1000000.0);
GPF("offer_time_avg %.6f", (double) atomic64_get_na(&rtpe_stats_gauge_graphite_min_max_interval.avg.offer_time) / 1000000.0);
GPF("answer_time_min %.6f", (double) atomic64_get_na(&rtpe_stats_gauge_graphite_min_max_interval.min.answer_time) / 1000000.0);
GPF("answer_time_max %.6f", (double) atomic64_get_na(&rtpe_stats_gauge_graphite_min_max_interval.max.answer_time) / 1000000.0);
GPF("answer_time_avg %.6f", (double) atomic64_get_na(&rtpe_stats_gauge_graphite_min_max_interval.avg.answer_time) / 1000000.0);
GPF("delete_time_min %.6f", (double) atomic64_get_na(&rtpe_stats_gauge_graphite_min_max_interval.min.delete_time) / 1000000.0);
GPF("delete_time_max %.6f", (double) atomic64_get_na(&rtpe_stats_gauge_graphite_min_max_interval.max.delete_time) / 1000000.0);
GPF("delete_time_avg %.6f", (double) atomic64_get_na(&rtpe_stats_gauge_graphite_min_max_interval.avg.delete_time) / 1000000.0);
for (int i = 0; i < NGC_COUNT; i++) {
GPF("%s_time_min %.6f", ng_command_strings[i],
(double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.min.ng_command_times[i]) / 1000000.0);
GPF("%s_time_max %.6f", ng_command_strings[i],
(double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.max.ng_command_times[i]) / 1000000.0);
GPF("%s_time_avg %.6f", ng_command_strings[i],
(double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.avg.ng_command_times[i]) / 1000000.0);
}
GPF("call_dur %llu.%06llu",(unsigned long long)ts->total_calls_duration_interval.tv_sec,(unsigned long long)ts->total_calls_duration_interval.tv_usec);
GPF("average_call_dur %llu.%06llu",(unsigned long long)ts->total_average_call_dur.tv_sec,(unsigned long long)ts->total_average_call_dur.tv_usec);
@ -152,17 +149,11 @@ GString *print_graphite_data(struct totalstats *sent_data) {
GPF("timeout_sess "UINT64F, atomic64_get_na(&rtpe_stats_graphite_interval.timeout_sess));
GPF("reject_sess "UINT64F, atomic64_get_na(&rtpe_stats_graphite_interval.rejected_sess));
GPF("offers_ps_min " UINT64F, atomic64_get_na(&rtpe_stats_graphite_min_max_interval.min.offers));
GPF("offers_ps_max " UINT64F, atomic64_get_na(&rtpe_stats_graphite_min_max_interval.max.offers));
GPF("offers_ps_avg " UINT64F, atomic64_get_na(&rtpe_stats_graphite_min_max_interval.avg.offers));
GPF("answers_ps_min " UINT64F, atomic64_get_na(&rtpe_stats_graphite_min_max_interval.min.answers));
GPF("answers_ps_max " UINT64F, atomic64_get_na(&rtpe_stats_graphite_min_max_interval.max.answers));
GPF("answers_ps_avg " UINT64F, atomic64_get_na(&rtpe_stats_graphite_min_max_interval.avg.answers));
GPF("deletes_ps_min " UINT64F, atomic64_get_na(&rtpe_stats_graphite_min_max_interval.min.deletes));
GPF("deletes_ps_max " UINT64F, atomic64_get_na(&rtpe_stats_graphite_min_max_interval.max.deletes));
GPF("deletes_ps_avg " UINT64F, atomic64_get_na(&rtpe_stats_graphite_min_max_interval.avg.deletes));
for (int i = 0; i < NGC_COUNT; i++) {
GPF("%ss_ps_min " UINT64F, ng_command_strings[i], atomic64_get(&rtpe_stats_graphite_min_max_interval.min.ng_commands[i]));
GPF("%ss_ps_max " UINT64F, ng_command_strings[i], atomic64_get(&rtpe_stats_graphite_min_max_interval.max.ng_commands[i]));
GPF("%ss_ps_avg " UINT64F, ng_command_strings[i], atomic64_get(&rtpe_stats_graphite_min_max_interval.avg.ng_commands[i]));
}
for (GList *l = all_local_interfaces.head; l; l = l->next) {
struct local_intf *lif = l->data;
@ -210,18 +201,13 @@ GString *print_graphite_data(struct totalstats *sent_data) {
(unsigned long long ) ts->total_calls_duration_interval.tv_usec,
(unsigned long long ) rtpe_now.tv_sec);
ilog(LOG_DEBUG, "Min/Max/Avg offer processing delay: %.6f/%.6f/%.6f sec",
(double) atomic64_get_na(&rtpe_stats_gauge_graphite_min_max_interval.min.offer_time) / 1000000.0,
(double) atomic64_get_na(&rtpe_stats_gauge_graphite_min_max_interval.max.offer_time) / 1000000.0,
(double) atomic64_get_na(&rtpe_stats_gauge_graphite_min_max_interval.avg.offer_time) / 1000000.0);
ilog(LOG_DEBUG, "Min/Max/Avg answer processing delay: %.6f/%.6f/%.6f sec",
(double) atomic64_get_na(&rtpe_stats_gauge_graphite_min_max_interval.min.answer_time) / 1000000.0,
(double) atomic64_get_na(&rtpe_stats_gauge_graphite_min_max_interval.max.answer_time) / 1000000.0,
(double) atomic64_get_na(&rtpe_stats_gauge_graphite_min_max_interval.avg.answer_time) / 1000000.0);
ilog(LOG_DEBUG, "Min/Max/Avg delete processing delay: %.6f/%.6f/%.6f sec",
(double) atomic64_get_na(&rtpe_stats_gauge_graphite_min_max_interval.min.delete_time) / 1000000.0,
(double) atomic64_get_na(&rtpe_stats_gauge_graphite_min_max_interval.max.delete_time) / 1000000.0,
(double) atomic64_get_na(&rtpe_stats_gauge_graphite_min_max_interval.avg.delete_time) / 1000000.0);
for (int i = 0; i < NGC_COUNT; i++) {
ilog(LOG_DEBUG, "Min/Max/Avg %s processing delay: %.6f/%.6f/%.6f sec",
ng_command_strings[i],
(double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.min.ng_command_times[i]) / 1000000.0,
(double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.max.ng_command_times[i]) / 1000000.0,
(double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.avg.ng_command_times[i]) / 1000000.0);
}
return graph_str;
}


+ 27
- 43
daemon/statistics.c View File

@ -516,49 +516,33 @@ GQueue *statistics_gather_metrics(void) {
METRIC("minmanagedsessions", "Min managed sessions", UINT64F, UINT64F, min_sess_iv);
METRIC("maxmanagedsessions", "Max managed sessions", UINT64F, UINT64F, max_sess_iv);
METRICl("Min/Max/Avg offer processing delay", "%.6f/%.6f/%.6f sec",
(double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.min.offer_time) / 1000000.0,
(double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.max.offer_time) / 1000000.0,
(double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.avg.offer_time) / 1000000.0);
METRICsva("minofferdelay", "%.6f", (double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.min.offer_time) / 1000000.0);
METRICsva("maxofferdelay", "%.6f", (double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.max.offer_time) / 1000000.0);
METRICsva("avgofferdelay", "%.6f", (double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.avg.offer_time) / 1000000.0);
METRICl("Min/Max/Avg answer processing delay", "%.6f/%.6f/%.6f sec",
(double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.min.answer_time) / 1000000.0,
(double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.max.answer_time) / 1000000.0,
(double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.avg.answer_time) / 1000000.0);
METRICsva("minanswerdelay", "%.6f", (double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.min.answer_time) / 1000000.0);
METRICsva("maxanswerdelay", "%.6f", (double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.max.answer_time) / 1000000.0);
METRICsva("avganswerdelay", "%.6f", (double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.avg.answer_time) / 1000000.0);
METRICl("Min/Max/Avg delete processing delay", "%.6f/%.6f/%.6f sec",
(double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.min.delete_time) / 1000000.0,
(double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.max.delete_time) / 1000000.0,
(double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.avg.delete_time) / 1000000.0);
METRICsva("mindeletedelay", "%.6f", (double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.min.delete_time) / 1000000.0);
METRICsva("maxdeletedelay", "%.6f", (double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.max.delete_time) / 1000000.0);
METRICsva("avgdeletedelay", "%.6f", (double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.avg.delete_time) / 1000000.0);
METRICl("Min/Max/Avg offer requests per second", "%llu/%llu/%llu per sec",
(unsigned long long) atomic64_get(&rtpe_stats_graphite_min_max_interval.min.offers),
(unsigned long long) atomic64_get(&rtpe_stats_graphite_min_max_interval.max.offers),
(unsigned long long) atomic64_get(&rtpe_stats_graphite_min_max_interval.avg.offers));
METRICs("minofferrequestrate", "%llu", (unsigned long long) atomic64_get(&rtpe_stats_graphite_min_max_interval.min.offers));
METRICs("maxofferrequestrate", "%llu", (unsigned long long) atomic64_get(&rtpe_stats_graphite_min_max_interval.max.offers));
METRICs("avgofferrequestrate", "%llu", (unsigned long long) atomic64_get(&rtpe_stats_graphite_min_max_interval.avg.offers));
METRICl("Min/Max/Avg answer requests per second", "%llu/%llu/%llu per sec",
(unsigned long long) atomic64_get(&rtpe_stats_graphite_min_max_interval.min.answers),
(unsigned long long) atomic64_get(&rtpe_stats_graphite_min_max_interval.max.answers),
(unsigned long long) atomic64_get(&rtpe_stats_graphite_min_max_interval.avg.answers));
METRICs("minanswerrequestrate", "%llu", (unsigned long long) atomic64_get(&rtpe_stats_graphite_min_max_interval.min.answers));
METRICs("maxanswerrequestrate", "%llu", (unsigned long long) atomic64_get(&rtpe_stats_graphite_min_max_interval.max.answers));
METRICs("avganswerrequestrate", "%llu", (unsigned long long) atomic64_get(&rtpe_stats_graphite_min_max_interval.avg.answers));
METRICl("Min/Max/Avg delete requests per second", "%llu/%llu/%llu per sec",
(unsigned long long) atomic64_get(&rtpe_stats_graphite_min_max_interval.min.deletes),
(unsigned long long) atomic64_get(&rtpe_stats_graphite_min_max_interval.max.deletes),
(unsigned long long) atomic64_get(&rtpe_stats_graphite_min_max_interval.avg.deletes));
METRICs("mindeleterequestrate", "%llu", (unsigned long long) atomic64_get(&rtpe_stats_graphite_min_max_interval.min.deletes));
METRICs("maxdeleterequestrate", "%llu", (unsigned long long) atomic64_get(&rtpe_stats_graphite_min_max_interval.max.deletes));
METRICs("avgdeleterequestrate", "%llu", (unsigned long long) atomic64_get(&rtpe_stats_graphite_min_max_interval.avg.deletes));
for (int i = 0; i < NGC_COUNT; i++) {
double min = (double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.min.ng_command_times[i]) / 1000000.0;
double max = (double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.max.ng_command_times[i]) / 1000000.0;
double avg = (double) atomic64_get(&rtpe_stats_gauge_graphite_min_max_interval.avg.ng_command_times[i]) / 1000000.0;
AUTO_CLEANUP(char *min_label, free_gbuf) = g_strdup_printf("min%sdelay", ng_command_strings[i]);
AUTO_CLEANUP(char *max_label, free_gbuf) = g_strdup_printf("max%sdelay", ng_command_strings[i]);
AUTO_CLEANUP(char *avg_label, free_gbuf) = g_strdup_printf("avg%sdelay", ng_command_strings[i]);
AUTO_CLEANUP(char *long_label, free_gbuf) = g_strdup_printf("Min/Max/Avg %s processing delay", ng_command_strings[i]);
METRICl(long_label, "%.6f/%.6f/%.6f sec", min, max, avg);
METRICsva(min_label, "%.6f", min);
METRICsva(max_label, "%.6f", max);
METRICsva(avg_label, "%.6f", avg);
}
for (int i = 0; i < NGC_COUNT; i++) {
uint64_t min = atomic64_get(&rtpe_stats_graphite_min_max_interval.min.ng_commands[i]);
uint64_t max = atomic64_get(&rtpe_stats_graphite_min_max_interval.max.ng_commands[i]);
uint64_t avg = atomic64_get(&rtpe_stats_graphite_min_max_interval.avg.ng_commands[i]);
AUTO_CLEANUP(char *min_label, free_gbuf) = g_strdup_printf("min%srequestrate", ng_command_strings[i]);
AUTO_CLEANUP(char *max_label, free_gbuf) = g_strdup_printf("max%srequestrate", ng_command_strings[i]);
AUTO_CLEANUP(char *avg_label, free_gbuf) = g_strdup_printf("avg%srequestrate", ng_command_strings[i]);
AUTO_CLEANUP(char *long_label, free_gbuf) = g_strdup_printf("Min/Max/Avg %s requests per second", ng_command_strings[i]);
METRICl(long_label, "%" PRIu64 "/%" PRIu64 "/%" PRIu64 " per sec", min, max, avg);
METRICsva(min_label, "%" PRIu64 "", min);
METRICsva(max_label, "%" PRIu64 "", max);
METRICsva(avg_label, "%" PRIu64 "", avg);
}
HEADER(NULL, "");
HEADER("}", "");


+ 1
- 3
include/counter_stats_fields.inc View File

@ -1,9 +1,7 @@
F(packets)
F(bytes)
F(errors)
F(offers)
F(answers)
F(deletes)
FA(ng_commands, NGC_COUNT)
F(timeout_sess)
F(foreign_sess)
F(rejected_sess)


+ 2
- 3
include/gauge_stats_fields.inc View File

@ -1,8 +1,7 @@
F(total_sessions)
F(foreign_sessions)
F(transcoded_media)
F(ipv4_sessions)
F(ipv6_sessions)
F(mixed_sessions)
F(offer_time)
F(answer_time)
F(delete_time)
FdA(ng_command_times, NGC_COUNT)

+ 26
- 4
include/statistics.h View File

@ -4,6 +4,7 @@
#include "aux.h"
#include "bencode.h"
#include "rtpengine_config.h"
#include "control_ng.h"
struct call;
struct packet_stream;
@ -21,9 +22,16 @@ struct stream_stats {
// "gauge" style stats
struct global_stats_gauge {
// F(x) : real gauge that has a continuous value
// Fd(x) : gauge that receives values in discreet samples
// FA(x, n) / FdA(x, n) : array of the above
#define F(x) atomic64 x;
#define Fd(x) F(x)
#define FA(x, n) atomic64 x[n];
#define FdA(x, n) FA(x, n)
#include "gauge_stats_fields.inc"
#undef F
#undef FA
};
struct global_stats_gauge_min_max {
@ -36,8 +44,10 @@ struct global_stats_gauge_min_max {
// "counter" style stats that are incremental and are kept cumulative or per-interval
struct global_stats_counter {
#define F(x) atomic64 x;
#define FA(x, n) atomic64 x[n];
#include "counter_stats_fields.inc"
#undef F
#undef FA
};
struct global_stats_ax {
@ -142,6 +152,7 @@ INLINE void stats_counters_ax_calc_avg(struct global_stats_ax *stats, long long
return;
#define F(x) stats_counters_ax_calc_avg1(&stats->ax.x, &stats->intv.x, loc ? &loc->x : NULL, run_diff_us);
#define FA(x, n) for (int i = 0; i < n; i++) { F(x[i]) }
#include "counter_stats_fields.inc"
#undef F
}
@ -183,17 +194,28 @@ INLINE void stats_counters_min_max_reset(struct global_stats_min_max *mm, struct
atomic64_inc(&min_max_struct.count.field); \
} while (0)
extern struct global_stats_gauge rtpe_stats_gauge;
INLINE void stats_gauge_calc_avg_reset(struct global_stats_gauge_min_max *out,
struct global_stats_gauge_min_max *in_reset)
{
uint64_t count;
uint64_t cur, count;
#define F(x) \
atomic64_set(&out->min.x, atomic64_get_set(&in_reset->min.x, 0)); \
atomic64_set(&out->max.x, atomic64_get_set(&in_reset->max.x, 0)); \
#define Fc(x) \
atomic64_set(&out->min.x, atomic64_get_set(&in_reset->min.x, cur)); \
atomic64_set(&out->max.x, atomic64_get_set(&in_reset->max.x, cur)); \
count = atomic64_get_set(&in_reset->count.x, 0); \
atomic64_set(&out->count.x, count); \
atomic64_set(&out->avg.x, count ? atomic64_get_set(&in_reset->avg.x, 0) / count : 0);
#define F(x) \
cur = atomic64_get(&rtpe_stats_gauge.x); \
Fc(x)
#undef Fd
#undef FdA
#define Fd(x) \
cur = 0; \
Fc(x)
#define FdA(x, n) for (int i = 0; i < n; i++) { Fd(x[i]) }
#include "gauge_stats_fields.inc"
#undef F
}


+ 3336
- 102
t/test-stats.c
File diff suppressed because it is too large
View File


Loading…
Cancel
Save