|
@@ -336,6 +336,7 @@ int register_core_stats(void)
|
|
|
struct rpc_list_params {
|
|
|
rpc_t* rpc;
|
|
|
void* ctx;
|
|
|
+ void* hst;
|
|
|
int clear;
|
|
|
};
|
|
|
|
|
@@ -421,11 +422,157 @@ static void rpc_stats_get_statistics(rpc_t* rpc, void* ctx)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * Satistic getter RPC callback.
|
|
|
+ */
|
|
|
+static void rpc_fetch_grp_vars_cbk(void* p, str* g, str* n, counter_handle_t h)
|
|
|
+{
|
|
|
+ struct rpc_list_params *packed_params;
|
|
|
+ rpc_t* rpc;
|
|
|
+ void* ctx;
|
|
|
+ void* hst;
|
|
|
+ char nbuf[128];
|
|
|
+ char vbuf[32];
|
|
|
+
|
|
|
+ packed_params = p;
|
|
|
+ rpc = packed_params->rpc;
|
|
|
+ ctx = packed_params->ctx;
|
|
|
+ hst = packed_params->hst;
|
|
|
+
|
|
|
+ snprintf(nbuf, 127, "%.*s.%.*s", g->len, g->s, n->len, n->s);
|
|
|
+ snprintf(vbuf, 31, "%lu", counter_get_val(h));
|
|
|
+ if(rpc->struct_add(hst, "s", nbuf, vbuf)<0)
|
|
|
+ {
|
|
|
+ rpc->fault(ctx, 500, "Internal error");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Group statistic getter RPC callback.
|
|
|
+ */
|
|
|
+static void rpc_fetch_all_grps_cbk(void* p, str* g)
|
|
|
+{
|
|
|
+ counter_iterate_grp_vars(g->s, rpc_fetch_grp_vars_cbk, p);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * All statistic getter RPC callback.
|
|
|
+ */
|
|
|
+static void stats_fetch_all(rpc_t* rpc, void* ctx, char* stat)
|
|
|
+{
|
|
|
+ int len = strlen(stat);
|
|
|
+ struct rpc_list_params packed_params;
|
|
|
+ str s_statistic;
|
|
|
+ stat_var *s_stat;
|
|
|
+ void *th;
|
|
|
+ char nbuf[128];
|
|
|
+ char vbuf[32];
|
|
|
+ char *m;
|
|
|
+ char *n;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ if (rpc->add(ctx, "{", &th) < 0)
|
|
|
+ {
|
|
|
+ rpc->fault(ctx, 500, "Internal error creating root struct");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (len==3 && strcmp("all", stat)==0) {
|
|
|
+ packed_params.rpc = rpc;
|
|
|
+ packed_params.ctx = ctx;
|
|
|
+ packed_params.hst = th;
|
|
|
+ counter_iterate_grp_names(rpc_fetch_all_grps_cbk, &packed_params);
|
|
|
+ }
|
|
|
+ else if (stat[len-1]==':') {
|
|
|
+ packed_params.rpc = rpc;
|
|
|
+ packed_params.ctx = ctx;
|
|
|
+ packed_params.hst = th;
|
|
|
+ stat[len-1] = '\0';
|
|
|
+ counter_iterate_grp_vars(stat, rpc_fetch_grp_vars_cbk, &packed_params);
|
|
|
+ stat[len-1] = ':';
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ s_statistic.s = stat;
|
|
|
+ s_statistic.len = strlen(stat);
|
|
|
+ s_stat = get_stat(&s_statistic);
|
|
|
+ if (s_stat) {
|
|
|
+ snprintf(nbuf, 127, "%s.%s",
|
|
|
+ ZSW(get_stat_module(s_stat)), ZSW(get_stat_name(s_stat)));
|
|
|
+ snprintf(vbuf, 31, "%lu", get_stat_val(s_stat));
|
|
|
+ if(rpc->struct_add(th, "s", nbuf, vbuf)<0)
|
|
|
+ {
|
|
|
+ rpc->fault(ctx, 500, "Internal error");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ n = strchr(stat, '.');
|
|
|
+ if(n==NULL) {
|
|
|
+ n =strchr(stat, ':');
|
|
|
+ }
|
|
|
+ if(n==NULL) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ n++;
|
|
|
+ s_statistic.s = n;
|
|
|
+ s_statistic.len = strlen(n);
|
|
|
+ s_stat = get_stat(&s_statistic);
|
|
|
+ if (s_stat) {
|
|
|
+ if(m==NULL) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ m = get_stat_module(s_stat);
|
|
|
+ for(i=0; m[i]!=0 && stat[i]!=0; i++) {
|
|
|
+ if(stat[i]!=m[i]) {
|
|
|
+ /* module name mismatch */
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(m[i]!=0 || (stat[i]!='.' && stat[i]!=':')) {
|
|
|
+ /* module name mismatch */
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ snprintf(nbuf, 127, "%s.%s",
|
|
|
+ m, ZSW(get_stat_name(s_stat)));
|
|
|
+ snprintf(vbuf, 31, "%lu", get_stat_val(s_stat));
|
|
|
+ if(rpc->struct_add(th, "s", nbuf, vbuf)<0)
|
|
|
+ {
|
|
|
+ rpc->fault(ctx, 500, "Internal error");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * RPC statistics getter.
|
|
|
+ */
|
|
|
+static void rpc_stats_fetch_statistics(rpc_t* rpc, void* ctx)
|
|
|
+{
|
|
|
+ char* stat;
|
|
|
+
|
|
|
+ if (stats_support()==0) {
|
|
|
+ rpc->fault(ctx, 400, "stats support not enabled");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (rpc->scan(ctx, "s", &stat) < 1) {
|
|
|
+ rpc->fault(ctx, 400, "Please provide which stats to retrieve");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ stats_fetch_all(rpc, ctx, stat);
|
|
|
+ while((rpc->scan(ctx, "*s", &stat)>0)) {
|
|
|
+ stats_fetch_all(rpc, ctx, stat);
|
|
|
+ }
|
|
|
+ return;
|
|
|
+}
|
|
|
|
|
|
/**
|
|
|
* Satistic reset/clear-er RPC callback..
|
|
|
*/
|
|
|
-static void rpc_reset_or_clear_grp_vars_cbk(void* p, str* g, str* n, counter_handle_t h)
|
|
|
+static void rpc_reset_or_clear_grp_vars_cbk(void* p, str* g, str* n,
|
|
|
+ counter_handle_t h)
|
|
|
{
|
|
|
struct rpc_list_params *packed_params;
|
|
|
rpc_t* rpc;
|
|
@@ -569,11 +716,19 @@ static void rpc_stats_clear_statistics(rpc_t* rpc, void* ctx)
|
|
|
*/
|
|
|
static const char* rpc_stats_get_statistics_doc[2] =
|
|
|
{"get core and modules stats", 0};
|
|
|
+
|
|
|
+/**
|
|
|
+ * RPC statistics getter doc.
|
|
|
+ */
|
|
|
+static const char* rpc_stats_fetch_statistics_doc[2] =
|
|
|
+ {"fetch core and modules stats", 0};
|
|
|
+
|
|
|
/**
|
|
|
* RPC statistics reseter doc.
|
|
|
*/
|
|
|
static const char* rpc_stats_reset_statistics_doc[2] =
|
|
|
{"reset core and modules stats (silent operation)", 0};
|
|
|
+
|
|
|
/**
|
|
|
* RPC statistics clearer doc.
|
|
|
*/
|
|
@@ -587,6 +742,8 @@ rpc_export_t kex_stats_rpc[] =
|
|
|
{
|
|
|
{"stats.get_statistics", rpc_stats_get_statistics,
|
|
|
rpc_stats_get_statistics_doc, RET_ARRAY},
|
|
|
+ {"stats.fetch", rpc_stats_fetch_statistics,
|
|
|
+ rpc_stats_fetch_statistics_doc, 0},
|
|
|
{"stats.reset_statistics", rpc_stats_reset_statistics,
|
|
|
rpc_stats_reset_statistics_doc, 0},
|
|
|
{"stats.clear_statistics", rpc_stats_clear_statistics,
|