[PATCH 05/10] libctrl: Add commands to query counters and rate_cntr

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/OpenBSC@lists.osmocom.org/.

Daniel Willmann daniel at totalueberwachung.de
Fri May 20 17:06:22 UTC 2011


These commands are installed in controlif_setup. Query them like this:
"rate_ctr.<interval>.<counter group>.<index>.<counter name>" for rate
counters and "counter.<counter name>" for regular counters. <interval>
may be either "abs" for absolute values or one or
"per_{sec,min,hour,day}".

It is possible to query all rate counters in a group (regardless of
index) or all counters in a group and with a certain index if you omit
<counter name> and <index> or just <counter name>.
---
 openbsc/src/libctrl/control_if.c |  258 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 258 insertions(+), 0 deletions(-)

diff --git a/openbsc/src/libctrl/control_if.c b/openbsc/src/libctrl/control_if.c
index a607b10..0e625cd 100644
--- a/openbsc/src/libctrl/control_if.c
+++ b/openbsc/src/libctrl/control_if.c
@@ -49,7 +49,9 @@
 #include <openbsc/abis_nm.h>
 
 #include <osmocom/core/msgb.h>
+#include <osmocom/core/rate_ctr.h>
 #include <osmocom/core/select.h>
+#include <osmocom/core/statistics.h>
 #include <osmocom/core/talloc.h>
 
 #include <osmocom/gsm/tlv.h>
@@ -342,6 +344,259 @@ static int listen_fd_cb(struct osmo_fd *listen_bfd, unsigned int what)
 	return ret;
 }
 
+static uint64_t get_rate_ctr_value(const struct rate_ctr *ctr, int intv)
+{
+	if (intv >= RATE_CTR_INTV_NUM)
+		return 0;
+
+	/* Absolute value */
+	if (intv == -1) {
+		return  ctr->current;
+	} else {
+		return ctr->intv[intv].rate;
+	}
+}
+
+static char *get_all_rate_ctr_in_group(const struct rate_ctr_group *ctrg, int intv)
+{
+	int i;
+	char *counters = talloc_strdup(tall_bsc_ctx, "");
+	if (!counters)
+		return NULL;
+
+	for (i=0;i<ctrg->desc->num_ctr;i++) {
+		counters = talloc_asprintf_append(counters, "\n%s.%u.%s %lu",
+			ctrg->desc->group_name_prefix, ctrg->idx,
+			ctrg->desc->ctr_desc[i].name,
+			get_rate_ctr_value(&ctrg->ctr[i], intv));
+		if (!counters)
+			return NULL;
+	}
+	return counters;
+}
+
+static int get_rate_ctr_group(const char *ctr_group, int intv, struct ctrl_cmd *cmd)
+{
+	int i;
+	char *counters;
+	struct rate_ctr_group *ctrg;
+
+	cmd->reply = talloc_asprintf(cmd, "All counters in group %s", ctr_group);
+	if (!cmd->reply)
+		goto oom;
+
+	for (i=0;;i++) {
+		ctrg = rate_ctr_get_group_by_name_idx(ctr_group, i);
+		if (!ctrg)
+			break;
+
+		counters = get_all_rate_ctr_in_group(ctrg, intv);
+		if (!counters)
+			goto oom;
+
+		cmd->reply = talloc_asprintf_append(cmd->reply, "%s", counters);
+		talloc_free(counters);
+		if (!cmd->reply)
+			goto oom;
+	}
+
+	/* We found no counter group by that name */
+	if (i == 0) {
+		cmd->reply = talloc_asprintf(cmd, "No counter group with name %s.", ctr_group);
+		return CTRL_CMD_ERROR;
+	}
+
+	return CTRL_CMD_REPLY;
+oom:
+	cmd->reply = "OOM.";
+	return CTRL_CMD_ERROR;
+}
+
+static int get_rate_ctr_group_idx(const struct rate_ctr_group *ctrg, int intv, struct ctrl_cmd *cmd)
+{
+	char *counters;
+
+	counters = get_all_rate_ctr_in_group(ctrg, intv);
+	if (!counters)
+		goto oom;
+
+	cmd->reply = talloc_asprintf(cmd, "All counters in %s.%u%s",
+			ctrg->desc->group_name_prefix, ctrg->idx, counters);
+	talloc_free(counters);
+	if (!cmd->reply)
+		goto oom;
+
+	return CTRL_CMD_REPLY;
+oom:
+	cmd->reply = "OOM.";
+	return CTRL_CMD_ERROR;
+}
+
+/* rate_ctr */
+CTRL_CMD_DEFINE(rate_ctr, "rate_ctr *");
+int get_rate_ctr(struct ctrl_cmd *cmd, void *data)
+{
+	int intv;
+	unsigned int idx;
+	char *ctr_group, *ctr_idx, *ctr_name, *tmp, *dup, *saveptr, *interval;
+	struct rate_ctr_group *ctrg;
+	const struct rate_ctr *ctr;
+
+	dup = talloc_strdup(cmd, cmd->variable);
+	if (!dup)
+		goto oom;
+
+	/* Skip over possible prefixes (net.) */
+	tmp = strstr(dup, "rate_ctr");
+	if (!tmp) {
+		talloc_free(dup);
+		cmd->reply = "rate_ctr not a token in rate_ctr command!";
+		goto err;
+	}
+
+	strtok_r(tmp, ".", &saveptr);
+	interval = strtok_r(NULL, ".", &saveptr);
+	if (!interval) {
+		talloc_free(dup);
+		cmd->reply = "Missing interval.";
+		goto err;
+	}
+
+	if (!strcmp(interval, "abs")) {
+		intv = -1;
+	} else if (!strcmp(interval, "per_sec")) {
+		intv = RATE_CTR_INTV_SEC;
+	} else if (!strcmp(interval, "per_min")) {
+		intv = RATE_CTR_INTV_MIN;
+	} else if (!strcmp(interval, "per_hour")) {
+		intv = RATE_CTR_INTV_HOUR;
+	} else if (!strcmp(interval, "per_day")) {
+		intv = RATE_CTR_INTV_DAY;
+	} else {
+		talloc_free(dup);
+		cmd->reply = "Wrong interval.";
+		goto err;
+	}
+
+	ctr_group = strtok_r(NULL, ".", &saveptr);
+	tmp = strtok_r(NULL, ".", &saveptr);
+	if (!ctr_group || !tmp) {
+		talloc_free(dup);
+		cmd->reply = "Counter group must be of form a.b";
+		goto err;
+	}
+	ctr_group[strlen(ctr_group)] = '.';
+
+	ctr_idx = strtok_r(NULL, ".", &saveptr);
+	if (!ctr_idx) {
+		talloc_free(dup);
+		return get_rate_ctr_group(ctr_group, intv, cmd);
+	}
+	idx = atoi(ctr_idx);
+
+	ctrg = rate_ctr_get_group_by_name_idx(ctr_group, idx);
+	if (!ctrg) {
+		talloc_free(dup);
+		cmd->reply = "Counter group not found.";
+		goto err;
+	}
+
+	ctr_name = strtok_r(NULL, "\0", &saveptr);
+	if (!ctr_name) {
+		talloc_free(dup);
+		return get_rate_ctr_group_idx(ctrg, intv, cmd);
+	}
+
+	ctr = rate_ctr_get_by_name(ctrg, ctr_name);
+	if (!ctr) {
+		cmd->reply = "Counter name not found.";
+		talloc_free(dup);
+		goto err;
+	}
+
+	talloc_free(dup);
+
+	cmd->reply = talloc_asprintf(cmd, "%lu", get_rate_ctr_value(ctr, intv));
+	if (!cmd->reply)
+		goto oom;
+
+	return CTRL_CMD_REPLY;
+oom:
+	cmd->reply = "OOM";
+err:
+	return CTRL_CMD_ERROR;
+}
+
+int set_rate_ctr(struct ctrl_cmd *cmd, void *data)
+{
+	cmd->reply = "Can't set rate counter.";
+
+	return CTRL_CMD_ERROR;
+}
+
+int verify_rate_ctr(struct ctrl_cmd *cmd, const char *value, void *data)
+{
+	return 0;
+}
+
+/* counter */
+CTRL_CMD_DEFINE(counter, "counter *");
+int get_counter(struct ctrl_cmd *cmd, void *data)
+{
+	char *ctr_name, *tmp, *dup, *saveptr;
+	struct osmo_counter *counter;
+
+	cmd->reply = "OOM";
+	dup = talloc_strdup(cmd, cmd->variable);
+	if (!dup)
+		goto err;
+
+
+	tmp = strstr(dup, "counter");
+	if (!tmp) {
+		talloc_free(dup);
+		goto err;
+	}
+
+	strtok_r(tmp, ".", &saveptr);
+	ctr_name = strtok_r(NULL, "\0", &saveptr);
+
+	if (!ctr_name)
+		goto err;
+
+	counter = osmo_counter_get_by_name(ctr_name);
+	if (!counter) {
+		cmd->reply = "Counter name not found.";
+		talloc_free(dup);
+		goto err;
+	}
+
+	talloc_free(dup);
+
+	cmd->reply = talloc_asprintf(cmd, "%lu", counter->value);
+	if (!cmd->reply) {
+		cmd->reply = "OOM";
+		goto err;
+	}
+
+	return CTRL_CMD_REPLY;
+err:
+	return CTRL_CMD_ERROR;
+}
+
+int set_counter(struct ctrl_cmd *cmd, void *data)
+{
+
+	cmd->reply = "Can't set counter.";
+
+	return CTRL_CMD_ERROR;
+}
+
+int verify_counter(struct ctrl_cmd *cmd, const char *value, void *data)
+{
+	return 0;
+}
+
 int controlif_setup(struct gsm_network *gsmnet, uint16_t port)
 {
 	int ret;
@@ -365,5 +620,8 @@ int controlif_setup(struct gsm_network *gsmnet, uint16_t port)
 		return ret;
 	}
 
+	ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_rate_ctr);
+	ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_counter);
+
 	return ret;
 }
-- 
1.7.5.rc3





More information about the OpenBSC mailing list