diff --git a/src/modules/benchmark/benchmark.c b/src/modules/benchmark/benchmark.c
index cfa646913e0..c30476d31ba 100644
--- a/src/modules/benchmark/benchmark.c
+++ b/src/modules/benchmark/benchmark.c
@@ -244,6 +244,9 @@ void bm_reset_timer(int i)
bm_mycfg->tindex[i]->last_sum = 0;
bm_mycfg->tindex[i]->global_max = 0;
bm_mycfg->tindex[i]->global_min = 0xffffffff;
+ bm_mycfg->tindex[i]->period_sum = 0;
+ bm_mycfg->tindex[i]->period_max = 0;
+ bm_mycfg->tindex[i]->period_min = 0xffffffff;
}
void reset_timers(void)
@@ -361,6 +364,11 @@ int _bm_log_timer(unsigned int id)
bm_mycfg->tindex[id]->global_max,
((double)bm_mycfg->tindex[id]->sum)/bm_mycfg->tindex[id]->calls);
+ /* Fill data for last period. */
+ bm_mycfg->tindex[id]->period_sum = bm_mycfg->tindex[id]->last_sum;
+ bm_mycfg->tindex[id]->period_max = bm_mycfg->tindex[id]->last_max;
+ bm_mycfg->tindex[id]->period_min = bm_mycfg->tindex[id]->last_min;
+
bm_mycfg->tindex[id]->last_sum = 0;
bm_mycfg->tindex[id]->last_max = 0;
bm_mycfg->tindex[id]->last_min = 0xffffffff;
@@ -610,6 +618,167 @@ void bm_rpc_loglevel(rpc_t* rpc, void* ctx)
bm_mycfg->loglevel = v1;
}
+/**
+ * Internal buffer to convert llu numbers into strings.
+ */
+#define BUFFER_S_LEN 100
+static char buffer_s[BUFFER_S_LEN];
+
+/**
+ * Create a RPC structure for a timer.
+ *
+ * /return 0 on success.
+ */
+int bm_rpc_timer_struct(rpc_t* rpc, void* ctx, int id)
+{
+ void *handle; /* Handle for RPC structure. */
+
+ /* Create empty structure and obtain its handle */
+ if (rpc->add(ctx, "{", &handle) < 0) {
+ return -1;
+ }
+
+ int enabled = timer_active(id);
+
+ if (rpc->struct_add(handle, "s", "name", bm_mycfg->tindex[id]->name) < 0) {
+ return -1;
+ }
+
+ if (rpc->struct_add(handle, "s", "state", (enabled==0)?"disabled":"enabled") < 0) {
+ return -1;
+ }
+
+ if (rpc->struct_add(handle, "d", "id", id) < 0) {
+ return -1;
+ }
+
+ if (rpc->struct_add(handle, "d", "granularity", bm_mycfg->granularity) < 0) {
+ return -1;
+ }
+
+ /* We use a string to represent long long unsigned integers. */
+ int len;
+ len = snprintf(buffer_s, BUFFER_S_LEN, "%llu", bm_mycfg->tindex[id]->period_sum);
+ if (len <= 0 || len >= BUFFER_S_LEN) {
+ LM_ERR("Buffer overflow\n");
+ return -1;
+ }
+ if (rpc->struct_add(handle, "s", "period_sum", buffer_s) < 0) {
+ return -1;
+ }
+
+ len = snprintf(buffer_s, BUFFER_S_LEN, "%llu", bm_mycfg->tindex[id]->period_min);
+ if (len <= 0 || len >= BUFFER_S_LEN) {
+ LM_ERR("Buffer overflow\n");
+ return -1;
+ }
+ if (rpc->struct_add(handle, "s", "period_min", buffer_s) < 0) {
+ return -1;
+ }
+
+ len = snprintf(buffer_s, BUFFER_S_LEN, "%llu", bm_mycfg->tindex[id]->period_max);
+ if (len <= 0 || len >= BUFFER_S_LEN) {
+ LM_ERR("Buffer overflow\n");
+ return -1;
+ }
+ if (rpc->struct_add(handle, "s", "period_max", buffer_s) < 0) {
+ return -1;
+ }
+
+ if (bm_mycfg->granularity > 0) {
+ double media = ((double)bm_mycfg->tindex[id]->period_sum)/bm_mycfg->granularity;
+
+ if (rpc->struct_add(handle, "f", "period_media", media) < 0) {
+ return -1;
+ }
+ }
+
+ len = snprintf(buffer_s, BUFFER_S_LEN, "%llu", bm_mycfg->tindex[id]->calls);
+ if (len <= 0 || len >= BUFFER_S_LEN) {
+ LM_ERR("Buffer overflow\n");
+ return -1;
+ }
+ if (rpc->struct_add(handle, "s", "calls", buffer_s) < 0) {
+ return -1;
+ }
+
+ len = snprintf(buffer_s, BUFFER_S_LEN, "%llu", bm_mycfg->tindex[id]->sum);
+ if (len <= 0 || len >= BUFFER_S_LEN) {
+ LM_ERR("Buffer overflow\n");
+ return -1;
+ }
+ if (rpc->struct_add(handle, "s", "sum", buffer_s) < 0) {
+ return -1;
+ }
+
+ len = snprintf(buffer_s, BUFFER_S_LEN, "%llu", bm_mycfg->tindex[id]->global_min);
+ if (len <= 0 || len >= BUFFER_S_LEN) {
+ LM_ERR("Buffer overflow\n");
+ return -1;
+ }
+ if (rpc->struct_add(handle, "s", "global_min", buffer_s) < 0) {
+ return -1;
+ }
+
+ len = snprintf(buffer_s, BUFFER_S_LEN, "%llu", bm_mycfg->tindex[id]->global_max);
+ if (len <= 0 || len >= BUFFER_S_LEN) {
+ LM_ERR("Buffer overflow\n");
+ return -1;
+ }
+ if (rpc->struct_add(handle, "s", "global_max", buffer_s) < 0) {
+ return -1;
+ }
+
+ if (bm_mycfg->tindex[id]->calls > 0) {
+ double media = ((double)bm_mycfg->tindex[id]->sum)/bm_mycfg->tindex[id]->calls;
+
+ if (rpc->struct_add(handle, "f", "global_media", media) < 0) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+void bm_rpc_timer_list(rpc_t* rpc, void* ctx)
+{
+ int id;
+
+ for (id = 0; id < bm_mycfg->nrtimers; id++) {
+
+ if (bm_rpc_timer_struct(rpc, ctx, id)) {
+ LM_ERR("Failure writing RPC structure for timer: %d\n", id);
+ return;
+ }
+
+ } /* for (id = 0; id < bm_mycfg->nrtimers; id++) */
+
+ return;
+}
+
+void bm_rpc_timer_name_list(rpc_t* rpc, void* ctx)
+{
+ char *name = NULL;
+ unsigned int id = 0;
+
+ if(rpc->scan(ctx, "s", &name) < 1) {
+ LM_WARN("invalid timer name\n");
+ rpc->fault(ctx, 400, "Invalid timer name");
+ return;
+ }
+ if(_bm_register_timer(name, 0, &id)!=0) {
+ rpc->fault(ctx, 500, "Register timer failure");
+ return;
+ }
+
+ if (bm_rpc_timer_struct(rpc, ctx, id)) {
+ LM_ERR("Failure writing RPC structure for timer: %d\n", id);
+ return;
+ }
+
+ return;
+}
+
static const char* bm_rpc_enable_global_doc[2] = {
"Enable/disable benchmarking",
0
@@ -630,6 +799,16 @@ static const char* bm_rpc_loglevel_doc[2] = {
0
};
+static const char* bm_rpc_timer_list_doc[2] = {
+ "List all timers",
+ 0
+};
+
+static const char* bm_rpc_timer_name_list_doc[2] = {
+ "List a timer based on its name",
+ 0
+};
+
rpc_export_t bm_rpc_cmds[] = {
{"benchmark.enable_global", bm_rpc_enable_global,
bm_rpc_enable_global_doc, 0},
@@ -639,6 +818,10 @@ rpc_export_t bm_rpc_cmds[] = {
bm_rpc_granularity_doc, 0},
{"benchmark.loglevel", bm_rpc_loglevel,
bm_rpc_loglevel_doc, 0},
+ {"benchmark.timer_list", bm_rpc_timer_list,
+ bm_rpc_timer_list_doc, 0},
+ {"benchmark.timer_name_list", bm_rpc_timer_name_list,
+ bm_rpc_timer_name_list_doc, 0},
{0, 0, 0, 0}
};
@@ -683,4 +866,4 @@ int mod_register(char *path, int *dlflags, void *p1, void *p2)
/*@} */
-/* End of file */
\ No newline at end of file
+/* End of file */
diff --git a/src/modules/benchmark/benchmark.h b/src/modules/benchmark/benchmark.h
index fea0649720e..9859f4a36a6 100644
--- a/src/modules/benchmark/benchmark.h
+++ b/src/modules/benchmark/benchmark.h
@@ -66,6 +66,9 @@ typedef struct benchmark_timer
unsigned long long last_min; /* Maximum ... */
unsigned long long global_max; /* Global minimum, since start */
unsigned long long global_min; /* ... maximum ... */
+ unsigned long long period_sum; /* Sum for last completed period (between granularity) */
+ unsigned long long period_max; /* Maximum for last completed period ... */
+ unsigned long long period_min; /* Minimum for last completed period ... */
struct benchmark_timer *next;
} benchmark_timer_t;
diff --git a/src/modules/benchmark/doc/benchmark_admin.xml b/src/modules/benchmark/doc/benchmark_admin.xml
index d01bbc81ee2..10f94b2b5c4 100644
--- a/src/modules/benchmark/doc/benchmark_admin.xml
+++ b/src/modules/benchmark/doc/benchmark_admin.xml
@@ -332,6 +332,86 @@ bm_log_timer("test");
Modifies the module log level. See "loglevel" variable.
+
+ benchmark.timer_list
+
+ List data for all timers (Last complete period and global data)
+ Displays info close to the one output in the log by using a RPC structure.
+ period_sum, period_min and period_media show data for last granularity
+ period already completed.
+
+
+ List all timers
+
+...
+&kamcmd; benchmark.timer_list
+{
+ name: test
+ state: enabled
+ id: 0
+ granularity: 2
+ period_sum: 69
+ period_min: 22
+ period_max: 47
+ period_media: 34.500000
+ calls: 4
+ sum: 217
+ global_min: 22
+ global_max: 88
+ global_media: 54.250000
+}
+{
+ name: test2
+ state: enabled
+ id: 1
+ granularity: 2
+ period_sum: 122
+ period_min: 25
+ period_max: 97
+ period_media: 61.000000
+ calls: 4
+ sum: 349
+ global_min: 25
+ global_max: 151
+ global_media: 87.250000
+}
+...
+
+
+
+
+ benchmark.timer_name_list
+
+ List data for one timer based on its name (Last complete period and global data)
+ It displays info close to the one output in the log by using a RPC structure.
+ period_sum, period_min and period_media show data for last granularity
+ period already completed.
+
+
+ List one timer
+
+...
+&kamcmd; benchmark.timer_name_list test
+{
+ name: test
+ state: enabled
+ id: 0
+ granularity: 2
+ period_sum: 69
+ period_min: 22
+ period_max: 47
+ period_media: 34.500000
+ calls: 4
+ sum: 217
+ global_min: 22
+ global_max: 88
+ global_media: 54.250000
+}
+...
+
+
+
+