blob: 46282817d6a1113124d5ac984e4ae3fb10e0a7d9 [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
Harald Weltee08da972017-11-13 01:00:26 +09004 * (C) 2015 by sysmocom - s.f.m.c. GmbH
Jacob Erlbeck45513e62015-10-19 15:14:13 +02005 * All Rights Reserved
6 *
Harald Weltee08da972017-11-13 01:00:26 +09007 * SPDX-License-Identifier: GPL-2.0+
8 *
Jacob Erlbeck45513e62015-10-19 15:14:13 +02009 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 *
23 */
24
25#include <stdlib.h>
26#include <string.h>
27
28#include "../../config.h"
29
30#include <osmocom/vty/command.h>
31#include <osmocom/vty/buffer.h>
32#include <osmocom/vty/vty.h>
33#include <osmocom/vty/telnet_interface.h>
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020034#include <osmocom/vty/telnet_interface.h>
Jacob Erlbeck45513e62015-10-19 15:14:13 +020035#include <osmocom/vty/misc.h>
36
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020037#include <osmocom/core/stats.h>
Harald Welte216338c2017-10-15 19:46:19 +020038#include <osmocom/core/counter.h>
Alexander Couzensad580ba2016-05-16 16:01:45 +020039#include <osmocom/core/rate_ctr.h>
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020040
Jacob Erlbeck45513e62015-10-19 15:14:13 +020041#define CFG_STATS_STR "Configure stats sub-system\n"
42#define CFG_REPORTER_STR "Configure a stats reporter\n"
43
44#define SHOW_STATS_STR "Show statistical values\n"
45
Harald Welte8c648252017-10-16 15:17:03 +020046/*! \file stats_vty.c
Neels Hofmeyr87e45502017-06-20 00:17:59 +020047 * VTY interface for statsd / statistic items
Harald Welte8c648252017-10-16 15:17:03 +020048 *
49 * This code allows you to register a couple of VTY commands that
50 * permit configuration of the \ref stats functionality from the VTY.
51 *
52 * Use \ref osmo_stats_vty_add_cmds once at application start-up to
53 * enable related commands.
Harald Welte96e2a002017-06-12 21:44:18 +020054 */
55
Alexander Couzense052dc22016-10-04 18:04:37 +020056/* containing version info */
57extern struct host host;
58
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020059struct cmd_node cfg_stats_node = {
60 CFG_STATS_NODE,
61 "%s(config-stats)# ",
62 1
63};
64
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +010065static const struct value_string stats_class_strs[] = {
66 { OSMO_STATS_CLASS_GLOBAL, "global" },
67 { OSMO_STATS_CLASS_PEER, "peer" },
68 { OSMO_STATS_CLASS_SUBSCRIBER, "subscriber" },
69 { 0, NULL }
70};
71
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +010072static struct osmo_stats_reporter *osmo_stats_vty2srep(struct vty *vty)
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020073{
74 if (vty->node == CFG_STATS_NODE)
75 return vty->index;
76
77 return NULL;
78}
79
80static int set_srep_parameter_str(struct vty *vty,
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +010081 int (*fun)(struct osmo_stats_reporter *, const char *),
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020082 const char *val, const char *param_name)
83{
84 int rc;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +010085 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020086 OSMO_ASSERT(srep);
87
88 rc = fun(srep, val);
89 if (rc < 0) {
90 vty_out(vty, "%% Unable to set %s: %s%s",
91 param_name, strerror(-rc), VTY_NEWLINE);
92 return CMD_WARNING;
93 }
94
95 return CMD_SUCCESS;
96}
97
98static int set_srep_parameter_int(struct vty *vty,
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +010099 int (*fun)(struct osmo_stats_reporter *, int),
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200100 const char *val, const char *param_name)
101{
102 int rc;
103 int int_val;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100104 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200105 OSMO_ASSERT(srep);
106
107 int_val = atoi(val);
108
109 rc = fun(srep, int_val);
110 if (rc < 0) {
111 vty_out(vty, "%% Unable to set %s: %s%s",
112 param_name, strerror(-rc), VTY_NEWLINE);
113 return CMD_WARNING;
114 }
115
116 return CMD_SUCCESS;
117}
118
119DEFUN(cfg_stats_reporter_local_ip, cfg_stats_reporter_local_ip_cmd,
120 "local-ip ADDR",
121 "Set the IP address to which we bind locally\n"
122 "IP Address\n")
123{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100124 return set_srep_parameter_str(vty, osmo_stats_reporter_set_local_addr,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200125 argv[0], "local address");
126}
127
128DEFUN(cfg_no_stats_reporter_local_ip, cfg_no_stats_reporter_local_ip_cmd,
129 "no local-ip",
130 NO_STR
131 "Set the IP address to which we bind locally\n")
132{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100133 return set_srep_parameter_str(vty, osmo_stats_reporter_set_local_addr,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200134 NULL, "local address");
135}
136
137DEFUN(cfg_stats_reporter_remote_ip, cfg_stats_reporter_remote_ip_cmd,
138 "remote-ip ADDR",
139 "Set the remote IP address to which we connect\n"
140 "IP Address\n")
141{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100142 return set_srep_parameter_str(vty, osmo_stats_reporter_set_remote_addr,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200143 argv[0], "remote address");
144}
145
146DEFUN(cfg_stats_reporter_remote_port, cfg_stats_reporter_remote_port_cmd,
147 "remote-port <1-65535>",
148 "Set the remote port to which we connect\n"
149 "Remote port number\n")
150{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100151 return set_srep_parameter_int(vty, osmo_stats_reporter_set_remote_port,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200152 argv[0], "remote port");
153}
154
Jacob Erlbeckd01acfc2015-10-26 16:22:45 +0100155DEFUN(cfg_stats_reporter_mtu, cfg_stats_reporter_mtu_cmd,
156 "mtu <100-65535>",
157 "Set the maximum packet size\n"
158 "Size in byte\n")
159{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100160 return set_srep_parameter_int(vty, osmo_stats_reporter_set_mtu,
Jacob Erlbeckd01acfc2015-10-26 16:22:45 +0100161 argv[0], "mtu");
162}
163
164DEFUN(cfg_no_stats_reporter_mtu, cfg_no_stats_reporter_mtu_cmd,
165 "no mtu",
166 NO_STR "Set the maximum packet size\n")
167{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100168 return set_srep_parameter_int(vty, osmo_stats_reporter_set_mtu,
Holger Hans Peter Freyther8f0374f2015-11-02 15:53:09 +0100169 "0", "mtu");
Jacob Erlbeckd01acfc2015-10-26 16:22:45 +0100170}
171
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200172DEFUN(cfg_stats_reporter_prefix, cfg_stats_reporter_prefix_cmd,
173 "prefix PREFIX",
174 "Set the item name prefix\n"
175 "The prefix string\n")
176{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100177 return set_srep_parameter_str(vty, osmo_stats_reporter_set_name_prefix,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200178 argv[0], "prefix string");
179}
180
181DEFUN(cfg_no_stats_reporter_prefix, cfg_no_stats_reporter_prefix_cmd,
182 "no prefix",
183 NO_STR
184 "Set the item name prefix\n")
185{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100186 return set_srep_parameter_str(vty, osmo_stats_reporter_set_name_prefix,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200187 "", "prefix string");
188}
189
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100190DEFUN(cfg_stats_reporter_level, cfg_stats_reporter_level_cmd,
191 "level (global|peer|subscriber)",
192 "Set the maximum group level\n"
193 "Report global groups only\n"
194 "Report global and network peer related groups\n"
195 "Report global, peer, and subscriber groups\n")
196{
197 int level = get_string_value(stats_class_strs, argv[0]);
198 int rc;
199 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
200
201 OSMO_ASSERT(srep);
202 rc = osmo_stats_reporter_set_max_class(srep, level);
203 if (rc < 0) {
204 vty_out(vty, "%% Unable to set level: %s%s",
205 strerror(-rc), VTY_NEWLINE);
206 return CMD_WARNING;
207 }
208
209 return 0;
210}
211
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200212DEFUN(cfg_stats_reporter_enable, cfg_stats_reporter_enable_cmd,
213 "enable",
214 "Enable the reporter\n")
215{
216 int rc;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100217 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200218 OSMO_ASSERT(srep);
219
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100220 rc = osmo_stats_reporter_enable(srep);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200221 if (rc < 0) {
222 vty_out(vty, "%% Unable to enable the reporter: %s%s",
223 strerror(-rc), VTY_NEWLINE);
224 return CMD_WARNING;
225 }
226
227 return CMD_SUCCESS;
228}
229
230DEFUN(cfg_stats_reporter_disable, cfg_stats_reporter_disable_cmd,
231 "disable",
232 "Disable the reporter\n")
233{
234 int rc;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100235 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200236 OSMO_ASSERT(srep);
237
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100238 rc = osmo_stats_reporter_disable(srep);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200239 if (rc < 0) {
240 vty_out(vty, "%% Unable to disable the reporter: %s%s",
241 strerror(-rc), VTY_NEWLINE);
242 return CMD_WARNING;
243 }
244
245 return CMD_SUCCESS;
246}
247
Alexander Chemerisdfebf402020-05-08 19:10:40 +0300248DEFUN(cfg_stats_reporter_flush_period, cfg_stats_reporter_flush_period_cmd,
249 "flush-period <0-65535>",
250 CFG_STATS_STR "Send all stats even if they have not changed (i.e. force the flush)"
251 "every N-th reporting interval. Set to 0 to disable regular flush (default).\n"
252 "0 to disable regular flush (default), 1 to flush every time, 2 to flush every 2nd time, etc\n")
253{
254 int rc;
255 unsigned int period = atoi(argv[0]);
256 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
257 OSMO_ASSERT(srep);
258
259 rc = osmo_stats_reporter_set_flush_period(srep, period);
260 if (rc < 0) {
261 vty_out(vty, "%% Unable to set force flush period: %s%s",
262 strerror(-rc), VTY_NEWLINE);
263 return CMD_WARNING;
264 }
265
266 return CMD_SUCCESS;
267}
268
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200269DEFUN(cfg_stats_reporter_statsd, cfg_stats_reporter_statsd_cmd,
270 "stats reporter statsd",
271 CFG_STATS_STR CFG_REPORTER_STR "Report to a STATSD server\n")
272{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100273 struct osmo_stats_reporter *srep;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200274
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100275 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_STATSD, NULL);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200276 if (!srep) {
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100277 srep = osmo_stats_reporter_create_statsd(NULL);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200278 if (!srep) {
279 vty_out(vty, "%% Unable to create statsd reporter%s",
280 VTY_NEWLINE);
281 return CMD_WARNING;
282 }
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100283 srep->max_class = OSMO_STATS_CLASS_GLOBAL;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100284 /* TODO: if needed, add osmo_stats_add_reporter(srep); */
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200285 }
286
287 vty->index = srep;
288 vty->node = CFG_STATS_NODE;
289
290 return CMD_SUCCESS;
291}
292
293DEFUN(cfg_no_stats_reporter_statsd, cfg_no_stats_reporter_statsd_cmd,
294 "no stats reporter statsd",
295 NO_STR CFG_STATS_STR CFG_REPORTER_STR "Report to a STATSD server\n")
296{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100297 struct osmo_stats_reporter *srep;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200298
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100299 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_STATSD, NULL);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200300 if (!srep) {
301 vty_out(vty, "%% No statsd logging active%s",
302 VTY_NEWLINE);
303 return CMD_WARNING;
304 }
305
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100306 osmo_stats_reporter_free(srep);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200307
308 return CMD_SUCCESS;
309}
310
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100311DEFUN(cfg_stats_reporter_log, cfg_stats_reporter_log_cmd,
312 "stats reporter log",
313 CFG_STATS_STR CFG_REPORTER_STR "Report to the logger\n")
314{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100315 struct osmo_stats_reporter *srep;
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100316
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100317 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_LOG, NULL);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100318 if (!srep) {
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100319 srep = osmo_stats_reporter_create_log(NULL);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100320 if (!srep) {
321 vty_out(vty, "%% Unable to create log reporter%s",
322 VTY_NEWLINE);
323 return CMD_WARNING;
324 }
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100325 srep->max_class = OSMO_STATS_CLASS_GLOBAL;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100326 /* TODO: if needed, add osmo_stats_add_reporter(srep); */
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100327 }
328
329 vty->index = srep;
330 vty->node = CFG_STATS_NODE;
331
332 return CMD_SUCCESS;
333}
334
335DEFUN(cfg_no_stats_reporter_log, cfg_no_stats_reporter_log_cmd,
336 "no stats reporter log",
337 NO_STR CFG_STATS_STR CFG_REPORTER_STR "Report to the logger\n")
338{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100339 struct osmo_stats_reporter *srep;
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100340
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100341 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_LOG, NULL);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100342 if (!srep) {
343 vty_out(vty, "%% No log reporting active%s",
344 VTY_NEWLINE);
345 return CMD_WARNING;
346 }
347
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100348 osmo_stats_reporter_free(srep);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100349
350 return CMD_SUCCESS;
351}
352
Alexander Chemeris161adee2020-05-08 18:19:24 +0300353DEFUN(cfg_stats_interval, cfg_stats_interval_cmd,
354 "stats interval <1-65535>",
355 CFG_STATS_STR "Set the reporting interval\n"
356 "Interval in seconds\n")
357{
358 int rc;
359 int interval = atoi(argv[0]);
360 rc = osmo_stats_set_interval(interval);
361 if (rc < 0) {
362 vty_out(vty, "%% Unable to set interval: %s%s",
363 strerror(-rc), VTY_NEWLINE);
364 return CMD_WARNING;
365 }
366
367 return CMD_SUCCESS;
368}
369
Jacob Erlbeck45513e62015-10-19 15:14:13 +0200370DEFUN(show_stats,
371 show_stats_cmd,
372 "show stats",
373 SHOW_STR SHOW_STATS_STR)
374{
375 vty_out_statistics_full(vty, "");
376
377 return CMD_SUCCESS;
378}
379
Jacob Erlbeck59b90bc2015-11-03 16:21:40 +0100380DEFUN(show_stats_level,
381 show_stats_level_cmd,
382 "show stats level (global|peer|subscriber)",
383 SHOW_STR SHOW_STATS_STR
Holger Hans Peter Freyther83481942015-11-07 21:10:01 +0100384 "Set the maximum group level\n"
Jacob Erlbeck59b90bc2015-11-03 16:21:40 +0100385 "Show global groups only\n"
386 "Show global and network peer related groups\n"
387 "Show global, peer, and subscriber groups\n")
388{
389 int level = get_string_value(stats_class_strs, argv[0]);
390 vty_out_statistics_partial(vty, "", level);
391
392 return CMD_SUCCESS;
393}
394
Alexander Couzensad580ba2016-05-16 16:01:45 +0200395static int asciidoc_handle_counter(struct osmo_counter *counter, void *sctx_)
396{
397 struct vty *vty = sctx_;
398 char *name = osmo_asciidoc_escape(counter->name);
399 char *description = osmo_asciidoc_escape(counter->description);
400
401 /* | name | This document & | description | */
402 vty_out(vty, "| %s | <<ungroup_counter_%s>> | %s%s",
403 name,
404 name,
405 description ? description : "",
406 VTY_NEWLINE);
407
408 talloc_free(name);
409 talloc_free(description);
410
411 return 0;
412}
413
414static void asciidoc_counter_generate(struct vty *vty)
415{
Alexander Couzens06dbdf52017-12-05 16:12:14 +0100416 if (osmo_counters_count() == 0)
417 {
418 vty_out(vty, "// there are no ungrouped osmo_counters%s",
419 VTY_NEWLINE);
420 return;
421 }
422
Alexander Couzensad580ba2016-05-16 16:01:45 +0200423 vty_out(vty, "// ungrouped osmo_counters%s", VTY_NEWLINE);
424 vty_out(vty, ".ungrouped osmo counters%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200425 vty_out(vty, "[options=\"header\"]%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200426 vty_out(vty, "|===%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200427 vty_out(vty, "| Name | Reference | Description%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200428 osmo_counters_for_each(asciidoc_handle_counter, vty);
429 vty_out(vty, "|===%s", VTY_NEWLINE);
430}
431
432static int asciidoc_rate_ctr_handler(
433 struct rate_ctr_group *ctrg, struct rate_ctr *ctr,
434 const struct rate_ctr_desc *desc, void *sctx_)
435{
436 struct vty *vty = sctx_;
437 char *name = osmo_asciidoc_escape(desc->name);
438 char *description = osmo_asciidoc_escape(desc->description);
439 char *group_name_prefix = osmo_asciidoc_escape(ctrg->desc->group_name_prefix);
440
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200441 /* | Name | This document & | Description | */
Alexander Couzensad580ba2016-05-16 16:01:45 +0200442 vty_out(vty, "| %s | <<%s_%s>> | %s%s",
443 name,
444 group_name_prefix,
445 name,
446 description ? description : NULL,
447 VTY_NEWLINE);
448
449 /* description seems to be optional */
450 talloc_free(name);
451 talloc_free(group_name_prefix);
452 talloc_free(description);
453
454 return 0;
455}
456
457static int asciidoc_rate_ctr_group_handler(struct rate_ctr_group *ctrg, void *sctx_)
458{
459 struct vty *vty = sctx_;
460
461 char *group_description = osmo_asciidoc_escape(ctrg->desc->group_description);
462 char *group_name_prefix = osmo_asciidoc_escape(ctrg->desc->group_name_prefix);
463
464 vty_out(vty, "// rate_ctr_group table %s%s", group_description, VTY_NEWLINE);
Pau Espin Pedrol18e019e2019-06-19 14:24:27 +0200465 vty_out(vty, ".%s - %s%s", group_name_prefix, group_description, VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200466 vty_out(vty, "[options=\"header\"]%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200467 vty_out(vty, "|===%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200468 vty_out(vty, "| Name | Reference | Description%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200469 rate_ctr_for_each_counter(ctrg, asciidoc_rate_ctr_handler, sctx_);
470 vty_out(vty, "|===%s", VTY_NEWLINE);
471
472 talloc_free(group_name_prefix);
473 talloc_free(group_description);
474
475 return 0;
476}
477
478static int asciidoc_osmo_stat_item_handler(
479 struct osmo_stat_item_group *statg, struct osmo_stat_item *item, void *sctx_)
480{
481 struct vty *vty = sctx_;
482
483 char *name = osmo_asciidoc_escape(item->desc->name);
484 char *description = osmo_asciidoc_escape(item->desc->description);
485 char *group_name_prefix = osmo_asciidoc_escape(statg->desc->group_name_prefix);
486 char *unit = osmo_asciidoc_escape(item->desc->unit);
487
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200488 /* | Name | Reference | Description | Unit | */
Alexander Couzensad580ba2016-05-16 16:01:45 +0200489 vty_out(vty, "| %s | <<%s_%s>> | %s | %s%s",
490 name,
491 group_name_prefix,
492 name,
493 description ? description : "",
494 unit ? unit : "",
495 VTY_NEWLINE);
496
497 talloc_free(name);
498 talloc_free(group_name_prefix);
499 talloc_free(description);
500 talloc_free(unit);
501
502 return 0;
503}
504
505static int asciidoc_osmo_stat_item_group_handler(struct osmo_stat_item_group *statg, void *sctx_)
506{
507 char *group_name_prefix = osmo_asciidoc_escape(statg->desc->group_name_prefix);
508 char *group_description = osmo_asciidoc_escape(statg->desc->group_description);
509
510 struct vty *vty = sctx_;
511 vty_out(vty, "%s%s", group_description ? group_description : "" , VTY_NEWLINE);
512
513 vty_out(vty, "// osmo_stat_item_group table %s%s", group_description ? group_description : "", VTY_NEWLINE);
Pau Espin Pedrol18e019e2019-06-19 14:24:27 +0200514 vty_out(vty, ".%s - %s%s", group_name_prefix, group_description ? group_description : "", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200515 vty_out(vty, "[options=\"header\"]%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200516 vty_out(vty, "|===%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200517 vty_out(vty, "| Name | Reference | Description | Unit%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200518 osmo_stat_item_for_each_item(statg, asciidoc_osmo_stat_item_handler, sctx_);
519 vty_out(vty, "|===%s", VTY_NEWLINE);
520
521 talloc_free(group_name_prefix);
522 talloc_free(group_description);
523
524 return 0;
525}
526
527DEFUN(show_stats_asciidoc_table,
528 show_stats_asciidoc_table_cmd,
529 "show asciidoc counters",
Harald Weltef624c332016-06-15 11:35:16 +0200530 SHOW_STR "Asciidoc generation\n" "Generate table of all registered counters\n")
Alexander Couzensad580ba2016-05-16 16:01:45 +0200531{
Alexander Couzense052dc22016-10-04 18:04:37 +0200532 vty_out(vty, "// autogenerated by show asciidoc counters%s", VTY_NEWLINE);
Daniel Willmann6f3bbd42019-07-25 11:33:50 +0200533 vty_out(vty, "These counters and their description are based on %s %s (%s).%s%s",
Alexander Couzense052dc22016-10-04 18:04:37 +0200534 host.app_info->name,
535 host.app_info->version,
536 host.app_info->name ? host.app_info->name : "", VTY_NEWLINE, VTY_NEWLINE);
537 /* 2x VTY_NEWLINE are intentional otherwise it would interpret the first table header
538 * as usual text*/
Daniel Willmannd910a352018-07-24 20:01:26 +0200539 vty_out(vty, "=== Rate Counters%s%s", VTY_NEWLINE, VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200540 vty_out(vty, "// generating tables for rate_ctr_group%s", VTY_NEWLINE);
541 rate_ctr_for_each_group(asciidoc_rate_ctr_group_handler, vty);
542
Daniel Willmannd910a352018-07-24 20:01:26 +0200543 vty_out(vty, "== Osmo Stat Items%s%s", VTY_NEWLINE, VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200544 vty_out(vty, "// generating tables for osmo_stat_items%s", VTY_NEWLINE);
545 osmo_stat_item_for_each_group(asciidoc_osmo_stat_item_group_handler, vty);
546
Daniel Willmannd910a352018-07-24 20:01:26 +0200547 vty_out(vty, "== Osmo Counters%s%s", VTY_NEWLINE, VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200548 vty_out(vty, "// generating tables for osmo_counters%s", VTY_NEWLINE);
549 asciidoc_counter_generate(vty);
550 return CMD_SUCCESS;
551}
552
Stefan Sperling73b7fa62018-05-24 18:40:03 +0200553static int rate_ctr_group_handler(struct rate_ctr_group *ctrg, void *sctx_)
554{
555 struct vty *vty = sctx_;
Stefan Sperling84eb1ab2018-10-29 17:50:30 +0100556 vty_out(vty, "%s %u:%s", ctrg->desc->group_description, ctrg->idx, VTY_NEWLINE);
Stefan Sperling73b7fa62018-05-24 18:40:03 +0200557 vty_out_rate_ctr_group_fmt(vty, "%25n: %10c (%S/s %M/m %H/h %D/d) %d", ctrg);
558 return 0;
559}
560
561DEFUN(show_rate_counters,
562 show_rate_counters_cmd,
563 "show rate-counters",
564 SHOW_STR "Show all rate counters\n")
565{
566 rate_ctr_for_each_group(rate_ctr_group_handler, vty);
567 return CMD_SUCCESS;
568}
569
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100570static int config_write_stats_reporter(struct vty *vty, struct osmo_stats_reporter *srep)
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200571{
572 if (srep == NULL)
573 return 0;
574
575 switch (srep->type) {
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100576 case OSMO_STATS_REPORTER_STATSD:
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200577 vty_out(vty, "stats reporter statsd%s", VTY_NEWLINE);
578 break;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100579 case OSMO_STATS_REPORTER_LOG:
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100580 vty_out(vty, "stats reporter log%s", VTY_NEWLINE);
581 break;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200582 }
583
584 vty_out(vty, " disable%s", VTY_NEWLINE);
585
Jacob Erlbecked197fd2015-10-27 14:43:24 +0100586 if (srep->have_net_config) {
587 if (srep->dest_addr_str)
588 vty_out(vty, " remote-ip %s%s",
589 srep->dest_addr_str, VTY_NEWLINE);
590 if (srep->dest_port)
591 vty_out(vty, " remote-port %d%s",
592 srep->dest_port, VTY_NEWLINE);
593 if (srep->bind_addr_str)
594 vty_out(vty, " local-ip %s%s",
595 srep->bind_addr_str, VTY_NEWLINE);
596 if (srep->mtu)
597 vty_out(vty, " mtu %d%s",
598 srep->mtu, VTY_NEWLINE);
599 }
600
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100601 if (srep->max_class)
602 vty_out(vty, " level %s%s",
603 get_value_string(stats_class_strs, srep->max_class),
604 VTY_NEWLINE);
605
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200606 if (srep->name_prefix && *srep->name_prefix)
607 vty_out(vty, " prefix %s%s",
608 srep->name_prefix, VTY_NEWLINE);
609 else
610 vty_out(vty, " no prefix%s", VTY_NEWLINE);
611
Alexander Chemerisdfebf402020-05-08 19:10:40 +0300612 if (srep->flush_period > 0)
613 vty_out(vty, " flush-period %d%s",
614 srep->flush_period, VTY_NEWLINE);
615
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200616 if (srep->enabled)
617 vty_out(vty, " enable%s", VTY_NEWLINE);
618
619 return 1;
620}
621
622static int config_write_stats(struct vty *vty)
623{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100624 struct osmo_stats_reporter *srep;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200625
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100626 /* TODO: loop through all reporters */
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100627 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_STATSD, NULL);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200628 config_write_stats_reporter(vty, srep);
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100629 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_LOG, NULL);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100630 config_write_stats_reporter(vty, srep);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200631
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100632 vty_out(vty, "stats interval %d%s", osmo_stats_config->interval, VTY_NEWLINE);
Jacob Erlbeckb1dbfb42015-10-26 11:58:38 +0100633
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200634 return 1;
635}
636
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200637/*! Add stats related commands to the VTY
Harald Welte96e2a002017-06-12 21:44:18 +0200638 * Call this once during your application initialization if you would
639 * like to have stats VTY commands enabled.
640 */
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100641void osmo_stats_vty_add_cmds()
Jacob Erlbeck45513e62015-10-19 15:14:13 +0200642{
643 install_element_ve(&show_stats_cmd);
Jacob Erlbeck59b90bc2015-11-03 16:21:40 +0100644 install_element_ve(&show_stats_level_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200645
646 install_element(CONFIG_NODE, &cfg_stats_reporter_statsd_cmd);
647 install_element(CONFIG_NODE, &cfg_no_stats_reporter_statsd_cmd);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100648 install_element(CONFIG_NODE, &cfg_stats_reporter_log_cmd);
649 install_element(CONFIG_NODE, &cfg_no_stats_reporter_log_cmd);
Jacob Erlbeckb1dbfb42015-10-26 11:58:38 +0100650 install_element(CONFIG_NODE, &cfg_stats_interval_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200651
652 install_node(&cfg_stats_node, config_write_stats);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200653
654 install_element(CFG_STATS_NODE, &cfg_stats_reporter_local_ip_cmd);
655 install_element(CFG_STATS_NODE, &cfg_no_stats_reporter_local_ip_cmd);
656 install_element(CFG_STATS_NODE, &cfg_stats_reporter_remote_ip_cmd);
657 install_element(CFG_STATS_NODE, &cfg_stats_reporter_remote_port_cmd);
Jacob Erlbeckd01acfc2015-10-26 16:22:45 +0100658 install_element(CFG_STATS_NODE, &cfg_stats_reporter_mtu_cmd);
659 install_element(CFG_STATS_NODE, &cfg_no_stats_reporter_mtu_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200660 install_element(CFG_STATS_NODE, &cfg_stats_reporter_prefix_cmd);
661 install_element(CFG_STATS_NODE, &cfg_no_stats_reporter_prefix_cmd);
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100662 install_element(CFG_STATS_NODE, &cfg_stats_reporter_level_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200663 install_element(CFG_STATS_NODE, &cfg_stats_reporter_enable_cmd);
664 install_element(CFG_STATS_NODE, &cfg_stats_reporter_disable_cmd);
Alexander Chemerisdfebf402020-05-08 19:10:40 +0300665 install_element(CFG_STATS_NODE, &cfg_stats_reporter_flush_period_cmd);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200666
667 install_element_ve(&show_stats_asciidoc_table_cmd);
Stefan Sperling73b7fa62018-05-24 18:40:03 +0200668 install_element_ve(&show_rate_counters_cmd);
Jacob Erlbeck45513e62015-10-19 15:14:13 +0200669}