Преглед на файлове

kex: new rpc command - stats.fetch

- similar to stats.get_statistics, but with more json friendly output
Daniel-Constantin Mierla преди 8 години
родител
ревизия
931831bec1
променени са 1 файла, в които са добавени 158 реда и са изтрити 1 реда
  1. 158 1
      src/modules/kex/core_stats.c

+ 158 - 1
src/modules/kex/core_stats.c

@@ -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,