diff options
-rw-r--r-- | TODO-RELEASE | 1 | ||||
-rw-r--r-- | include/osmocom/vty/command.h | 1 | ||||
-rw-r--r-- | src/vty/stats_vty.c | 261 | ||||
-rw-r--r-- | tests/vty/vty_test.ok | 6 |
4 files changed, 265 insertions, 4 deletions
diff --git a/TODO-RELEASE b/TODO-RELEASE index 43b1e8ef..93198e40 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -1 +1,2 @@ #library what description / commit summary line +libosmovty abi-change stats/vty: Add stats configuration (enum node_type has changed) diff --git a/include/osmocom/vty/command.h b/include/osmocom/vty/command.h index 4eb519f6..890f0d6d 100644 --- a/include/osmocom/vty/command.h +++ b/include/osmocom/vty/command.h @@ -75,6 +75,7 @@ enum node_type { SERVICE_NODE, /*!< \brief Service node. */ DEBUG_NODE, /*!< \brief Debug node. */ CFG_LOG_NODE, /*!< \brief Configure the logging */ + CFG_STATS_NODE, /*!< \brief Configure the statistics */ VTY_NODE, /*!< \brief Vty node. */ diff --git a/src/vty/stats_vty.c b/src/vty/stats_vty.c index c19b2259..954f3581 100644 --- a/src/vty/stats_vty.c +++ b/src/vty/stats_vty.c @@ -29,13 +29,209 @@ #include <osmocom/vty/buffer.h> #include <osmocom/vty/vty.h> #include <osmocom/vty/telnet_interface.h> +#include <osmocom/vty/telnet_interface.h> #include <osmocom/vty/misc.h> +#include <osmocom/core/stats.h> + #define CFG_STATS_STR "Configure stats sub-system\n" #define CFG_REPORTER_STR "Configure a stats reporter\n" #define SHOW_STATS_STR "Show statistical values\n" +struct cmd_node cfg_stats_node = { + CFG_STATS_NODE, + "%s(config-stats)# ", + 1 +}; + +static struct stats_reporter *osmo_stats_vty2srep(struct vty *vty) +{ + if (vty->node == CFG_STATS_NODE) + return vty->index; + + return NULL; +} + +static int set_srep_parameter_str(struct vty *vty, + int (*fun)(struct stats_reporter *, const char *), + const char *val, const char *param_name) +{ + int rc; + struct stats_reporter *srep = osmo_stats_vty2srep(vty); + OSMO_ASSERT(srep); + + rc = fun(srep, val); + if (rc < 0) { + vty_out(vty, "%% Unable to set %s: %s%s", + param_name, strerror(-rc), VTY_NEWLINE); + return CMD_WARNING; + } + + return CMD_SUCCESS; +} + +static int set_srep_parameter_int(struct vty *vty, + int (*fun)(struct stats_reporter *, int), + const char *val, const char *param_name) +{ + int rc; + int int_val; + struct stats_reporter *srep = osmo_stats_vty2srep(vty); + OSMO_ASSERT(srep); + + int_val = atoi(val); + + rc = fun(srep, int_val); + if (rc < 0) { + vty_out(vty, "%% Unable to set %s: %s%s", + param_name, strerror(-rc), VTY_NEWLINE); + return CMD_WARNING; + } + + return CMD_SUCCESS; +} + +DEFUN(cfg_stats_reporter_local_ip, cfg_stats_reporter_local_ip_cmd, + "local-ip ADDR", + "Set the IP address to which we bind locally\n" + "IP Address\n") +{ + return set_srep_parameter_str(vty, stats_reporter_set_local_addr, + argv[0], "local address"); +} + +DEFUN(cfg_no_stats_reporter_local_ip, cfg_no_stats_reporter_local_ip_cmd, + "no local-ip", + NO_STR + "Set the IP address to which we bind locally\n") +{ + return set_srep_parameter_str(vty, stats_reporter_set_local_addr, + NULL, "local address"); +} + +DEFUN(cfg_stats_reporter_remote_ip, cfg_stats_reporter_remote_ip_cmd, + "remote-ip ADDR", + "Set the remote IP address to which we connect\n" + "IP Address\n") +{ + return set_srep_parameter_str(vty, stats_reporter_set_remote_addr, + argv[0], "remote address"); +} + +DEFUN(cfg_stats_reporter_remote_port, cfg_stats_reporter_remote_port_cmd, + "remote-port <1-65535>", + "Set the remote port to which we connect\n" + "Remote port number\n") +{ + return set_srep_parameter_int(vty, stats_reporter_set_remote_port, + 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" + "The prefix string\n") +{ + return set_srep_parameter_str(vty, stats_reporter_set_name_prefix, + argv[0], "prefix string"); +} + +DEFUN(cfg_no_stats_reporter_prefix, cfg_no_stats_reporter_prefix_cmd, + "no prefix", + NO_STR + "Set the item name prefix\n") +{ + return set_srep_parameter_str(vty, stats_reporter_set_name_prefix, + "", "prefix string"); +} + +DEFUN(cfg_stats_reporter_enable, cfg_stats_reporter_enable_cmd, + "enable", + "Enable the reporter\n") +{ + int rc; + struct stats_reporter *srep = osmo_stats_vty2srep(vty); + OSMO_ASSERT(srep); + + rc = stats_reporter_enable(srep); + if (rc < 0) { + vty_out(vty, "%% Unable to enable the reporter: %s%s", + strerror(-rc), VTY_NEWLINE); + return CMD_WARNING; + } + + return CMD_SUCCESS; +} + +DEFUN(cfg_stats_reporter_disable, cfg_stats_reporter_disable_cmd, + "disable", + "Disable the reporter\n") +{ + int rc; + struct stats_reporter *srep = osmo_stats_vty2srep(vty); + OSMO_ASSERT(srep); + + rc = stats_reporter_disable(srep); + if (rc < 0) { + vty_out(vty, "%% Unable to disable the reporter: %s%s", + strerror(-rc), VTY_NEWLINE); + return CMD_WARNING; + } + + return CMD_SUCCESS; +} + +DEFUN(cfg_stats_reporter_statsd, cfg_stats_reporter_statsd_cmd, + "stats reporter statsd", + CFG_STATS_STR CFG_REPORTER_STR "Report to a STATSD server\n") +{ + struct stats_reporter *srep; + + srep = stats_reporter_find(STATS_REPORTER_STATSD, NULL); + if (!srep) { + srep = stats_reporter_create_statsd(NULL); + if (!srep) { + vty_out(vty, "%% Unable to create statsd reporter%s", + VTY_NEWLINE); + return CMD_WARNING; + } + /* TODO: if needed, add stats_add_reporter(srep); */ + } + + vty->index = srep; + vty->node = CFG_STATS_NODE; + + 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") +{ + struct stats_reporter *srep; + + srep = stats_reporter_find(STATS_REPORTER_STATSD, NULL); + if (!srep) { + vty_out(vty, "%% No statsd logging active%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + stats_reporter_free(srep); + + return CMD_SUCCESS; +} + DEFUN(show_stats, show_stats_cmd, "show stats", @@ -46,7 +242,70 @@ DEFUN(show_stats, return CMD_SUCCESS; } -void stats_vty_add_cmds(const struct log_info *cat) +static int config_write_stats_reporter(struct vty *vty, struct stats_reporter *srep) +{ + if (srep == NULL) + return 0; + + switch (srep->type) { + case STATS_REPORTER_STATSD: + vty_out(vty, "stats reporter statsd%s", VTY_NEWLINE); + break; + } + + vty_out(vty, " disable%s", VTY_NEWLINE); + + if (srep->dest_addr_str) + vty_out(vty, " remote-ip %s%s", + srep->dest_addr_str, VTY_NEWLINE); + if (srep->dest_port) + vty_out(vty, " remote-port %d%s", + srep->dest_port, VTY_NEWLINE); + 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); + else + vty_out(vty, " no prefix%s", VTY_NEWLINE); + + if (srep->enabled) + vty_out(vty, " enable%s", VTY_NEWLINE); + + return 1; +} + +static int config_write_stats(struct vty *vty) +{ + struct stats_reporter *srep; + + srep = stats_reporter_find(STATS_REPORTER_STATSD, NULL); + config_write_stats_reporter(vty, srep); + + return 1; +} + +void stats_vty_add_cmds() { install_element_ve(&show_stats_cmd); + + install_element(CONFIG_NODE, &cfg_stats_reporter_statsd_cmd); + install_element(CONFIG_NODE, &cfg_no_stats_reporter_statsd_cmd); + + install_node(&cfg_stats_node, config_write_stats); + vty_install_default(CFG_STATS_NODE); + + install_element(CFG_STATS_NODE, &cfg_stats_reporter_local_ip_cmd); + 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); + install_element(CFG_STATS_NODE, &cfg_stats_reporter_disable_cmd); } diff --git a/tests/vty/vty_test.ok b/tests/vty/vty_test.ok index 0ea2dabf..c6365907 100644 --- a/tests/vty/vty_test.ok +++ b/tests/vty/vty_test.ok @@ -24,11 +24,11 @@ Returned: 0, Current node: 3 '%s# ' Going to execute 'configure terminal' Returned: 0, Current node: 4 '%s(config)# ' Going to execute 'line vty' -Returned: 0, Current node: 8 '%s(config-line)# ' +Returned: 0, Current node: 9 '%s(config-line)# ' Going to execute 'exit' Returned: 0, Current node: 4 '%s(config)# ' Going to execute 'line vty' -Returned: 0, Current node: 8 '%s(config-line)# ' +Returned: 0, Current node: 9 '%s(config-line)# ' Going to execute 'end' Returned: 0, Current node: 3 '%s# ' Going to execute 'configure terminal' @@ -36,7 +36,7 @@ Returned: 0, Current node: 4 '%s(config)# ' Going to execute 'log stderr' Returned: 0, Current node: 7 '%s(config-log)# ' Going to execute 'line vty' -Returned: 0, Current node: 8 '%s(config-line)# ' +Returned: 0, Current node: 9 '%s(config-line)# ' Going to execute 'log stderr' Returned: 0, Current node: 7 '%s(config-log)# ' Going to execute 'end' |