From b1dbfb4c4179a62cd4b761ebdc7a3c2de5bdc0d9 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 26 Oct 2015 11:58:38 +0100 Subject: stats: Implement timer based reporting This calls stats_flush in regular intervals which polls the statistical values and calls the active reporters when values have changed. Sponsored-by: On-Waves ehf --- include/osmocom/core/stats.h | 10 ++++++++-- src/stats.c | 46 +++++++++++++++++++++++++++++++++++++++++--- src/vty/stats_vty.c | 34 +++++++++++++++++++------------- 3 files changed, 72 insertions(+), 18 deletions(-) diff --git a/include/osmocom/core/stats.h b/include/osmocom/core/stats.h index b4fb727c..489e0e41 100644 --- a/include/osmocom/core/stats.h +++ b/include/osmocom/core/stats.h @@ -32,7 +32,6 @@ struct stats_reporter { /* config */ int enabled; - int interval; char *name_prefix; char *dest_addr_str; char *bind_addr_str; @@ -50,9 +49,17 @@ struct stats_reporter { struct llist_head list; }; +struct stats_config { + int interval; +}; + +extern struct stats_config *stats_config; + void stats_init(void *ctx); int stats_report(); +int stats_set_interval(int interval); + struct stats_reporter *stats_reporter_alloc(enum stats_reporter_type type, const char *name); void stats_reporter_free(struct stats_reporter *srep); @@ -64,7 +71,6 @@ struct stats_reporter *stats_reporter_find(enum stats_reporter_type type, int stats_reporter_set_remote_addr(struct stats_reporter *srep, const char *addr); int stats_reporter_set_remote_port(struct stats_reporter *srep, int port); int stats_reporter_set_local_addr(struct stats_reporter *srep, const char *addr); -int stats_reporter_set_interval(struct stats_reporter *srep, int interval); int stats_reporter_set_name_prefix(struct stats_reporter *srep, const char *prefix); int stats_reporter_enable(struct stats_reporter *srep); int stats_reporter_disable(struct stats_reporter *srep); diff --git a/src/stats.c b/src/stats.c index 180452e2..c9be0b74 100644 --- a/src/stats.c +++ b/src/stats.c @@ -36,13 +36,24 @@ #include #include #include +#include /* TODO: register properly */ #define DSTATS DLGLOBAL +#define STATS_DEFAULT_INTERVAL 5 /* secs */ static LLIST_HEAD(stats_reporter_list); static void *stats_ctx = NULL; +static int is_initialised = 0; +static int32_t current_stat_item_index = 0; + +static struct stats_config s_stats_config = { + .interval = STATS_DEFAULT_INTERVAL, +}; +struct stats_config *stats_config = &s_stats_config; + +static struct osmo_timer_list stats_timer; static int stats_reporter_statsd_open(struct stats_reporter *srep); static int stats_reporter_statsd_close(struct stats_reporter *srep); @@ -75,6 +86,27 @@ static int update_srep_config(struct stats_reporter *srep) return rc; } +static void stats_timer_cb(void *data) +{ + int interval = stats_config->interval; + + if (!llist_empty(&stats_reporter_list)) + stats_report(); + + osmo_timer_schedule(&stats_timer, interval, 0); +} + +static int start_timer() +{ + if (!is_initialised) + return -ESRCH; + + stats_timer.cb = stats_timer_cb; + osmo_timer_schedule(&stats_timer, 0, 1); + + return 0; +} + struct stats_reporter *stats_reporter_alloc(enum stats_reporter_type type, const char *name) { @@ -101,6 +133,9 @@ void stats_reporter_free(struct stats_reporter *srep) void stats_init(void *ctx) { stats_ctx = ctx; + + is_initialised = 1; + start_timer(); } struct stats_reporter *stats_reporter_find(enum stats_reporter_type type, @@ -176,11 +211,16 @@ int stats_reporter_set_local_addr(struct stats_reporter *srep, const char *addr) return update_srep_config(srep); } -int stats_reporter_set_interval(struct stats_reporter *srep, int interval) +int stats_set_interval(int interval) { - srep->interval = interval; + if (interval <= 0) + return -EINVAL; - return update_srep_config(srep); + stats_config->interval = interval; + if (is_initialised) + start_timer(); + + return 0; } int stats_reporter_set_name_prefix(struct stats_reporter *srep, const char *prefix) diff --git a/src/vty/stats_vty.c b/src/vty/stats_vty.c index 954f3581..a4fd7b05 100644 --- a/src/vty/stats_vty.c +++ b/src/vty/stats_vty.c @@ -128,15 +128,6 @@ DEFUN(cfg_stats_reporter_remote_port, cfg_stats_reporter_remote_port_cmd, argv[0], "remote port"); } -DEFUN(cfg_stats_reporter_interval, cfg_stats_reporter_interval_cmd, - "interval <1-65535>", - "Set the reporting interval\n" - "Interval in seconds\n") -{ - return set_srep_parameter_int(vty, stats_reporter_set_interval, - argv[0], "reporting interval"); -} - DEFUN(cfg_stats_reporter_prefix, cfg_stats_reporter_prefix_cmd, "prefix PREFIX", "Set the item name prefix\n" @@ -214,6 +205,24 @@ DEFUN(cfg_stats_reporter_statsd, cfg_stats_reporter_statsd_cmd, return CMD_SUCCESS; } +DEFUN(cfg_stats_interval, cfg_stats_interval_cmd, + "stats interval <1-65535>", + CFG_STATS_STR "Set the reporting interval\n" + "Interval in seconds\n") +{ + int rc; + int interval = atoi(argv[0]); + rc = stats_set_interval(interval); + if (rc < 0) { + vty_out(vty, "%% Unable to set interval: %s%s", + strerror(-rc), VTY_NEWLINE); + return CMD_WARNING; + } + + return CMD_SUCCESS; +} + + DEFUN(cfg_no_stats_reporter_statsd, cfg_no_stats_reporter_statsd_cmd, "no stats reporter statsd", NO_STR CFG_STATS_STR CFG_REPORTER_STR "Report to a STATSD server\n") @@ -264,9 +273,6 @@ static int config_write_stats_reporter(struct vty *vty, struct stats_reporter *s if (srep->bind_addr_str) vty_out(vty, " local-ip %s%s", srep->bind_addr_str, VTY_NEWLINE); - if (srep->interval) - vty_out(vty, " interval %d%s", - srep->interval, VTY_NEWLINE); if (srep->name_prefix && *srep->name_prefix) vty_out(vty, " prefix %s%s", srep->name_prefix, VTY_NEWLINE); @@ -286,6 +292,8 @@ static int config_write_stats(struct vty *vty) srep = stats_reporter_find(STATS_REPORTER_STATSD, NULL); config_write_stats_reporter(vty, srep); + vty_out(vty, "stats interval %d%s", stats_config->interval, VTY_NEWLINE); + return 1; } @@ -295,6 +303,7 @@ void stats_vty_add_cmds() install_element(CONFIG_NODE, &cfg_stats_reporter_statsd_cmd); install_element(CONFIG_NODE, &cfg_no_stats_reporter_statsd_cmd); + install_element(CONFIG_NODE, &cfg_stats_interval_cmd); install_node(&cfg_stats_node, config_write_stats); vty_install_default(CFG_STATS_NODE); @@ -303,7 +312,6 @@ void stats_vty_add_cmds() install_element(CFG_STATS_NODE, &cfg_no_stats_reporter_local_ip_cmd); install_element(CFG_STATS_NODE, &cfg_stats_reporter_remote_ip_cmd); install_element(CFG_STATS_NODE, &cfg_stats_reporter_remote_port_cmd); - install_element(CFG_STATS_NODE, &cfg_stats_reporter_interval_cmd); install_element(CFG_STATS_NODE, &cfg_stats_reporter_prefix_cmd); install_element(CFG_STATS_NODE, &cfg_no_stats_reporter_prefix_cmd); install_element(CFG_STATS_NODE, &cfg_stats_reporter_enable_cmd); -- cgit v1.2.3