blob: a73fafbb344016f7dac26ed571422b800fde3ac8 [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 *
Jacob Erlbeck45513e62015-10-19 15:14:13 +020019 */
20
21#include <stdlib.h>
22#include <string.h>
23
24#include "../../config.h"
25
26#include <osmocom/vty/command.h>
27#include <osmocom/vty/buffer.h>
28#include <osmocom/vty/vty.h>
29#include <osmocom/vty/telnet_interface.h>
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020030#include <osmocom/vty/telnet_interface.h>
Jacob Erlbeck45513e62015-10-19 15:14:13 +020031#include <osmocom/vty/misc.h>
32
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020033#include <osmocom/core/stats.h>
Harald Welte216338c2017-10-15 19:46:19 +020034#include <osmocom/core/counter.h>
Alexander Couzensad580ba2016-05-16 16:01:45 +020035#include <osmocom/core/rate_ctr.h>
Philipp Maierb1ef8f52021-12-06 16:31:02 +010036#include <osmocom/core/stats_tcp.h>
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020037
Jacob Erlbeck45513e62015-10-19 15:14:13 +020038#define CFG_STATS_STR "Configure stats sub-system\n"
39#define CFG_REPORTER_STR "Configure a stats reporter\n"
40
41#define SHOW_STATS_STR "Show statistical values\n"
42
Daniel Willmann1a1de332020-07-14 18:11:14 +020043#define STATS_STR "Stats related commands\n"
44
Harald Welte8c648252017-10-16 15:17:03 +020045/*! \file stats_vty.c
Neels Hofmeyr87e45502017-06-20 00:17:59 +020046 * VTY interface for statsd / statistic items
Harald Welte8c648252017-10-16 15:17:03 +020047 *
48 * This code allows you to register a couple of VTY commands that
49 * permit configuration of the \ref stats functionality from the VTY.
50 *
51 * Use \ref osmo_stats_vty_add_cmds once at application start-up to
52 * enable related commands.
Harald Welte96e2a002017-06-12 21:44:18 +020053 */
54
Alexander Couzense052dc22016-10-04 18:04:37 +020055/* containing version info */
56extern struct host host;
57
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020058struct cmd_node cfg_stats_node = {
59 CFG_STATS_NODE,
60 "%s(config-stats)# ",
61 1
62};
63
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +010064static const struct value_string stats_class_strs[] = {
65 { OSMO_STATS_CLASS_GLOBAL, "global" },
66 { OSMO_STATS_CLASS_PEER, "peer" },
67 { OSMO_STATS_CLASS_SUBSCRIBER, "subscriber" },
68 { 0, NULL }
69};
70
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +010071static struct osmo_stats_reporter *osmo_stats_vty2srep(struct vty *vty)
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020072{
73 if (vty->node == CFG_STATS_NODE)
74 return vty->index;
75
76 return NULL;
77}
78
79static int set_srep_parameter_str(struct vty *vty,
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +010080 int (*fun)(struct osmo_stats_reporter *, const char *),
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020081 const char *val, const char *param_name)
82{
83 int rc;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +010084 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020085 OSMO_ASSERT(srep);
86
87 rc = fun(srep, val);
88 if (rc < 0) {
89 vty_out(vty, "%% Unable to set %s: %s%s",
90 param_name, strerror(-rc), VTY_NEWLINE);
91 return CMD_WARNING;
92 }
93
94 return CMD_SUCCESS;
95}
96
97static int set_srep_parameter_int(struct vty *vty,
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +010098 int (*fun)(struct osmo_stats_reporter *, int),
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020099 const char *val, const char *param_name)
100{
101 int rc;
102 int int_val;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100103 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200104 OSMO_ASSERT(srep);
105
106 int_val = atoi(val);
107
108 rc = fun(srep, int_val);
109 if (rc < 0) {
110 vty_out(vty, "%% Unable to set %s: %s%s",
111 param_name, strerror(-rc), VTY_NEWLINE);
112 return CMD_WARNING;
113 }
114
115 return CMD_SUCCESS;
116}
117
118DEFUN(cfg_stats_reporter_local_ip, cfg_stats_reporter_local_ip_cmd,
119 "local-ip ADDR",
120 "Set the IP address to which we bind locally\n"
121 "IP Address\n")
122{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100123 return set_srep_parameter_str(vty, osmo_stats_reporter_set_local_addr,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200124 argv[0], "local address");
125}
126
127DEFUN(cfg_no_stats_reporter_local_ip, cfg_no_stats_reporter_local_ip_cmd,
128 "no local-ip",
129 NO_STR
130 "Set the IP address to which we bind locally\n")
131{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100132 return set_srep_parameter_str(vty, osmo_stats_reporter_set_local_addr,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200133 NULL, "local address");
134}
135
136DEFUN(cfg_stats_reporter_remote_ip, cfg_stats_reporter_remote_ip_cmd,
137 "remote-ip ADDR",
138 "Set the remote IP address to which we connect\n"
139 "IP Address\n")
140{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100141 return set_srep_parameter_str(vty, osmo_stats_reporter_set_remote_addr,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200142 argv[0], "remote address");
143}
144
145DEFUN(cfg_stats_reporter_remote_port, cfg_stats_reporter_remote_port_cmd,
146 "remote-port <1-65535>",
147 "Set the remote port to which we connect\n"
148 "Remote port number\n")
149{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100150 return set_srep_parameter_int(vty, osmo_stats_reporter_set_remote_port,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200151 argv[0], "remote port");
152}
153
Jacob Erlbeckd01acfc2015-10-26 16:22:45 +0100154DEFUN(cfg_stats_reporter_mtu, cfg_stats_reporter_mtu_cmd,
155 "mtu <100-65535>",
156 "Set the maximum packet size\n"
157 "Size in byte\n")
158{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100159 return set_srep_parameter_int(vty, osmo_stats_reporter_set_mtu,
Jacob Erlbeckd01acfc2015-10-26 16:22:45 +0100160 argv[0], "mtu");
161}
162
163DEFUN(cfg_no_stats_reporter_mtu, cfg_no_stats_reporter_mtu_cmd,
164 "no mtu",
165 NO_STR "Set the maximum packet size\n")
166{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100167 return set_srep_parameter_int(vty, osmo_stats_reporter_set_mtu,
Holger Hans Peter Freyther8f0374f2015-11-02 15:53:09 +0100168 "0", "mtu");
Jacob Erlbeckd01acfc2015-10-26 16:22:45 +0100169}
170
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200171DEFUN(cfg_stats_reporter_prefix, cfg_stats_reporter_prefix_cmd,
172 "prefix PREFIX",
173 "Set the item name prefix\n"
174 "The prefix string\n")
175{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100176 return set_srep_parameter_str(vty, osmo_stats_reporter_set_name_prefix,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200177 argv[0], "prefix string");
178}
179
180DEFUN(cfg_no_stats_reporter_prefix, cfg_no_stats_reporter_prefix_cmd,
181 "no prefix",
182 NO_STR
183 "Set the item name prefix\n")
184{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100185 return set_srep_parameter_str(vty, osmo_stats_reporter_set_name_prefix,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200186 "", "prefix string");
187}
188
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100189DEFUN(cfg_stats_reporter_level, cfg_stats_reporter_level_cmd,
190 "level (global|peer|subscriber)",
191 "Set the maximum group level\n"
192 "Report global groups only\n"
193 "Report global and network peer related groups\n"
194 "Report global, peer, and subscriber groups\n")
195{
196 int level = get_string_value(stats_class_strs, argv[0]);
197 int rc;
198 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
199
200 OSMO_ASSERT(srep);
201 rc = osmo_stats_reporter_set_max_class(srep, level);
202 if (rc < 0) {
203 vty_out(vty, "%% Unable to set level: %s%s",
204 strerror(-rc), VTY_NEWLINE);
205 return CMD_WARNING;
206 }
207
208 return 0;
209}
210
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200211DEFUN(cfg_stats_reporter_enable, cfg_stats_reporter_enable_cmd,
212 "enable",
213 "Enable the reporter\n")
214{
215 int rc;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100216 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200217 OSMO_ASSERT(srep);
218
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100219 rc = osmo_stats_reporter_enable(srep);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200220 if (rc < 0) {
221 vty_out(vty, "%% Unable to enable the reporter: %s%s",
222 strerror(-rc), VTY_NEWLINE);
223 return CMD_WARNING;
224 }
225
226 return CMD_SUCCESS;
227}
228
229DEFUN(cfg_stats_reporter_disable, cfg_stats_reporter_disable_cmd,
230 "disable",
231 "Disable the reporter\n")
232{
233 int rc;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100234 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200235 OSMO_ASSERT(srep);
236
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100237 rc = osmo_stats_reporter_disable(srep);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200238 if (rc < 0) {
239 vty_out(vty, "%% Unable to disable the reporter: %s%s",
240 strerror(-rc), VTY_NEWLINE);
241 return CMD_WARNING;
242 }
243
244 return CMD_SUCCESS;
245}
246
Alexander Chemerisdfebf402020-05-08 19:10:40 +0300247DEFUN(cfg_stats_reporter_flush_period, cfg_stats_reporter_flush_period_cmd,
248 "flush-period <0-65535>",
249 CFG_STATS_STR "Send all stats even if they have not changed (i.e. force the flush)"
250 "every N-th reporting interval. Set to 0 to disable regular flush (default).\n"
251 "0 to disable regular flush (default), 1 to flush every time, 2 to flush every 2nd time, etc\n")
252{
253 int rc;
254 unsigned int period = atoi(argv[0]);
255 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
256 OSMO_ASSERT(srep);
257
258 rc = osmo_stats_reporter_set_flush_period(srep, period);
259 if (rc < 0) {
260 vty_out(vty, "%% Unable to set force flush period: %s%s",
261 strerror(-rc), VTY_NEWLINE);
262 return CMD_WARNING;
263 }
264
265 return CMD_SUCCESS;
266}
267
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200268DEFUN(cfg_stats_reporter_statsd, cfg_stats_reporter_statsd_cmd,
Vadim Yanitskiybfc83772021-11-08 23:14:29 +0300269 "stats reporter statsd [NAME]",
270 CFG_STATS_STR CFG_REPORTER_STR
271 "Report to a STATSD server\n"
272 "Name of the reporter\n")
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200273{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100274 struct osmo_stats_reporter *srep;
Vadim Yanitskiybfc83772021-11-08 23:14:29 +0300275 const char *name = NULL;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200276
Vadim Yanitskiybfc83772021-11-08 23:14:29 +0300277 if (argc > 0)
278 name = argv[0];
279
280 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_STATSD, name);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200281 if (!srep) {
Vadim Yanitskiybfc83772021-11-08 23:14:29 +0300282 srep = osmo_stats_reporter_create_statsd(name);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200283 if (!srep) {
284 vty_out(vty, "%% Unable to create statsd reporter%s",
285 VTY_NEWLINE);
286 return CMD_WARNING;
287 }
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100288 srep->max_class = OSMO_STATS_CLASS_GLOBAL;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100289 /* TODO: if needed, add osmo_stats_add_reporter(srep); */
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200290 }
291
292 vty->index = srep;
293 vty->node = CFG_STATS_NODE;
294
295 return CMD_SUCCESS;
296}
297
298DEFUN(cfg_no_stats_reporter_statsd, cfg_no_stats_reporter_statsd_cmd,
Vadim Yanitskiybfc83772021-11-08 23:14:29 +0300299 "no stats reporter statsd [NAME]",
300 NO_STR CFG_STATS_STR CFG_REPORTER_STR
301 "Report to a STATSD server\n"
302 "Name of the reporter\n")
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200303{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100304 struct osmo_stats_reporter *srep;
Vadim Yanitskiybfc83772021-11-08 23:14:29 +0300305 const char *name = NULL;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200306
Vadim Yanitskiybfc83772021-11-08 23:14:29 +0300307 if (argc > 0)
308 name = argv[0];
309
310 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_STATSD, name);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200311 if (!srep) {
Vadim Yanitskiy52a5c112021-11-09 13:59:20 +0300312 vty_out(vty, "%% There is no such statsd reporter with name '%s'%s",
313 name ? name : "", VTY_NEWLINE);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200314 return CMD_WARNING;
315 }
316
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100317 osmo_stats_reporter_free(srep);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200318
319 return CMD_SUCCESS;
320}
321
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100322DEFUN(cfg_stats_reporter_log, cfg_stats_reporter_log_cmd,
Vadim Yanitskiybfc83772021-11-08 23:14:29 +0300323 "stats reporter log [NAME]",
324 CFG_STATS_STR CFG_REPORTER_STR
325 "Report to the logger\n"
326 "Name of the reporter\n")
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100327{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100328 struct osmo_stats_reporter *srep;
Vadim Yanitskiybfc83772021-11-08 23:14:29 +0300329 const char *name = NULL;
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100330
Vadim Yanitskiybfc83772021-11-08 23:14:29 +0300331 if (argc > 0)
332 name = argv[0];
333
334 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_LOG, name);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100335 if (!srep) {
Vadim Yanitskiybfc83772021-11-08 23:14:29 +0300336 srep = osmo_stats_reporter_create_log(name);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100337 if (!srep) {
338 vty_out(vty, "%% Unable to create log reporter%s",
339 VTY_NEWLINE);
340 return CMD_WARNING;
341 }
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100342 srep->max_class = OSMO_STATS_CLASS_GLOBAL;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100343 /* TODO: if needed, add osmo_stats_add_reporter(srep); */
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100344 }
345
346 vty->index = srep;
347 vty->node = CFG_STATS_NODE;
348
349 return CMD_SUCCESS;
350}
351
352DEFUN(cfg_no_stats_reporter_log, cfg_no_stats_reporter_log_cmd,
Vadim Yanitskiybfc83772021-11-08 23:14:29 +0300353 "no stats reporter log [NAME]",
354 NO_STR CFG_STATS_STR CFG_REPORTER_STR
355 "Report to the logger\n"
356 "Name of the reporter\n")
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100357{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100358 struct osmo_stats_reporter *srep;
Vadim Yanitskiybfc83772021-11-08 23:14:29 +0300359 const char *name = NULL;
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100360
Vadim Yanitskiybfc83772021-11-08 23:14:29 +0300361 if (argc > 0)
362 name = argv[0];
363
364 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_LOG, name);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100365 if (!srep) {
Vadim Yanitskiy52a5c112021-11-09 13:59:20 +0300366 vty_out(vty, "%% There is no such log reporter with name '%s'%s",
367 name ? name : "", VTY_NEWLINE);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100368 return CMD_WARNING;
369 }
370
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100371 osmo_stats_reporter_free(srep);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100372
373 return CMD_SUCCESS;
374}
375
Alexander Chemeris161adee2020-05-08 18:19:24 +0300376DEFUN(cfg_stats_interval, cfg_stats_interval_cmd,
Daniel Willmann1a1de332020-07-14 18:11:14 +0200377 "stats interval <0-65535>",
Alexander Chemeris161adee2020-05-08 18:19:24 +0300378 CFG_STATS_STR "Set the reporting interval\n"
Daniel Willmann1a1de332020-07-14 18:11:14 +0200379 "Interval in seconds (0 disables the reporting interval)\n")
Alexander Chemeris161adee2020-05-08 18:19:24 +0300380{
381 int rc;
382 int interval = atoi(argv[0]);
383 rc = osmo_stats_set_interval(interval);
384 if (rc < 0) {
385 vty_out(vty, "%% Unable to set interval: %s%s",
386 strerror(-rc), VTY_NEWLINE);
387 return CMD_WARNING;
388 }
389
390 return CMD_SUCCESS;
391}
392
Philipp Maierb1ef8f52021-12-06 16:31:02 +0100393DEFUN(cfg_tcp_stats_interval, cfg_tcp_stats_interval_cmd,
394 "stats-tcp interval <0-65535>",
395 CFG_STATS_STR "Set the tcp socket stats polling interval\n"
396 "Interval in seconds (0 disables the polling interval)\n")
397{
398 int rc;
399 int interval = atoi(argv[0]);
400 rc = osmo_stats_tcp_set_interval(interval);
401 if (rc < 0) {
402 vty_out(vty, "%% Unable to set interval: %s%s",
403 strerror(-rc), VTY_NEWLINE);
404 return CMD_WARNING;
405 }
406
407 return CMD_SUCCESS;
408}
409
410DEFUN(cfg_tcp_stats_batch_size, cfg_tcp_stats_batch_size_cmd,
411 "stats-tcp batch-size <1-65535>",
412 CFG_STATS_STR "Set the number of tcp sockets that are processed per stats polling interval\n"
413 "Number of sockets per interval\n")
414{
415 osmo_tcp_stats_config->batch_size = atoi(argv[0]);
416 return CMD_SUCCESS;
417}
418
Jacob Erlbeck45513e62015-10-19 15:14:13 +0200419DEFUN(show_stats,
420 show_stats_cmd,
421 "show stats",
422 SHOW_STR SHOW_STATS_STR)
423{
424 vty_out_statistics_full(vty, "");
425
426 return CMD_SUCCESS;
427}
428
Jacob Erlbeck59b90bc2015-11-03 16:21:40 +0100429DEFUN(show_stats_level,
430 show_stats_level_cmd,
431 "show stats level (global|peer|subscriber)",
432 SHOW_STR SHOW_STATS_STR
Holger Hans Peter Freyther83481942015-11-07 21:10:01 +0100433 "Set the maximum group level\n"
Jacob Erlbeck59b90bc2015-11-03 16:21:40 +0100434 "Show global groups only\n"
435 "Show global and network peer related groups\n"
436 "Show global, peer, and subscriber groups\n")
437{
438 int level = get_string_value(stats_class_strs, argv[0]);
439 vty_out_statistics_partial(vty, "", level);
440
441 return CMD_SUCCESS;
442}
443
Alexander Couzensad580ba2016-05-16 16:01:45 +0200444static int asciidoc_handle_counter(struct osmo_counter *counter, void *sctx_)
445{
446 struct vty *vty = sctx_;
447 char *name = osmo_asciidoc_escape(counter->name);
448 char *description = osmo_asciidoc_escape(counter->description);
449
450 /* | name | This document & | description | */
451 vty_out(vty, "| %s | <<ungroup_counter_%s>> | %s%s",
452 name,
453 name,
454 description ? description : "",
455 VTY_NEWLINE);
456
457 talloc_free(name);
458 talloc_free(description);
459
460 return 0;
461}
462
463static void asciidoc_counter_generate(struct vty *vty)
464{
465 vty_out(vty, "// ungrouped osmo_counters%s", VTY_NEWLINE);
466 vty_out(vty, ".ungrouped osmo counters%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200467 vty_out(vty, "[options=\"header\"]%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200468 vty_out(vty, "|===%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200469 vty_out(vty, "| Name | Reference | Description%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200470 osmo_counters_for_each(asciidoc_handle_counter, vty);
471 vty_out(vty, "|===%s", VTY_NEWLINE);
472}
473
474static int asciidoc_rate_ctr_handler(
475 struct rate_ctr_group *ctrg, struct rate_ctr *ctr,
476 const struct rate_ctr_desc *desc, void *sctx_)
477{
478 struct vty *vty = sctx_;
479 char *name = osmo_asciidoc_escape(desc->name);
480 char *description = osmo_asciidoc_escape(desc->description);
481 char *group_name_prefix = osmo_asciidoc_escape(ctrg->desc->group_name_prefix);
482
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200483 /* | Name | This document & | Description | */
Alexander Couzensad580ba2016-05-16 16:01:45 +0200484 vty_out(vty, "| %s | <<%s_%s>> | %s%s",
485 name,
486 group_name_prefix,
487 name,
488 description ? description : NULL,
489 VTY_NEWLINE);
490
491 /* description seems to be optional */
492 talloc_free(name);
493 talloc_free(group_name_prefix);
494 talloc_free(description);
495
496 return 0;
497}
498
499static int asciidoc_rate_ctr_group_handler(struct rate_ctr_group *ctrg, void *sctx_)
500{
501 struct vty *vty = sctx_;
502
503 char *group_description = osmo_asciidoc_escape(ctrg->desc->group_description);
504 char *group_name_prefix = osmo_asciidoc_escape(ctrg->desc->group_name_prefix);
505
506 vty_out(vty, "// rate_ctr_group table %s%s", group_description, VTY_NEWLINE);
Pau Espin Pedrol18e019e2019-06-19 14:24:27 +0200507 vty_out(vty, ".%s - %s%s", group_name_prefix, group_description, VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200508 vty_out(vty, "[options=\"header\"]%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200509 vty_out(vty, "|===%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200510 vty_out(vty, "| Name | Reference | Description%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200511 rate_ctr_for_each_counter(ctrg, asciidoc_rate_ctr_handler, sctx_);
512 vty_out(vty, "|===%s", VTY_NEWLINE);
513
514 talloc_free(group_name_prefix);
515 talloc_free(group_description);
516
517 return 0;
518}
519
520static int asciidoc_osmo_stat_item_handler(
521 struct osmo_stat_item_group *statg, struct osmo_stat_item *item, void *sctx_)
522{
523 struct vty *vty = sctx_;
524
Neels Hofmeyre90c7172021-09-14 14:37:38 +0200525 const struct osmo_stat_item_desc *desc = osmo_stat_item_get_desc(item);
526 char *name = osmo_asciidoc_escape(desc->name);
527 char *description = osmo_asciidoc_escape(desc->description);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200528 char *group_name_prefix = osmo_asciidoc_escape(statg->desc->group_name_prefix);
Neels Hofmeyre90c7172021-09-14 14:37:38 +0200529 char *unit = osmo_asciidoc_escape(desc->unit);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200530
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200531 /* | Name | Reference | Description | Unit | */
Alexander Couzensad580ba2016-05-16 16:01:45 +0200532 vty_out(vty, "| %s | <<%s_%s>> | %s | %s%s",
533 name,
534 group_name_prefix,
535 name,
536 description ? description : "",
537 unit ? unit : "",
538 VTY_NEWLINE);
539
540 talloc_free(name);
541 talloc_free(group_name_prefix);
542 talloc_free(description);
543 talloc_free(unit);
544
545 return 0;
546}
547
548static int asciidoc_osmo_stat_item_group_handler(struct osmo_stat_item_group *statg, void *sctx_)
549{
550 char *group_name_prefix = osmo_asciidoc_escape(statg->desc->group_name_prefix);
551 char *group_description = osmo_asciidoc_escape(statg->desc->group_description);
552
553 struct vty *vty = sctx_;
554 vty_out(vty, "%s%s", group_description ? group_description : "" , VTY_NEWLINE);
555
556 vty_out(vty, "// osmo_stat_item_group table %s%s", group_description ? group_description : "", VTY_NEWLINE);
Pau Espin Pedrol18e019e2019-06-19 14:24:27 +0200557 vty_out(vty, ".%s - %s%s", group_name_prefix, group_description ? group_description : "", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200558 vty_out(vty, "[options=\"header\"]%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200559 vty_out(vty, "|===%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200560 vty_out(vty, "| Name | Reference | Description | Unit%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200561 osmo_stat_item_for_each_item(statg, asciidoc_osmo_stat_item_handler, sctx_);
562 vty_out(vty, "|===%s", VTY_NEWLINE);
563
564 talloc_free(group_name_prefix);
565 talloc_free(group_description);
566
567 return 0;
568}
569
570DEFUN(show_stats_asciidoc_table,
571 show_stats_asciidoc_table_cmd,
572 "show asciidoc counters",
Harald Weltef624c332016-06-15 11:35:16 +0200573 SHOW_STR "Asciidoc generation\n" "Generate table of all registered counters\n")
Alexander Couzensad580ba2016-05-16 16:01:45 +0200574{
Alexander Couzense052dc22016-10-04 18:04:37 +0200575 vty_out(vty, "// autogenerated by show asciidoc counters%s", VTY_NEWLINE);
Daniel Willmann6f3bbd42019-07-25 11:33:50 +0200576 vty_out(vty, "These counters and their description are based on %s %s (%s).%s%s",
Alexander Couzense052dc22016-10-04 18:04:37 +0200577 host.app_info->name,
578 host.app_info->version,
579 host.app_info->name ? host.app_info->name : "", VTY_NEWLINE, VTY_NEWLINE);
580 /* 2x VTY_NEWLINE are intentional otherwise it would interpret the first table header
581 * as usual text*/
Daniel Willmannd910a352018-07-24 20:01:26 +0200582 vty_out(vty, "=== Rate Counters%s%s", VTY_NEWLINE, VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200583 vty_out(vty, "// generating tables for rate_ctr_group%s", VTY_NEWLINE);
584 rate_ctr_for_each_group(asciidoc_rate_ctr_group_handler, vty);
585
Daniel Willmann81588822021-06-16 14:19:48 +0200586 vty_out(vty, "=== Osmo Stat Items%s%s", VTY_NEWLINE, VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200587 vty_out(vty, "// generating tables for osmo_stat_items%s", VTY_NEWLINE);
588 osmo_stat_item_for_each_group(asciidoc_osmo_stat_item_group_handler, vty);
589
Daniel Willmann81588822021-06-16 14:19:48 +0200590 if (osmo_counters_count() == 0)
591 {
592 vty_out(vty, "// there are no ungrouped osmo_counters%s",
593 VTY_NEWLINE);
594 } else {
595 vty_out(vty, "=== Osmo Counters%s%s", VTY_NEWLINE, VTY_NEWLINE);
596 vty_out(vty, "// generating tables for osmo_counters%s", VTY_NEWLINE);
597 asciidoc_counter_generate(vty);
598 }
Alexander Couzensad580ba2016-05-16 16:01:45 +0200599 return CMD_SUCCESS;
600}
601
Stefan Sperling73b7fa62018-05-24 18:40:03 +0200602static int rate_ctr_group_handler(struct rate_ctr_group *ctrg, void *sctx_)
603{
604 struct vty *vty = sctx_;
Vadim Yanitskiye9fd81a2021-06-06 18:02:57 +0200605 vty_out(vty, "%s %u", ctrg->desc->group_description, ctrg->idx);
606 if (ctrg->name != NULL)
607 vty_out(vty, " (%s)", ctrg->name);
608 vty_out(vty, ":%s", VTY_NEWLINE);
Stefan Sperling73b7fa62018-05-24 18:40:03 +0200609 vty_out_rate_ctr_group_fmt(vty, "%25n: %10c (%S/s %M/m %H/h %D/d) %d", ctrg);
610 return 0;
611}
612
613DEFUN(show_rate_counters,
614 show_rate_counters_cmd,
615 "show rate-counters",
616 SHOW_STR "Show all rate counters\n")
617{
618 rate_ctr_for_each_group(rate_ctr_group_handler, vty);
619 return CMD_SUCCESS;
620}
621
Daniel Willmann1a1de332020-07-14 18:11:14 +0200622DEFUN(stats_report,
623 stats_report_cmd,
624 "stats report",
625 STATS_STR "Manurally trigger reporting of stats\n")
626{
627 osmo_stats_report();
628 return CMD_SUCCESS;
629}
630
631static int reset_rate_ctr_group_handler(struct rate_ctr_group *ctrg, void *sctx_)
632{
633 rate_ctr_group_reset(ctrg);
634 return 0;
635}
636
Daniel Willmann1a1de332020-07-14 18:11:14 +0200637DEFUN(stats_reset,
638 stats_reset_cmd,
639 "stats reset",
Neels Hofmeyr923cb842021-08-20 17:09:38 +0200640 STATS_STR "Reset all rate counter stats\n")
Daniel Willmann1a1de332020-07-14 18:11:14 +0200641{
642 rate_ctr_for_each_group(reset_rate_ctr_group_handler, NULL);
Daniel Willmann1a1de332020-07-14 18:11:14 +0200643 return CMD_SUCCESS;
644}
645
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100646static int config_write_stats_reporter(struct vty *vty, struct osmo_stats_reporter *srep)
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200647{
Vadim Yanitskiybfc83772021-11-08 23:14:29 +0300648 const char *type = NULL;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200649
650 switch (srep->type) {
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100651 case OSMO_STATS_REPORTER_STATSD:
Vadim Yanitskiybfc83772021-11-08 23:14:29 +0300652 type = "statsd";
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200653 break;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100654 case OSMO_STATS_REPORTER_LOG:
Vadim Yanitskiybfc83772021-11-08 23:14:29 +0300655 type = "log";
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100656 break;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200657 }
658
Vadim Yanitskiybfc83772021-11-08 23:14:29 +0300659 vty_out(vty, "stats reporter %s", type);
660 if (srep->name != NULL)
661 vty_out(vty, " %s", srep->name);
662 vty_out(vty, "%s", VTY_NEWLINE);
663
Jacob Erlbecked197fd2015-10-27 14:43:24 +0100664 if (srep->have_net_config) {
665 if (srep->dest_addr_str)
666 vty_out(vty, " remote-ip %s%s",
667 srep->dest_addr_str, VTY_NEWLINE);
668 if (srep->dest_port)
669 vty_out(vty, " remote-port %d%s",
670 srep->dest_port, VTY_NEWLINE);
671 if (srep->bind_addr_str)
672 vty_out(vty, " local-ip %s%s",
673 srep->bind_addr_str, VTY_NEWLINE);
674 if (srep->mtu)
675 vty_out(vty, " mtu %d%s",
676 srep->mtu, VTY_NEWLINE);
677 }
678
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100679 if (srep->max_class)
680 vty_out(vty, " level %s%s",
681 get_value_string(stats_class_strs, srep->max_class),
682 VTY_NEWLINE);
683
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200684 if (srep->name_prefix && *srep->name_prefix)
685 vty_out(vty, " prefix %s%s",
686 srep->name_prefix, VTY_NEWLINE);
687 else
688 vty_out(vty, " no prefix%s", VTY_NEWLINE);
689
Alexander Chemerisdfebf402020-05-08 19:10:40 +0300690 if (srep->flush_period > 0)
691 vty_out(vty, " flush-period %d%s",
692 srep->flush_period, VTY_NEWLINE);
693
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200694 if (srep->enabled)
695 vty_out(vty, " enable%s", VTY_NEWLINE);
Vadim Yanitskiyd6b00592021-11-09 13:46:55 +0300696 else
697 vty_out(vty, " disable%s", VTY_NEWLINE);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200698
699 return 1;
700}
701
702static int config_write_stats(struct vty *vty)
703{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100704 struct osmo_stats_reporter *srep;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200705
Vadim Yanitskiy4f1c4e32021-11-09 13:38:40 +0300706 vty_out(vty, "stats interval %d%s", osmo_stats_config->interval, VTY_NEWLINE);
Philipp Maierb1ef8f52021-12-06 16:31:02 +0100707 if (osmo_tcp_stats_config->interval != TCP_STATS_DEFAULT_INTERVAL)
708 vty_out(vty, "stats-tcp interval %d%s", osmo_tcp_stats_config->interval, VTY_NEWLINE);
709 if (osmo_tcp_stats_config->batch_size != TCP_STATS_DEFAULT_BATCH_SIZE)
710 vty_out(vty, "stats-tcp batch-size %d%s", osmo_tcp_stats_config->batch_size, VTY_NEWLINE);
Vadim Yanitskiy4f1c4e32021-11-09 13:38:40 +0300711
Vadim Yanitskiybfc83772021-11-08 23:14:29 +0300712 /* Loop through all reporters */
713 llist_for_each_entry(srep, &osmo_stats_reporter_list, list)
714 config_write_stats_reporter(vty, srep);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200715
716 return 1;
717}
718
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200719/*! Add stats related commands to the VTY
Harald Welte96e2a002017-06-12 21:44:18 +0200720 * Call this once during your application initialization if you would
721 * like to have stats VTY commands enabled.
722 */
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100723void osmo_stats_vty_add_cmds()
Jacob Erlbeck45513e62015-10-19 15:14:13 +0200724{
Vadim Yanitskiy8e7c4962020-10-04 15:37:31 +0700725 install_lib_element_ve(&show_stats_cmd);
726 install_lib_element_ve(&show_stats_level_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200727
Vadim Yanitskiy8e7c4962020-10-04 15:37:31 +0700728 install_lib_element(CONFIG_NODE, &cfg_stats_reporter_statsd_cmd);
729 install_lib_element(CONFIG_NODE, &cfg_no_stats_reporter_statsd_cmd);
730 install_lib_element(CONFIG_NODE, &cfg_stats_reporter_log_cmd);
731 install_lib_element(CONFIG_NODE, &cfg_no_stats_reporter_log_cmd);
732 install_lib_element(CONFIG_NODE, &cfg_stats_interval_cmd);
Philipp Maierb1ef8f52021-12-06 16:31:02 +0100733 install_lib_element(CONFIG_NODE, &cfg_tcp_stats_interval_cmd);
734 install_lib_element(CONFIG_NODE, &cfg_tcp_stats_batch_size_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200735
736 install_node(&cfg_stats_node, config_write_stats);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200737
Vadim Yanitskiy8e7c4962020-10-04 15:37:31 +0700738 install_lib_element(CFG_STATS_NODE, &cfg_stats_reporter_local_ip_cmd);
739 install_lib_element(CFG_STATS_NODE, &cfg_no_stats_reporter_local_ip_cmd);
740 install_lib_element(CFG_STATS_NODE, &cfg_stats_reporter_remote_ip_cmd);
741 install_lib_element(CFG_STATS_NODE, &cfg_stats_reporter_remote_port_cmd);
742 install_lib_element(CFG_STATS_NODE, &cfg_stats_reporter_mtu_cmd);
743 install_lib_element(CFG_STATS_NODE, &cfg_no_stats_reporter_mtu_cmd);
744 install_lib_element(CFG_STATS_NODE, &cfg_stats_reporter_prefix_cmd);
745 install_lib_element(CFG_STATS_NODE, &cfg_no_stats_reporter_prefix_cmd);
746 install_lib_element(CFG_STATS_NODE, &cfg_stats_reporter_level_cmd);
747 install_lib_element(CFG_STATS_NODE, &cfg_stats_reporter_enable_cmd);
748 install_lib_element(CFG_STATS_NODE, &cfg_stats_reporter_disable_cmd);
749 install_lib_element(CFG_STATS_NODE, &cfg_stats_reporter_flush_period_cmd);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200750
Vadim Yanitskiy8e7c4962020-10-04 15:37:31 +0700751 install_lib_element_ve(&show_stats_asciidoc_table_cmd);
752 install_lib_element_ve(&show_rate_counters_cmd);
Daniel Willmann1a1de332020-07-14 18:11:14 +0200753
Vadim Yanitskiy8e7c4962020-10-04 15:37:31 +0700754 install_lib_element(ENABLE_NODE, &stats_report_cmd);
755 install_lib_element(ENABLE_NODE, &stats_reset_cmd);
Jacob Erlbeck45513e62015-10-19 15:14:13 +0200756}