blob: 2ccbf6681923c4958c3b2192c9296f773d121970 [file] [log] [blame]
Neels Hofmeyr17518fe2017-06-20 04:35:06 +02001/*
2 * (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
Jacob Erlbeck45513e62015-10-19 15:14:13 +02003 * (C) 2009-2014 by Holger Hans Peter Freyther
4 * (C) 2015 by Sysmocom s.f.m.c. GmbH
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 */
22
23#include <stdlib.h>
24#include <string.h>
25
26#include "../../config.h"
27
28#include <osmocom/vty/command.h>
29#include <osmocom/vty/buffer.h>
30#include <osmocom/vty/vty.h>
31#include <osmocom/vty/telnet_interface.h>
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020032#include <osmocom/vty/telnet_interface.h>
Jacob Erlbeck45513e62015-10-19 15:14:13 +020033#include <osmocom/vty/misc.h>
34
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020035#include <osmocom/core/stats.h>
Harald Welte216338c2017-10-15 19:46:19 +020036#include <osmocom/core/counter.h>
Alexander Couzensad580ba2016-05-16 16:01:45 +020037#include <osmocom/core/rate_ctr.h>
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020038
Jacob Erlbeck45513e62015-10-19 15:14:13 +020039#define CFG_STATS_STR "Configure stats sub-system\n"
40#define CFG_REPORTER_STR "Configure a stats reporter\n"
41
42#define SHOW_STATS_STR "Show statistical values\n"
43
Harald Welte8c648252017-10-16 15:17:03 +020044/*! \file stats_vty.c
Neels Hofmeyr87e45502017-06-20 00:17:59 +020045 * VTY interface for statsd / statistic items
Harald Welte8c648252017-10-16 15:17:03 +020046 *
47 * This code allows you to register a couple of VTY commands that
48 * permit configuration of the \ref stats functionality from the VTY.
49 *
50 * Use \ref osmo_stats_vty_add_cmds once at application start-up to
51 * enable related commands.
Harald Welte96e2a002017-06-12 21:44:18 +020052 */
53
Alexander Couzense052dc22016-10-04 18:04:37 +020054/* containing version info */
55extern struct host host;
56
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020057struct cmd_node cfg_stats_node = {
58 CFG_STATS_NODE,
59 "%s(config-stats)# ",
60 1
61};
62
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +010063static const struct value_string stats_class_strs[] = {
64 { OSMO_STATS_CLASS_GLOBAL, "global" },
65 { OSMO_STATS_CLASS_PEER, "peer" },
66 { OSMO_STATS_CLASS_SUBSCRIBER, "subscriber" },
67 { 0, NULL }
68};
69
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +010070static struct osmo_stats_reporter *osmo_stats_vty2srep(struct vty *vty)
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020071{
72 if (vty->node == CFG_STATS_NODE)
73 return vty->index;
74
75 return NULL;
76}
77
78static int set_srep_parameter_str(struct vty *vty,
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +010079 int (*fun)(struct osmo_stats_reporter *, const char *),
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020080 const char *val, const char *param_name)
81{
82 int rc;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +010083 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020084 OSMO_ASSERT(srep);
85
86 rc = fun(srep, val);
87 if (rc < 0) {
88 vty_out(vty, "%% Unable to set %s: %s%s",
89 param_name, strerror(-rc), VTY_NEWLINE);
90 return CMD_WARNING;
91 }
92
93 return CMD_SUCCESS;
94}
95
96static int set_srep_parameter_int(struct vty *vty,
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +010097 int (*fun)(struct osmo_stats_reporter *, int),
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020098 const char *val, const char *param_name)
99{
100 int rc;
101 int int_val;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100102 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200103 OSMO_ASSERT(srep);
104
105 int_val = atoi(val);
106
107 rc = fun(srep, int_val);
108 if (rc < 0) {
109 vty_out(vty, "%% Unable to set %s: %s%s",
110 param_name, strerror(-rc), VTY_NEWLINE);
111 return CMD_WARNING;
112 }
113
114 return CMD_SUCCESS;
115}
116
117DEFUN(cfg_stats_reporter_local_ip, cfg_stats_reporter_local_ip_cmd,
118 "local-ip ADDR",
119 "Set the IP address to which we bind locally\n"
120 "IP Address\n")
121{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100122 return set_srep_parameter_str(vty, osmo_stats_reporter_set_local_addr,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200123 argv[0], "local address");
124}
125
126DEFUN(cfg_no_stats_reporter_local_ip, cfg_no_stats_reporter_local_ip_cmd,
127 "no local-ip",
128 NO_STR
129 "Set the IP address to which we bind locally\n")
130{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100131 return set_srep_parameter_str(vty, osmo_stats_reporter_set_local_addr,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200132 NULL, "local address");
133}
134
135DEFUN(cfg_stats_reporter_remote_ip, cfg_stats_reporter_remote_ip_cmd,
136 "remote-ip ADDR",
137 "Set the remote IP address to which we connect\n"
138 "IP Address\n")
139{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100140 return set_srep_parameter_str(vty, osmo_stats_reporter_set_remote_addr,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200141 argv[0], "remote address");
142}
143
144DEFUN(cfg_stats_reporter_remote_port, cfg_stats_reporter_remote_port_cmd,
145 "remote-port <1-65535>",
146 "Set the remote port to which we connect\n"
147 "Remote port number\n")
148{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100149 return set_srep_parameter_int(vty, osmo_stats_reporter_set_remote_port,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200150 argv[0], "remote port");
151}
152
Jacob Erlbeckd01acfc2015-10-26 16:22:45 +0100153DEFUN(cfg_stats_reporter_mtu, cfg_stats_reporter_mtu_cmd,
154 "mtu <100-65535>",
155 "Set the maximum packet size\n"
156 "Size in byte\n")
157{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100158 return set_srep_parameter_int(vty, osmo_stats_reporter_set_mtu,
Jacob Erlbeckd01acfc2015-10-26 16:22:45 +0100159 argv[0], "mtu");
160}
161
162DEFUN(cfg_no_stats_reporter_mtu, cfg_no_stats_reporter_mtu_cmd,
163 "no mtu",
164 NO_STR "Set the maximum packet size\n")
165{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100166 return set_srep_parameter_int(vty, osmo_stats_reporter_set_mtu,
Holger Hans Peter Freyther8f0374f2015-11-02 15:53:09 +0100167 "0", "mtu");
Jacob Erlbeckd01acfc2015-10-26 16:22:45 +0100168}
169
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200170DEFUN(cfg_stats_reporter_prefix, cfg_stats_reporter_prefix_cmd,
171 "prefix PREFIX",
172 "Set the item name prefix\n"
173 "The prefix string\n")
174{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100175 return set_srep_parameter_str(vty, osmo_stats_reporter_set_name_prefix,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200176 argv[0], "prefix string");
177}
178
179DEFUN(cfg_no_stats_reporter_prefix, cfg_no_stats_reporter_prefix_cmd,
180 "no prefix",
181 NO_STR
182 "Set the item name prefix\n")
183{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100184 return set_srep_parameter_str(vty, osmo_stats_reporter_set_name_prefix,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200185 "", "prefix string");
186}
187
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100188DEFUN(cfg_stats_reporter_level, cfg_stats_reporter_level_cmd,
189 "level (global|peer|subscriber)",
190 "Set the maximum group level\n"
191 "Report global groups only\n"
192 "Report global and network peer related groups\n"
193 "Report global, peer, and subscriber groups\n")
194{
195 int level = get_string_value(stats_class_strs, argv[0]);
196 int rc;
197 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
198
199 OSMO_ASSERT(srep);
200 rc = osmo_stats_reporter_set_max_class(srep, level);
201 if (rc < 0) {
202 vty_out(vty, "%% Unable to set level: %s%s",
203 strerror(-rc), VTY_NEWLINE);
204 return CMD_WARNING;
205 }
206
207 return 0;
208}
209
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200210DEFUN(cfg_stats_reporter_enable, cfg_stats_reporter_enable_cmd,
211 "enable",
212 "Enable the reporter\n")
213{
214 int rc;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100215 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200216 OSMO_ASSERT(srep);
217
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100218 rc = osmo_stats_reporter_enable(srep);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200219 if (rc < 0) {
220 vty_out(vty, "%% Unable to enable the reporter: %s%s",
221 strerror(-rc), VTY_NEWLINE);
222 return CMD_WARNING;
223 }
224
225 return CMD_SUCCESS;
226}
227
228DEFUN(cfg_stats_reporter_disable, cfg_stats_reporter_disable_cmd,
229 "disable",
230 "Disable the reporter\n")
231{
232 int rc;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100233 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200234 OSMO_ASSERT(srep);
235
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100236 rc = osmo_stats_reporter_disable(srep);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200237 if (rc < 0) {
238 vty_out(vty, "%% Unable to disable the reporter: %s%s",
239 strerror(-rc), VTY_NEWLINE);
240 return CMD_WARNING;
241 }
242
243 return CMD_SUCCESS;
244}
245
246DEFUN(cfg_stats_reporter_statsd, cfg_stats_reporter_statsd_cmd,
247 "stats reporter statsd",
248 CFG_STATS_STR CFG_REPORTER_STR "Report to a STATSD server\n")
249{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100250 struct osmo_stats_reporter *srep;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200251
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100252 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_STATSD, NULL);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200253 if (!srep) {
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100254 srep = osmo_stats_reporter_create_statsd(NULL);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200255 if (!srep) {
256 vty_out(vty, "%% Unable to create statsd reporter%s",
257 VTY_NEWLINE);
258 return CMD_WARNING;
259 }
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100260 srep->max_class = OSMO_STATS_CLASS_GLOBAL;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100261 /* TODO: if needed, add osmo_stats_add_reporter(srep); */
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200262 }
263
264 vty->index = srep;
265 vty->node = CFG_STATS_NODE;
266
267 return CMD_SUCCESS;
268}
269
Jacob Erlbeckb1dbfb42015-10-26 11:58:38 +0100270DEFUN(cfg_stats_interval, cfg_stats_interval_cmd,
271 "stats interval <1-65535>",
272 CFG_STATS_STR "Set the reporting interval\n"
273 "Interval in seconds\n")
274{
275 int rc;
276 int interval = atoi(argv[0]);
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100277 rc = osmo_stats_set_interval(interval);
Jacob Erlbeckb1dbfb42015-10-26 11:58:38 +0100278 if (rc < 0) {
279 vty_out(vty, "%% Unable to set interval: %s%s",
280 strerror(-rc), VTY_NEWLINE);
281 return CMD_WARNING;
282 }
283
284 return CMD_SUCCESS;
285}
286
287
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200288DEFUN(cfg_no_stats_reporter_statsd, cfg_no_stats_reporter_statsd_cmd,
289 "no stats reporter statsd",
290 NO_STR CFG_STATS_STR CFG_REPORTER_STR "Report to a STATSD server\n")
291{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100292 struct osmo_stats_reporter *srep;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200293
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100294 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_STATSD, NULL);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200295 if (!srep) {
296 vty_out(vty, "%% No statsd logging active%s",
297 VTY_NEWLINE);
298 return CMD_WARNING;
299 }
300
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100301 osmo_stats_reporter_free(srep);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200302
303 return CMD_SUCCESS;
304}
305
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100306DEFUN(cfg_stats_reporter_log, cfg_stats_reporter_log_cmd,
307 "stats reporter log",
308 CFG_STATS_STR CFG_REPORTER_STR "Report to the logger\n")
309{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100310 struct osmo_stats_reporter *srep;
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100311
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100312 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_LOG, NULL);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100313 if (!srep) {
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100314 srep = osmo_stats_reporter_create_log(NULL);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100315 if (!srep) {
316 vty_out(vty, "%% Unable to create log reporter%s",
317 VTY_NEWLINE);
318 return CMD_WARNING;
319 }
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100320 srep->max_class = OSMO_STATS_CLASS_GLOBAL;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100321 /* TODO: if needed, add osmo_stats_add_reporter(srep); */
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100322 }
323
324 vty->index = srep;
325 vty->node = CFG_STATS_NODE;
326
327 return CMD_SUCCESS;
328}
329
330DEFUN(cfg_no_stats_reporter_log, cfg_no_stats_reporter_log_cmd,
331 "no stats reporter log",
332 NO_STR CFG_STATS_STR CFG_REPORTER_STR "Report to the logger\n")
333{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100334 struct osmo_stats_reporter *srep;
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100335
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100336 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_LOG, NULL);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100337 if (!srep) {
338 vty_out(vty, "%% No log reporting active%s",
339 VTY_NEWLINE);
340 return CMD_WARNING;
341 }
342
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100343 osmo_stats_reporter_free(srep);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100344
345 return CMD_SUCCESS;
346}
347
Jacob Erlbeck45513e62015-10-19 15:14:13 +0200348DEFUN(show_stats,
349 show_stats_cmd,
350 "show stats",
351 SHOW_STR SHOW_STATS_STR)
352{
353 vty_out_statistics_full(vty, "");
354
355 return CMD_SUCCESS;
356}
357
Jacob Erlbeck59b90bc2015-11-03 16:21:40 +0100358DEFUN(show_stats_level,
359 show_stats_level_cmd,
360 "show stats level (global|peer|subscriber)",
361 SHOW_STR SHOW_STATS_STR
Holger Hans Peter Freyther83481942015-11-07 21:10:01 +0100362 "Set the maximum group level\n"
Jacob Erlbeck59b90bc2015-11-03 16:21:40 +0100363 "Show global groups only\n"
364 "Show global and network peer related groups\n"
365 "Show global, peer, and subscriber groups\n")
366{
367 int level = get_string_value(stats_class_strs, argv[0]);
368 vty_out_statistics_partial(vty, "", level);
369
370 return CMD_SUCCESS;
371}
372
Alexander Couzensad580ba2016-05-16 16:01:45 +0200373static int asciidoc_handle_counter(struct osmo_counter *counter, void *sctx_)
374{
375 struct vty *vty = sctx_;
376 char *name = osmo_asciidoc_escape(counter->name);
377 char *description = osmo_asciidoc_escape(counter->description);
378
379 /* | name | This document & | description | */
380 vty_out(vty, "| %s | <<ungroup_counter_%s>> | %s%s",
381 name,
382 name,
383 description ? description : "",
384 VTY_NEWLINE);
385
386 talloc_free(name);
387 talloc_free(description);
388
389 return 0;
390}
391
392static void asciidoc_counter_generate(struct vty *vty)
393{
394 vty_out(vty, "// ungrouped osmo_counters%s", VTY_NEWLINE);
395 vty_out(vty, ".ungrouped osmo counters%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200396 vty_out(vty, "[options=\"header\"]%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200397 vty_out(vty, "|===%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200398 vty_out(vty, "| Name | Reference | Description%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200399 osmo_counters_for_each(asciidoc_handle_counter, vty);
400 vty_out(vty, "|===%s", VTY_NEWLINE);
401}
402
403static int asciidoc_rate_ctr_handler(
404 struct rate_ctr_group *ctrg, struct rate_ctr *ctr,
405 const struct rate_ctr_desc *desc, void *sctx_)
406{
407 struct vty *vty = sctx_;
408 char *name = osmo_asciidoc_escape(desc->name);
409 char *description = osmo_asciidoc_escape(desc->description);
410 char *group_name_prefix = osmo_asciidoc_escape(ctrg->desc->group_name_prefix);
411
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200412 /* | Name | This document & | Description | */
Alexander Couzensad580ba2016-05-16 16:01:45 +0200413 vty_out(vty, "| %s | <<%s_%s>> | %s%s",
414 name,
415 group_name_prefix,
416 name,
417 description ? description : NULL,
418 VTY_NEWLINE);
419
420 /* description seems to be optional */
421 talloc_free(name);
422 talloc_free(group_name_prefix);
423 talloc_free(description);
424
425 return 0;
426}
427
428static int asciidoc_rate_ctr_group_handler(struct rate_ctr_group *ctrg, void *sctx_)
429{
430 struct vty *vty = sctx_;
431
432 char *group_description = osmo_asciidoc_escape(ctrg->desc->group_description);
433 char *group_name_prefix = osmo_asciidoc_escape(ctrg->desc->group_name_prefix);
434
435 vty_out(vty, "// rate_ctr_group table %s%s", group_description, VTY_NEWLINE);
436 vty_out(vty, ".%s - %s %s", group_name_prefix, group_description, VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200437 vty_out(vty, "[options=\"header\"]%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200438 vty_out(vty, "|===%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200439 vty_out(vty, "| Name | Reference | Description%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200440 rate_ctr_for_each_counter(ctrg, asciidoc_rate_ctr_handler, sctx_);
441 vty_out(vty, "|===%s", VTY_NEWLINE);
442
443 talloc_free(group_name_prefix);
444 talloc_free(group_description);
445
446 return 0;
447}
448
449static int asciidoc_osmo_stat_item_handler(
450 struct osmo_stat_item_group *statg, struct osmo_stat_item *item, void *sctx_)
451{
452 struct vty *vty = sctx_;
453
454 char *name = osmo_asciidoc_escape(item->desc->name);
455 char *description = osmo_asciidoc_escape(item->desc->description);
456 char *group_name_prefix = osmo_asciidoc_escape(statg->desc->group_name_prefix);
457 char *unit = osmo_asciidoc_escape(item->desc->unit);
458
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200459 /* | Name | Reference | Description | Unit | */
Alexander Couzensad580ba2016-05-16 16:01:45 +0200460 vty_out(vty, "| %s | <<%s_%s>> | %s | %s%s",
461 name,
462 group_name_prefix,
463 name,
464 description ? description : "",
465 unit ? unit : "",
466 VTY_NEWLINE);
467
468 talloc_free(name);
469 talloc_free(group_name_prefix);
470 talloc_free(description);
471 talloc_free(unit);
472
473 return 0;
474}
475
476static int asciidoc_osmo_stat_item_group_handler(struct osmo_stat_item_group *statg, void *sctx_)
477{
478 char *group_name_prefix = osmo_asciidoc_escape(statg->desc->group_name_prefix);
479 char *group_description = osmo_asciidoc_escape(statg->desc->group_description);
480
481 struct vty *vty = sctx_;
482 vty_out(vty, "%s%s", group_description ? group_description : "" , VTY_NEWLINE);
483
484 vty_out(vty, "// osmo_stat_item_group table %s%s", group_description ? group_description : "", VTY_NEWLINE);
485 vty_out(vty, ".%s - %s %s", group_name_prefix, group_description ? group_description : "", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200486 vty_out(vty, "[options=\"header\"]%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200487 vty_out(vty, "|===%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200488 vty_out(vty, "| Name | Reference | Description | Unit%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200489 osmo_stat_item_for_each_item(statg, asciidoc_osmo_stat_item_handler, sctx_);
490 vty_out(vty, "|===%s", VTY_NEWLINE);
491
492 talloc_free(group_name_prefix);
493 talloc_free(group_description);
494
495 return 0;
496}
497
498DEFUN(show_stats_asciidoc_table,
499 show_stats_asciidoc_table_cmd,
500 "show asciidoc counters",
Harald Weltef624c332016-06-15 11:35:16 +0200501 SHOW_STR "Asciidoc generation\n" "Generate table of all registered counters\n")
Alexander Couzensad580ba2016-05-16 16:01:45 +0200502{
Alexander Couzense052dc22016-10-04 18:04:37 +0200503 vty_out(vty, "// autogenerated by show asciidoc counters%s", VTY_NEWLINE);
504 vty_out(vty, "These counters and their description based on %s %s (%s).%s%s",
505 host.app_info->name,
506 host.app_info->version,
507 host.app_info->name ? host.app_info->name : "", VTY_NEWLINE, VTY_NEWLINE);
508 /* 2x VTY_NEWLINE are intentional otherwise it would interpret the first table header
509 * as usual text*/
Alexander Couzensad580ba2016-05-16 16:01:45 +0200510 vty_out(vty, "// generating tables for rate_ctr_group%s", VTY_NEWLINE);
511 rate_ctr_for_each_group(asciidoc_rate_ctr_group_handler, vty);
512
513 vty_out(vty, "// generating tables for osmo_stat_items%s", VTY_NEWLINE);
514 osmo_stat_item_for_each_group(asciidoc_osmo_stat_item_group_handler, vty);
515
516 vty_out(vty, "// generating tables for osmo_counters%s", VTY_NEWLINE);
517 asciidoc_counter_generate(vty);
518 return CMD_SUCCESS;
519}
520
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100521static int config_write_stats_reporter(struct vty *vty, struct osmo_stats_reporter *srep)
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200522{
523 if (srep == NULL)
524 return 0;
525
526 switch (srep->type) {
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100527 case OSMO_STATS_REPORTER_STATSD:
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200528 vty_out(vty, "stats reporter statsd%s", VTY_NEWLINE);
529 break;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100530 case OSMO_STATS_REPORTER_LOG:
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100531 vty_out(vty, "stats reporter log%s", VTY_NEWLINE);
532 break;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200533 }
534
535 vty_out(vty, " disable%s", VTY_NEWLINE);
536
Jacob Erlbecked197fd2015-10-27 14:43:24 +0100537 if (srep->have_net_config) {
538 if (srep->dest_addr_str)
539 vty_out(vty, " remote-ip %s%s",
540 srep->dest_addr_str, VTY_NEWLINE);
541 if (srep->dest_port)
542 vty_out(vty, " remote-port %d%s",
543 srep->dest_port, VTY_NEWLINE);
544 if (srep->bind_addr_str)
545 vty_out(vty, " local-ip %s%s",
546 srep->bind_addr_str, VTY_NEWLINE);
547 if (srep->mtu)
548 vty_out(vty, " mtu %d%s",
549 srep->mtu, VTY_NEWLINE);
550 }
551
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100552 if (srep->max_class)
553 vty_out(vty, " level %s%s",
554 get_value_string(stats_class_strs, srep->max_class),
555 VTY_NEWLINE);
556
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200557 if (srep->name_prefix && *srep->name_prefix)
558 vty_out(vty, " prefix %s%s",
559 srep->name_prefix, VTY_NEWLINE);
560 else
561 vty_out(vty, " no prefix%s", VTY_NEWLINE);
562
563 if (srep->enabled)
564 vty_out(vty, " enable%s", VTY_NEWLINE);
565
566 return 1;
567}
568
569static int config_write_stats(struct vty *vty)
570{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100571 struct osmo_stats_reporter *srep;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200572
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100573 /* TODO: loop through all reporters */
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100574 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_STATSD, NULL);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200575 config_write_stats_reporter(vty, srep);
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100576 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_LOG, NULL);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100577 config_write_stats_reporter(vty, srep);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200578
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100579 vty_out(vty, "stats interval %d%s", osmo_stats_config->interval, VTY_NEWLINE);
Jacob Erlbeckb1dbfb42015-10-26 11:58:38 +0100580
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200581 return 1;
582}
583
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200584/*! Add stats related commands to the VTY
Harald Welte96e2a002017-06-12 21:44:18 +0200585 * Call this once during your application initialization if you would
586 * like to have stats VTY commands enabled.
587 */
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100588void osmo_stats_vty_add_cmds()
Jacob Erlbeck45513e62015-10-19 15:14:13 +0200589{
590 install_element_ve(&show_stats_cmd);
Jacob Erlbeck59b90bc2015-11-03 16:21:40 +0100591 install_element_ve(&show_stats_level_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200592
593 install_element(CONFIG_NODE, &cfg_stats_reporter_statsd_cmd);
594 install_element(CONFIG_NODE, &cfg_no_stats_reporter_statsd_cmd);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100595 install_element(CONFIG_NODE, &cfg_stats_reporter_log_cmd);
596 install_element(CONFIG_NODE, &cfg_no_stats_reporter_log_cmd);
Jacob Erlbeckb1dbfb42015-10-26 11:58:38 +0100597 install_element(CONFIG_NODE, &cfg_stats_interval_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200598
599 install_node(&cfg_stats_node, config_write_stats);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200600
601 install_element(CFG_STATS_NODE, &cfg_stats_reporter_local_ip_cmd);
602 install_element(CFG_STATS_NODE, &cfg_no_stats_reporter_local_ip_cmd);
603 install_element(CFG_STATS_NODE, &cfg_stats_reporter_remote_ip_cmd);
604 install_element(CFG_STATS_NODE, &cfg_stats_reporter_remote_port_cmd);
Jacob Erlbeckd01acfc2015-10-26 16:22:45 +0100605 install_element(CFG_STATS_NODE, &cfg_stats_reporter_mtu_cmd);
606 install_element(CFG_STATS_NODE, &cfg_no_stats_reporter_mtu_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200607 install_element(CFG_STATS_NODE, &cfg_stats_reporter_prefix_cmd);
608 install_element(CFG_STATS_NODE, &cfg_no_stats_reporter_prefix_cmd);
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100609 install_element(CFG_STATS_NODE, &cfg_stats_reporter_level_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200610 install_element(CFG_STATS_NODE, &cfg_stats_reporter_enable_cmd);
611 install_element(CFG_STATS_NODE, &cfg_stats_reporter_disable_cmd);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200612
613 install_element_ve(&show_stats_asciidoc_table_cmd);
Jacob Erlbeck45513e62015-10-19 15:14:13 +0200614}