blob: 1483eaa53bc441f9e48f25788ab22c039bdc6bdd [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
Daniel Willmann1a1de332020-07-14 18:11:14 +020046#define STATS_STR "Stats related commands\n"
47
Harald Welte8c648252017-10-16 15:17:03 +020048/*! \file stats_vty.c
Neels Hofmeyr87e45502017-06-20 00:17:59 +020049 * VTY interface for statsd / statistic items
Harald Welte8c648252017-10-16 15:17:03 +020050 *
51 * This code allows you to register a couple of VTY commands that
52 * permit configuration of the \ref stats functionality from the VTY.
53 *
54 * Use \ref osmo_stats_vty_add_cmds once at application start-up to
55 * enable related commands.
Harald Welte96e2a002017-06-12 21:44:18 +020056 */
57
Alexander Couzense052dc22016-10-04 18:04:37 +020058/* containing version info */
59extern struct host host;
60
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020061struct cmd_node cfg_stats_node = {
62 CFG_STATS_NODE,
63 "%s(config-stats)# ",
64 1
65};
66
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +010067static const struct value_string stats_class_strs[] = {
68 { OSMO_STATS_CLASS_GLOBAL, "global" },
69 { OSMO_STATS_CLASS_PEER, "peer" },
70 { OSMO_STATS_CLASS_SUBSCRIBER, "subscriber" },
71 { 0, NULL }
72};
73
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +010074static struct osmo_stats_reporter *osmo_stats_vty2srep(struct vty *vty)
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020075{
76 if (vty->node == CFG_STATS_NODE)
77 return vty->index;
78
79 return NULL;
80}
81
82static int set_srep_parameter_str(struct vty *vty,
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +010083 int (*fun)(struct osmo_stats_reporter *, const char *),
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020084 const char *val, const char *param_name)
85{
86 int rc;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +010087 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020088 OSMO_ASSERT(srep);
89
90 rc = fun(srep, val);
91 if (rc < 0) {
92 vty_out(vty, "%% Unable to set %s: %s%s",
93 param_name, strerror(-rc), VTY_NEWLINE);
94 return CMD_WARNING;
95 }
96
97 return CMD_SUCCESS;
98}
99
100static int set_srep_parameter_int(struct vty *vty,
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100101 int (*fun)(struct osmo_stats_reporter *, int),
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200102 const char *val, const char *param_name)
103{
104 int rc;
105 int int_val;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100106 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200107 OSMO_ASSERT(srep);
108
109 int_val = atoi(val);
110
111 rc = fun(srep, int_val);
112 if (rc < 0) {
113 vty_out(vty, "%% Unable to set %s: %s%s",
114 param_name, strerror(-rc), VTY_NEWLINE);
115 return CMD_WARNING;
116 }
117
118 return CMD_SUCCESS;
119}
120
121DEFUN(cfg_stats_reporter_local_ip, cfg_stats_reporter_local_ip_cmd,
122 "local-ip ADDR",
123 "Set the IP address to which we bind locally\n"
124 "IP Address\n")
125{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100126 return set_srep_parameter_str(vty, osmo_stats_reporter_set_local_addr,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200127 argv[0], "local address");
128}
129
130DEFUN(cfg_no_stats_reporter_local_ip, cfg_no_stats_reporter_local_ip_cmd,
131 "no local-ip",
132 NO_STR
133 "Set the IP address to which we bind locally\n")
134{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100135 return set_srep_parameter_str(vty, osmo_stats_reporter_set_local_addr,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200136 NULL, "local address");
137}
138
139DEFUN(cfg_stats_reporter_remote_ip, cfg_stats_reporter_remote_ip_cmd,
140 "remote-ip ADDR",
141 "Set the remote IP address to which we connect\n"
142 "IP Address\n")
143{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100144 return set_srep_parameter_str(vty, osmo_stats_reporter_set_remote_addr,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200145 argv[0], "remote address");
146}
147
148DEFUN(cfg_stats_reporter_remote_port, cfg_stats_reporter_remote_port_cmd,
149 "remote-port <1-65535>",
150 "Set the remote port to which we connect\n"
151 "Remote port number\n")
152{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100153 return set_srep_parameter_int(vty, osmo_stats_reporter_set_remote_port,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200154 argv[0], "remote port");
155}
156
Jacob Erlbeckd01acfc2015-10-26 16:22:45 +0100157DEFUN(cfg_stats_reporter_mtu, cfg_stats_reporter_mtu_cmd,
158 "mtu <100-65535>",
159 "Set the maximum packet size\n"
160 "Size in byte\n")
161{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100162 return set_srep_parameter_int(vty, osmo_stats_reporter_set_mtu,
Jacob Erlbeckd01acfc2015-10-26 16:22:45 +0100163 argv[0], "mtu");
164}
165
166DEFUN(cfg_no_stats_reporter_mtu, cfg_no_stats_reporter_mtu_cmd,
167 "no mtu",
168 NO_STR "Set the maximum packet size\n")
169{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100170 return set_srep_parameter_int(vty, osmo_stats_reporter_set_mtu,
Holger Hans Peter Freyther8f0374f2015-11-02 15:53:09 +0100171 "0", "mtu");
Jacob Erlbeckd01acfc2015-10-26 16:22:45 +0100172}
173
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200174DEFUN(cfg_stats_reporter_prefix, cfg_stats_reporter_prefix_cmd,
175 "prefix PREFIX",
176 "Set the item name prefix\n"
177 "The prefix string\n")
178{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100179 return set_srep_parameter_str(vty, osmo_stats_reporter_set_name_prefix,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200180 argv[0], "prefix string");
181}
182
183DEFUN(cfg_no_stats_reporter_prefix, cfg_no_stats_reporter_prefix_cmd,
184 "no prefix",
185 NO_STR
186 "Set the item name prefix\n")
187{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100188 return set_srep_parameter_str(vty, osmo_stats_reporter_set_name_prefix,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200189 "", "prefix string");
190}
191
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100192DEFUN(cfg_stats_reporter_level, cfg_stats_reporter_level_cmd,
193 "level (global|peer|subscriber)",
194 "Set the maximum group level\n"
195 "Report global groups only\n"
196 "Report global and network peer related groups\n"
197 "Report global, peer, and subscriber groups\n")
198{
199 int level = get_string_value(stats_class_strs, argv[0]);
200 int rc;
201 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
202
203 OSMO_ASSERT(srep);
204 rc = osmo_stats_reporter_set_max_class(srep, level);
205 if (rc < 0) {
206 vty_out(vty, "%% Unable to set level: %s%s",
207 strerror(-rc), VTY_NEWLINE);
208 return CMD_WARNING;
209 }
210
211 return 0;
212}
213
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200214DEFUN(cfg_stats_reporter_enable, cfg_stats_reporter_enable_cmd,
215 "enable",
216 "Enable the reporter\n")
217{
218 int rc;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100219 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200220 OSMO_ASSERT(srep);
221
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100222 rc = osmo_stats_reporter_enable(srep);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200223 if (rc < 0) {
224 vty_out(vty, "%% Unable to enable the reporter: %s%s",
225 strerror(-rc), VTY_NEWLINE);
226 return CMD_WARNING;
227 }
228
229 return CMD_SUCCESS;
230}
231
232DEFUN(cfg_stats_reporter_disable, cfg_stats_reporter_disable_cmd,
233 "disable",
234 "Disable the reporter\n")
235{
236 int rc;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100237 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200238 OSMO_ASSERT(srep);
239
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100240 rc = osmo_stats_reporter_disable(srep);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200241 if (rc < 0) {
242 vty_out(vty, "%% Unable to disable the reporter: %s%s",
243 strerror(-rc), VTY_NEWLINE);
244 return CMD_WARNING;
245 }
246
247 return CMD_SUCCESS;
248}
249
Alexander Chemerisdfebf402020-05-08 19:10:40 +0300250DEFUN(cfg_stats_reporter_flush_period, cfg_stats_reporter_flush_period_cmd,
251 "flush-period <0-65535>",
252 CFG_STATS_STR "Send all stats even if they have not changed (i.e. force the flush)"
253 "every N-th reporting interval. Set to 0 to disable regular flush (default).\n"
254 "0 to disable regular flush (default), 1 to flush every time, 2 to flush every 2nd time, etc\n")
255{
256 int rc;
257 unsigned int period = atoi(argv[0]);
258 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
259 OSMO_ASSERT(srep);
260
261 rc = osmo_stats_reporter_set_flush_period(srep, period);
262 if (rc < 0) {
263 vty_out(vty, "%% Unable to set force flush period: %s%s",
264 strerror(-rc), VTY_NEWLINE);
265 return CMD_WARNING;
266 }
267
268 return CMD_SUCCESS;
269}
270
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200271DEFUN(cfg_stats_reporter_statsd, cfg_stats_reporter_statsd_cmd,
272 "stats reporter statsd",
273 CFG_STATS_STR CFG_REPORTER_STR "Report to a STATSD server\n")
274{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100275 struct osmo_stats_reporter *srep;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200276
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100277 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_STATSD, NULL);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200278 if (!srep) {
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100279 srep = osmo_stats_reporter_create_statsd(NULL);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200280 if (!srep) {
281 vty_out(vty, "%% Unable to create statsd reporter%s",
282 VTY_NEWLINE);
283 return CMD_WARNING;
284 }
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100285 srep->max_class = OSMO_STATS_CLASS_GLOBAL;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100286 /* TODO: if needed, add osmo_stats_add_reporter(srep); */
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200287 }
288
289 vty->index = srep;
290 vty->node = CFG_STATS_NODE;
291
292 return CMD_SUCCESS;
293}
294
295DEFUN(cfg_no_stats_reporter_statsd, cfg_no_stats_reporter_statsd_cmd,
296 "no stats reporter statsd",
297 NO_STR CFG_STATS_STR CFG_REPORTER_STR "Report to a STATSD server\n")
298{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100299 struct osmo_stats_reporter *srep;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200300
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100301 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_STATSD, NULL);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200302 if (!srep) {
303 vty_out(vty, "%% No statsd logging active%s",
304 VTY_NEWLINE);
305 return CMD_WARNING;
306 }
307
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100308 osmo_stats_reporter_free(srep);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200309
310 return CMD_SUCCESS;
311}
312
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100313DEFUN(cfg_stats_reporter_log, cfg_stats_reporter_log_cmd,
314 "stats reporter log",
315 CFG_STATS_STR CFG_REPORTER_STR "Report to the logger\n")
316{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100317 struct osmo_stats_reporter *srep;
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100318
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100319 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_LOG, NULL);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100320 if (!srep) {
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100321 srep = osmo_stats_reporter_create_log(NULL);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100322 if (!srep) {
323 vty_out(vty, "%% Unable to create log reporter%s",
324 VTY_NEWLINE);
325 return CMD_WARNING;
326 }
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100327 srep->max_class = OSMO_STATS_CLASS_GLOBAL;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100328 /* TODO: if needed, add osmo_stats_add_reporter(srep); */
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100329 }
330
331 vty->index = srep;
332 vty->node = CFG_STATS_NODE;
333
334 return CMD_SUCCESS;
335}
336
337DEFUN(cfg_no_stats_reporter_log, cfg_no_stats_reporter_log_cmd,
338 "no stats reporter log",
339 NO_STR CFG_STATS_STR CFG_REPORTER_STR "Report to the logger\n")
340{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100341 struct osmo_stats_reporter *srep;
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100342
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100343 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_LOG, NULL);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100344 if (!srep) {
345 vty_out(vty, "%% No log reporting active%s",
346 VTY_NEWLINE);
347 return CMD_WARNING;
348 }
349
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100350 osmo_stats_reporter_free(srep);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100351
352 return CMD_SUCCESS;
353}
354
Alexander Chemeris161adee2020-05-08 18:19:24 +0300355DEFUN(cfg_stats_interval, cfg_stats_interval_cmd,
Daniel Willmann1a1de332020-07-14 18:11:14 +0200356 "stats interval <0-65535>",
Alexander Chemeris161adee2020-05-08 18:19:24 +0300357 CFG_STATS_STR "Set the reporting interval\n"
Daniel Willmann1a1de332020-07-14 18:11:14 +0200358 "Interval in seconds (0 disables the reporting interval)\n")
Alexander Chemeris161adee2020-05-08 18:19:24 +0300359{
360 int rc;
361 int interval = atoi(argv[0]);
362 rc = osmo_stats_set_interval(interval);
363 if (rc < 0) {
364 vty_out(vty, "%% Unable to set interval: %s%s",
365 strerror(-rc), VTY_NEWLINE);
366 return CMD_WARNING;
367 }
368
369 return CMD_SUCCESS;
370}
371
Jacob Erlbeck45513e62015-10-19 15:14:13 +0200372DEFUN(show_stats,
373 show_stats_cmd,
374 "show stats",
375 SHOW_STR SHOW_STATS_STR)
376{
377 vty_out_statistics_full(vty, "");
378
379 return CMD_SUCCESS;
380}
381
Jacob Erlbeck59b90bc2015-11-03 16:21:40 +0100382DEFUN(show_stats_level,
383 show_stats_level_cmd,
384 "show stats level (global|peer|subscriber)",
385 SHOW_STR SHOW_STATS_STR
Holger Hans Peter Freyther83481942015-11-07 21:10:01 +0100386 "Set the maximum group level\n"
Jacob Erlbeck59b90bc2015-11-03 16:21:40 +0100387 "Show global groups only\n"
388 "Show global and network peer related groups\n"
389 "Show global, peer, and subscriber groups\n")
390{
391 int level = get_string_value(stats_class_strs, argv[0]);
392 vty_out_statistics_partial(vty, "", level);
393
394 return CMD_SUCCESS;
395}
396
Alexander Couzensad580ba2016-05-16 16:01:45 +0200397static int asciidoc_handle_counter(struct osmo_counter *counter, void *sctx_)
398{
399 struct vty *vty = sctx_;
400 char *name = osmo_asciidoc_escape(counter->name);
401 char *description = osmo_asciidoc_escape(counter->description);
402
403 /* | name | This document & | description | */
404 vty_out(vty, "| %s | <<ungroup_counter_%s>> | %s%s",
405 name,
406 name,
407 description ? description : "",
408 VTY_NEWLINE);
409
410 talloc_free(name);
411 talloc_free(description);
412
413 return 0;
414}
415
416static void asciidoc_counter_generate(struct vty *vty)
417{
Alexander Couzens06dbdf52017-12-05 16:12:14 +0100418 if (osmo_counters_count() == 0)
419 {
420 vty_out(vty, "// there are no ungrouped osmo_counters%s",
421 VTY_NEWLINE);
422 return;
423 }
424
Alexander Couzensad580ba2016-05-16 16:01:45 +0200425 vty_out(vty, "// ungrouped osmo_counters%s", VTY_NEWLINE);
426 vty_out(vty, ".ungrouped osmo counters%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200427 vty_out(vty, "[options=\"header\"]%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200428 vty_out(vty, "|===%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200429 vty_out(vty, "| Name | Reference | Description%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200430 osmo_counters_for_each(asciidoc_handle_counter, vty);
431 vty_out(vty, "|===%s", VTY_NEWLINE);
432}
433
434static int asciidoc_rate_ctr_handler(
435 struct rate_ctr_group *ctrg, struct rate_ctr *ctr,
436 const struct rate_ctr_desc *desc, void *sctx_)
437{
438 struct vty *vty = sctx_;
439 char *name = osmo_asciidoc_escape(desc->name);
440 char *description = osmo_asciidoc_escape(desc->description);
441 char *group_name_prefix = osmo_asciidoc_escape(ctrg->desc->group_name_prefix);
442
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200443 /* | Name | This document & | Description | */
Alexander Couzensad580ba2016-05-16 16:01:45 +0200444 vty_out(vty, "| %s | <<%s_%s>> | %s%s",
445 name,
446 group_name_prefix,
447 name,
448 description ? description : NULL,
449 VTY_NEWLINE);
450
451 /* description seems to be optional */
452 talloc_free(name);
453 talloc_free(group_name_prefix);
454 talloc_free(description);
455
456 return 0;
457}
458
459static int asciidoc_rate_ctr_group_handler(struct rate_ctr_group *ctrg, void *sctx_)
460{
461 struct vty *vty = sctx_;
462
463 char *group_description = osmo_asciidoc_escape(ctrg->desc->group_description);
464 char *group_name_prefix = osmo_asciidoc_escape(ctrg->desc->group_name_prefix);
465
466 vty_out(vty, "// rate_ctr_group table %s%s", group_description, VTY_NEWLINE);
Pau Espin Pedrol18e019e2019-06-19 14:24:27 +0200467 vty_out(vty, ".%s - %s%s", group_name_prefix, group_description, VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200468 vty_out(vty, "[options=\"header\"]%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200469 vty_out(vty, "|===%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200470 vty_out(vty, "| Name | Reference | Description%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200471 rate_ctr_for_each_counter(ctrg, asciidoc_rate_ctr_handler, sctx_);
472 vty_out(vty, "|===%s", VTY_NEWLINE);
473
474 talloc_free(group_name_prefix);
475 talloc_free(group_description);
476
477 return 0;
478}
479
480static int asciidoc_osmo_stat_item_handler(
481 struct osmo_stat_item_group *statg, struct osmo_stat_item *item, void *sctx_)
482{
483 struct vty *vty = sctx_;
484
485 char *name = osmo_asciidoc_escape(item->desc->name);
486 char *description = osmo_asciidoc_escape(item->desc->description);
487 char *group_name_prefix = osmo_asciidoc_escape(statg->desc->group_name_prefix);
488 char *unit = osmo_asciidoc_escape(item->desc->unit);
489
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200490 /* | Name | Reference | Description | Unit | */
Alexander Couzensad580ba2016-05-16 16:01:45 +0200491 vty_out(vty, "| %s | <<%s_%s>> | %s | %s%s",
492 name,
493 group_name_prefix,
494 name,
495 description ? description : "",
496 unit ? unit : "",
497 VTY_NEWLINE);
498
499 talloc_free(name);
500 talloc_free(group_name_prefix);
501 talloc_free(description);
502 talloc_free(unit);
503
504 return 0;
505}
506
507static int asciidoc_osmo_stat_item_group_handler(struct osmo_stat_item_group *statg, void *sctx_)
508{
509 char *group_name_prefix = osmo_asciidoc_escape(statg->desc->group_name_prefix);
510 char *group_description = osmo_asciidoc_escape(statg->desc->group_description);
511
512 struct vty *vty = sctx_;
513 vty_out(vty, "%s%s", group_description ? group_description : "" , VTY_NEWLINE);
514
515 vty_out(vty, "// osmo_stat_item_group table %s%s", group_description ? group_description : "", VTY_NEWLINE);
Pau Espin Pedrol18e019e2019-06-19 14:24:27 +0200516 vty_out(vty, ".%s - %s%s", group_name_prefix, group_description ? group_description : "", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200517 vty_out(vty, "[options=\"header\"]%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200518 vty_out(vty, "|===%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200519 vty_out(vty, "| Name | Reference | Description | Unit%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200520 osmo_stat_item_for_each_item(statg, asciidoc_osmo_stat_item_handler, sctx_);
521 vty_out(vty, "|===%s", VTY_NEWLINE);
522
523 talloc_free(group_name_prefix);
524 talloc_free(group_description);
525
526 return 0;
527}
528
529DEFUN(show_stats_asciidoc_table,
530 show_stats_asciidoc_table_cmd,
531 "show asciidoc counters",
Harald Weltef624c332016-06-15 11:35:16 +0200532 SHOW_STR "Asciidoc generation\n" "Generate table of all registered counters\n")
Alexander Couzensad580ba2016-05-16 16:01:45 +0200533{
Alexander Couzense052dc22016-10-04 18:04:37 +0200534 vty_out(vty, "// autogenerated by show asciidoc counters%s", VTY_NEWLINE);
Daniel Willmann6f3bbd42019-07-25 11:33:50 +0200535 vty_out(vty, "These counters and their description are based on %s %s (%s).%s%s",
Alexander Couzense052dc22016-10-04 18:04:37 +0200536 host.app_info->name,
537 host.app_info->version,
538 host.app_info->name ? host.app_info->name : "", VTY_NEWLINE, VTY_NEWLINE);
539 /* 2x VTY_NEWLINE are intentional otherwise it would interpret the first table header
540 * as usual text*/
Daniel Willmannd910a352018-07-24 20:01:26 +0200541 vty_out(vty, "=== Rate Counters%s%s", VTY_NEWLINE, VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200542 vty_out(vty, "// generating tables for rate_ctr_group%s", VTY_NEWLINE);
543 rate_ctr_for_each_group(asciidoc_rate_ctr_group_handler, vty);
544
Daniel Willmannd910a352018-07-24 20:01:26 +0200545 vty_out(vty, "== Osmo Stat Items%s%s", VTY_NEWLINE, VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200546 vty_out(vty, "// generating tables for osmo_stat_items%s", VTY_NEWLINE);
547 osmo_stat_item_for_each_group(asciidoc_osmo_stat_item_group_handler, vty);
548
Daniel Willmannd910a352018-07-24 20:01:26 +0200549 vty_out(vty, "== Osmo Counters%s%s", VTY_NEWLINE, VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200550 vty_out(vty, "// generating tables for osmo_counters%s", VTY_NEWLINE);
551 asciidoc_counter_generate(vty);
552 return CMD_SUCCESS;
553}
554
Stefan Sperling73b7fa62018-05-24 18:40:03 +0200555static int rate_ctr_group_handler(struct rate_ctr_group *ctrg, void *sctx_)
556{
557 struct vty *vty = sctx_;
Stefan Sperling84eb1ab2018-10-29 17:50:30 +0100558 vty_out(vty, "%s %u:%s", ctrg->desc->group_description, ctrg->idx, VTY_NEWLINE);
Stefan Sperling73b7fa62018-05-24 18:40:03 +0200559 vty_out_rate_ctr_group_fmt(vty, "%25n: %10c (%S/s %M/m %H/h %D/d) %d", ctrg);
560 return 0;
561}
562
563DEFUN(show_rate_counters,
564 show_rate_counters_cmd,
565 "show rate-counters",
566 SHOW_STR "Show all rate counters\n")
567{
568 rate_ctr_for_each_group(rate_ctr_group_handler, vty);
569 return CMD_SUCCESS;
570}
571
Daniel Willmann1a1de332020-07-14 18:11:14 +0200572DEFUN(stats_report,
573 stats_report_cmd,
574 "stats report",
575 STATS_STR "Manurally trigger reporting of stats\n")
576{
577 osmo_stats_report();
578 return CMD_SUCCESS;
579}
580
581static int reset_rate_ctr_group_handler(struct rate_ctr_group *ctrg, void *sctx_)
582{
583 rate_ctr_group_reset(ctrg);
584 return 0;
585}
586
587static int reset_osmo_stat_item_group_handler(struct osmo_stat_item_group *statg, void *sctx_)
588{
589 osmo_stat_item_group_reset(statg);
590 return 0;
591}
592
593DEFUN(stats_reset,
594 stats_reset_cmd,
595 "stats reset",
596 STATS_STR "Reset all stats\n")
597{
598 rate_ctr_for_each_group(reset_rate_ctr_group_handler, NULL);
599 osmo_stat_item_for_each_group(reset_osmo_stat_item_group_handler, NULL);
600 return CMD_SUCCESS;
601}
602
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100603static int config_write_stats_reporter(struct vty *vty, struct osmo_stats_reporter *srep)
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200604{
605 if (srep == NULL)
606 return 0;
607
608 switch (srep->type) {
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100609 case OSMO_STATS_REPORTER_STATSD:
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200610 vty_out(vty, "stats reporter statsd%s", VTY_NEWLINE);
611 break;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100612 case OSMO_STATS_REPORTER_LOG:
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100613 vty_out(vty, "stats reporter log%s", VTY_NEWLINE);
614 break;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200615 }
616
617 vty_out(vty, " disable%s", VTY_NEWLINE);
618
Jacob Erlbecked197fd2015-10-27 14:43:24 +0100619 if (srep->have_net_config) {
620 if (srep->dest_addr_str)
621 vty_out(vty, " remote-ip %s%s",
622 srep->dest_addr_str, VTY_NEWLINE);
623 if (srep->dest_port)
624 vty_out(vty, " remote-port %d%s",
625 srep->dest_port, VTY_NEWLINE);
626 if (srep->bind_addr_str)
627 vty_out(vty, " local-ip %s%s",
628 srep->bind_addr_str, VTY_NEWLINE);
629 if (srep->mtu)
630 vty_out(vty, " mtu %d%s",
631 srep->mtu, VTY_NEWLINE);
632 }
633
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100634 if (srep->max_class)
635 vty_out(vty, " level %s%s",
636 get_value_string(stats_class_strs, srep->max_class),
637 VTY_NEWLINE);
638
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200639 if (srep->name_prefix && *srep->name_prefix)
640 vty_out(vty, " prefix %s%s",
641 srep->name_prefix, VTY_NEWLINE);
642 else
643 vty_out(vty, " no prefix%s", VTY_NEWLINE);
644
Alexander Chemerisdfebf402020-05-08 19:10:40 +0300645 if (srep->flush_period > 0)
646 vty_out(vty, " flush-period %d%s",
647 srep->flush_period, VTY_NEWLINE);
648
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200649 if (srep->enabled)
650 vty_out(vty, " enable%s", VTY_NEWLINE);
651
652 return 1;
653}
654
655static int config_write_stats(struct vty *vty)
656{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100657 struct osmo_stats_reporter *srep;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200658
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100659 /* TODO: loop through all reporters */
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100660 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_STATSD, NULL);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200661 config_write_stats_reporter(vty, srep);
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100662 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_LOG, NULL);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100663 config_write_stats_reporter(vty, srep);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200664
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100665 vty_out(vty, "stats interval %d%s", osmo_stats_config->interval, VTY_NEWLINE);
Jacob Erlbeckb1dbfb42015-10-26 11:58:38 +0100666
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200667 return 1;
668}
669
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200670/*! Add stats related commands to the VTY
Harald Welte96e2a002017-06-12 21:44:18 +0200671 * Call this once during your application initialization if you would
672 * like to have stats VTY commands enabled.
673 */
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100674void osmo_stats_vty_add_cmds()
Jacob Erlbeck45513e62015-10-19 15:14:13 +0200675{
676 install_element_ve(&show_stats_cmd);
Jacob Erlbeck59b90bc2015-11-03 16:21:40 +0100677 install_element_ve(&show_stats_level_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200678
679 install_element(CONFIG_NODE, &cfg_stats_reporter_statsd_cmd);
680 install_element(CONFIG_NODE, &cfg_no_stats_reporter_statsd_cmd);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100681 install_element(CONFIG_NODE, &cfg_stats_reporter_log_cmd);
682 install_element(CONFIG_NODE, &cfg_no_stats_reporter_log_cmd);
Jacob Erlbeckb1dbfb42015-10-26 11:58:38 +0100683 install_element(CONFIG_NODE, &cfg_stats_interval_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200684
685 install_node(&cfg_stats_node, config_write_stats);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200686
687 install_element(CFG_STATS_NODE, &cfg_stats_reporter_local_ip_cmd);
688 install_element(CFG_STATS_NODE, &cfg_no_stats_reporter_local_ip_cmd);
689 install_element(CFG_STATS_NODE, &cfg_stats_reporter_remote_ip_cmd);
690 install_element(CFG_STATS_NODE, &cfg_stats_reporter_remote_port_cmd);
Jacob Erlbeckd01acfc2015-10-26 16:22:45 +0100691 install_element(CFG_STATS_NODE, &cfg_stats_reporter_mtu_cmd);
692 install_element(CFG_STATS_NODE, &cfg_no_stats_reporter_mtu_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200693 install_element(CFG_STATS_NODE, &cfg_stats_reporter_prefix_cmd);
694 install_element(CFG_STATS_NODE, &cfg_no_stats_reporter_prefix_cmd);
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100695 install_element(CFG_STATS_NODE, &cfg_stats_reporter_level_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200696 install_element(CFG_STATS_NODE, &cfg_stats_reporter_enable_cmd);
697 install_element(CFG_STATS_NODE, &cfg_stats_reporter_disable_cmd);
Alexander Chemerisdfebf402020-05-08 19:10:40 +0300698 install_element(CFG_STATS_NODE, &cfg_stats_reporter_flush_period_cmd);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200699
700 install_element_ve(&show_stats_asciidoc_table_cmd);
Stefan Sperling73b7fa62018-05-24 18:40:03 +0200701 install_element_ve(&show_rate_counters_cmd);
Daniel Willmann1a1de332020-07-14 18:11:14 +0200702
703 install_element(ENABLE_NODE, &stats_report_cmd);
704 install_element(ENABLE_NODE, &stats_reset_cmd);
Jacob Erlbeck45513e62015-10-19 15:14:13 +0200705}