blob: 5ded7a443cd92c533a7792ad519f91df27fc90d2 [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
248DEFUN(cfg_stats_reporter_statsd, cfg_stats_reporter_statsd_cmd,
249 "stats reporter statsd",
250 CFG_STATS_STR CFG_REPORTER_STR "Report to a STATSD server\n")
251{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100252 struct osmo_stats_reporter *srep;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200253
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100254 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_STATSD, NULL);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200255 if (!srep) {
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100256 srep = osmo_stats_reporter_create_statsd(NULL);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200257 if (!srep) {
258 vty_out(vty, "%% Unable to create statsd reporter%s",
259 VTY_NEWLINE);
260 return CMD_WARNING;
261 }
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100262 srep->max_class = OSMO_STATS_CLASS_GLOBAL;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100263 /* TODO: if needed, add osmo_stats_add_reporter(srep); */
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200264 }
265
266 vty->index = srep;
267 vty->node = CFG_STATS_NODE;
268
269 return CMD_SUCCESS;
270}
271
Jacob Erlbeckb1dbfb42015-10-26 11:58:38 +0100272DEFUN(cfg_stats_interval, cfg_stats_interval_cmd,
273 "stats interval <1-65535>",
274 CFG_STATS_STR "Set the reporting interval\n"
275 "Interval in seconds\n")
276{
277 int rc;
278 int interval = atoi(argv[0]);
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100279 rc = osmo_stats_set_interval(interval);
Jacob Erlbeckb1dbfb42015-10-26 11:58:38 +0100280 if (rc < 0) {
281 vty_out(vty, "%% Unable to set interval: %s%s",
282 strerror(-rc), VTY_NEWLINE);
283 return CMD_WARNING;
284 }
285
286 return CMD_SUCCESS;
287}
288
289
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200290DEFUN(cfg_no_stats_reporter_statsd, cfg_no_stats_reporter_statsd_cmd,
291 "no stats reporter statsd",
292 NO_STR CFG_STATS_STR CFG_REPORTER_STR "Report to a STATSD server\n")
293{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100294 struct osmo_stats_reporter *srep;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200295
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100296 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_STATSD, NULL);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200297 if (!srep) {
298 vty_out(vty, "%% No statsd logging active%s",
299 VTY_NEWLINE);
300 return CMD_WARNING;
301 }
302
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100303 osmo_stats_reporter_free(srep);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200304
305 return CMD_SUCCESS;
306}
307
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100308DEFUN(cfg_stats_reporter_log, cfg_stats_reporter_log_cmd,
309 "stats reporter log",
310 CFG_STATS_STR CFG_REPORTER_STR "Report to the logger\n")
311{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100312 struct osmo_stats_reporter *srep;
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100313
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100314 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_LOG, NULL);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100315 if (!srep) {
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100316 srep = osmo_stats_reporter_create_log(NULL);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100317 if (!srep) {
318 vty_out(vty, "%% Unable to create log reporter%s",
319 VTY_NEWLINE);
320 return CMD_WARNING;
321 }
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100322 srep->max_class = OSMO_STATS_CLASS_GLOBAL;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100323 /* TODO: if needed, add osmo_stats_add_reporter(srep); */
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100324 }
325
326 vty->index = srep;
327 vty->node = CFG_STATS_NODE;
328
329 return CMD_SUCCESS;
330}
331
332DEFUN(cfg_no_stats_reporter_log, cfg_no_stats_reporter_log_cmd,
333 "no stats reporter log",
334 NO_STR CFG_STATS_STR CFG_REPORTER_STR "Report to the logger\n")
335{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100336 struct osmo_stats_reporter *srep;
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100337
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100338 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_LOG, NULL);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100339 if (!srep) {
340 vty_out(vty, "%% No log reporting active%s",
341 VTY_NEWLINE);
342 return CMD_WARNING;
343 }
344
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100345 osmo_stats_reporter_free(srep);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100346
347 return CMD_SUCCESS;
348}
349
Jacob Erlbeck45513e62015-10-19 15:14:13 +0200350DEFUN(show_stats,
351 show_stats_cmd,
352 "show stats",
353 SHOW_STR SHOW_STATS_STR)
354{
355 vty_out_statistics_full(vty, "");
356
357 return CMD_SUCCESS;
358}
359
Jacob Erlbeck59b90bc2015-11-03 16:21:40 +0100360DEFUN(show_stats_level,
361 show_stats_level_cmd,
362 "show stats level (global|peer|subscriber)",
363 SHOW_STR SHOW_STATS_STR
Holger Hans Peter Freyther83481942015-11-07 21:10:01 +0100364 "Set the maximum group level\n"
Jacob Erlbeck59b90bc2015-11-03 16:21:40 +0100365 "Show global groups only\n"
366 "Show global and network peer related groups\n"
367 "Show global, peer, and subscriber groups\n")
368{
369 int level = get_string_value(stats_class_strs, argv[0]);
370 vty_out_statistics_partial(vty, "", level);
371
372 return CMD_SUCCESS;
373}
374
Alexander Couzensad580ba2016-05-16 16:01:45 +0200375static int asciidoc_handle_counter(struct osmo_counter *counter, void *sctx_)
376{
377 struct vty *vty = sctx_;
378 char *name = osmo_asciidoc_escape(counter->name);
379 char *description = osmo_asciidoc_escape(counter->description);
380
381 /* | name | This document & | description | */
382 vty_out(vty, "| %s | <<ungroup_counter_%s>> | %s%s",
383 name,
384 name,
385 description ? description : "",
386 VTY_NEWLINE);
387
388 talloc_free(name);
389 talloc_free(description);
390
391 return 0;
392}
393
394static void asciidoc_counter_generate(struct vty *vty)
395{
Alexander Couzens06dbdf52017-12-05 16:12:14 +0100396 if (osmo_counters_count() == 0)
397 {
398 vty_out(vty, "// there are no ungrouped osmo_counters%s",
399 VTY_NEWLINE);
400 return;
401 }
402
Alexander Couzensad580ba2016-05-16 16:01:45 +0200403 vty_out(vty, "// ungrouped osmo_counters%s", VTY_NEWLINE);
404 vty_out(vty, ".ungrouped osmo counters%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200405 vty_out(vty, "[options=\"header\"]%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200406 vty_out(vty, "|===%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200407 vty_out(vty, "| Name | Reference | Description%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200408 osmo_counters_for_each(asciidoc_handle_counter, vty);
409 vty_out(vty, "|===%s", VTY_NEWLINE);
410}
411
412static int asciidoc_rate_ctr_handler(
413 struct rate_ctr_group *ctrg, struct rate_ctr *ctr,
414 const struct rate_ctr_desc *desc, void *sctx_)
415{
416 struct vty *vty = sctx_;
417 char *name = osmo_asciidoc_escape(desc->name);
418 char *description = osmo_asciidoc_escape(desc->description);
419 char *group_name_prefix = osmo_asciidoc_escape(ctrg->desc->group_name_prefix);
420
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200421 /* | Name | This document & | Description | */
Alexander Couzensad580ba2016-05-16 16:01:45 +0200422 vty_out(vty, "| %s | <<%s_%s>> | %s%s",
423 name,
424 group_name_prefix,
425 name,
426 description ? description : NULL,
427 VTY_NEWLINE);
428
429 /* description seems to be optional */
430 talloc_free(name);
431 talloc_free(group_name_prefix);
432 talloc_free(description);
433
434 return 0;
435}
436
437static int asciidoc_rate_ctr_group_handler(struct rate_ctr_group *ctrg, void *sctx_)
438{
439 struct vty *vty = sctx_;
440
441 char *group_description = osmo_asciidoc_escape(ctrg->desc->group_description);
442 char *group_name_prefix = osmo_asciidoc_escape(ctrg->desc->group_name_prefix);
443
444 vty_out(vty, "// rate_ctr_group table %s%s", group_description, VTY_NEWLINE);
445 vty_out(vty, ".%s - %s %s", group_name_prefix, group_description, VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200446 vty_out(vty, "[options=\"header\"]%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200447 vty_out(vty, "|===%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200448 vty_out(vty, "| Name | Reference | Description%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200449 rate_ctr_for_each_counter(ctrg, asciidoc_rate_ctr_handler, sctx_);
450 vty_out(vty, "|===%s", VTY_NEWLINE);
451
452 talloc_free(group_name_prefix);
453 talloc_free(group_description);
454
455 return 0;
456}
457
458static int asciidoc_osmo_stat_item_handler(
459 struct osmo_stat_item_group *statg, struct osmo_stat_item *item, void *sctx_)
460{
461 struct vty *vty = sctx_;
462
463 char *name = osmo_asciidoc_escape(item->desc->name);
464 char *description = osmo_asciidoc_escape(item->desc->description);
465 char *group_name_prefix = osmo_asciidoc_escape(statg->desc->group_name_prefix);
466 char *unit = osmo_asciidoc_escape(item->desc->unit);
467
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200468 /* | Name | Reference | Description | Unit | */
Alexander Couzensad580ba2016-05-16 16:01:45 +0200469 vty_out(vty, "| %s | <<%s_%s>> | %s | %s%s",
470 name,
471 group_name_prefix,
472 name,
473 description ? description : "",
474 unit ? unit : "",
475 VTY_NEWLINE);
476
477 talloc_free(name);
478 talloc_free(group_name_prefix);
479 talloc_free(description);
480 talloc_free(unit);
481
482 return 0;
483}
484
485static int asciidoc_osmo_stat_item_group_handler(struct osmo_stat_item_group *statg, void *sctx_)
486{
487 char *group_name_prefix = osmo_asciidoc_escape(statg->desc->group_name_prefix);
488 char *group_description = osmo_asciidoc_escape(statg->desc->group_description);
489
490 struct vty *vty = sctx_;
491 vty_out(vty, "%s%s", group_description ? group_description : "" , VTY_NEWLINE);
492
493 vty_out(vty, "// osmo_stat_item_group table %s%s", group_description ? group_description : "", VTY_NEWLINE);
494 vty_out(vty, ".%s - %s %s", group_name_prefix, group_description ? group_description : "", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200495 vty_out(vty, "[options=\"header\"]%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200496 vty_out(vty, "|===%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200497 vty_out(vty, "| Name | Reference | Description | Unit%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200498 osmo_stat_item_for_each_item(statg, asciidoc_osmo_stat_item_handler, sctx_);
499 vty_out(vty, "|===%s", VTY_NEWLINE);
500
501 talloc_free(group_name_prefix);
502 talloc_free(group_description);
503
504 return 0;
505}
506
507DEFUN(show_stats_asciidoc_table,
508 show_stats_asciidoc_table_cmd,
509 "show asciidoc counters",
Harald Weltef624c332016-06-15 11:35:16 +0200510 SHOW_STR "Asciidoc generation\n" "Generate table of all registered counters\n")
Alexander Couzensad580ba2016-05-16 16:01:45 +0200511{
Alexander Couzense052dc22016-10-04 18:04:37 +0200512 vty_out(vty, "// autogenerated by show asciidoc counters%s", VTY_NEWLINE);
513 vty_out(vty, "These counters and their description based on %s %s (%s).%s%s",
514 host.app_info->name,
515 host.app_info->version,
516 host.app_info->name ? host.app_info->name : "", VTY_NEWLINE, VTY_NEWLINE);
517 /* 2x VTY_NEWLINE are intentional otherwise it would interpret the first table header
518 * as usual text*/
Daniel Willmannd910a352018-07-24 20:01:26 +0200519 vty_out(vty, "=== Rate Counters%s%s", VTY_NEWLINE, VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200520 vty_out(vty, "// generating tables for rate_ctr_group%s", VTY_NEWLINE);
521 rate_ctr_for_each_group(asciidoc_rate_ctr_group_handler, vty);
522
Daniel Willmannd910a352018-07-24 20:01:26 +0200523 vty_out(vty, "== Osmo Stat Items%s%s", VTY_NEWLINE, VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200524 vty_out(vty, "// generating tables for osmo_stat_items%s", VTY_NEWLINE);
525 osmo_stat_item_for_each_group(asciidoc_osmo_stat_item_group_handler, vty);
526
Daniel Willmannd910a352018-07-24 20:01:26 +0200527 vty_out(vty, "== Osmo Counters%s%s", VTY_NEWLINE, VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200528 vty_out(vty, "// generating tables for osmo_counters%s", VTY_NEWLINE);
529 asciidoc_counter_generate(vty);
530 return CMD_SUCCESS;
531}
532
Stefan Sperling73b7fa62018-05-24 18:40:03 +0200533static int rate_ctr_group_handler(struct rate_ctr_group *ctrg, void *sctx_)
534{
535 struct vty *vty = sctx_;
536 vty_out_rate_ctr_group_fmt(vty, "%25n: %10c (%S/s %M/m %H/h %D/d) %d", ctrg);
537 return 0;
538}
539
540DEFUN(show_rate_counters,
541 show_rate_counters_cmd,
542 "show rate-counters",
543 SHOW_STR "Show all rate counters\n")
544{
545 rate_ctr_for_each_group(rate_ctr_group_handler, vty);
546 return CMD_SUCCESS;
547}
548
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100549static int config_write_stats_reporter(struct vty *vty, struct osmo_stats_reporter *srep)
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200550{
551 if (srep == NULL)
552 return 0;
553
554 switch (srep->type) {
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100555 case OSMO_STATS_REPORTER_STATSD:
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200556 vty_out(vty, "stats reporter statsd%s", VTY_NEWLINE);
557 break;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100558 case OSMO_STATS_REPORTER_LOG:
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100559 vty_out(vty, "stats reporter log%s", VTY_NEWLINE);
560 break;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200561 }
562
563 vty_out(vty, " disable%s", VTY_NEWLINE);
564
Jacob Erlbecked197fd2015-10-27 14:43:24 +0100565 if (srep->have_net_config) {
566 if (srep->dest_addr_str)
567 vty_out(vty, " remote-ip %s%s",
568 srep->dest_addr_str, VTY_NEWLINE);
569 if (srep->dest_port)
570 vty_out(vty, " remote-port %d%s",
571 srep->dest_port, VTY_NEWLINE);
572 if (srep->bind_addr_str)
573 vty_out(vty, " local-ip %s%s",
574 srep->bind_addr_str, VTY_NEWLINE);
575 if (srep->mtu)
576 vty_out(vty, " mtu %d%s",
577 srep->mtu, VTY_NEWLINE);
578 }
579
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100580 if (srep->max_class)
581 vty_out(vty, " level %s%s",
582 get_value_string(stats_class_strs, srep->max_class),
583 VTY_NEWLINE);
584
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200585 if (srep->name_prefix && *srep->name_prefix)
586 vty_out(vty, " prefix %s%s",
587 srep->name_prefix, VTY_NEWLINE);
588 else
589 vty_out(vty, " no prefix%s", VTY_NEWLINE);
590
591 if (srep->enabled)
592 vty_out(vty, " enable%s", VTY_NEWLINE);
593
594 return 1;
595}
596
597static int config_write_stats(struct vty *vty)
598{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100599 struct osmo_stats_reporter *srep;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200600
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100601 /* TODO: loop through all reporters */
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100602 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_STATSD, NULL);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200603 config_write_stats_reporter(vty, srep);
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100604 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_LOG, NULL);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100605 config_write_stats_reporter(vty, srep);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200606
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100607 vty_out(vty, "stats interval %d%s", osmo_stats_config->interval, VTY_NEWLINE);
Jacob Erlbeckb1dbfb42015-10-26 11:58:38 +0100608
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200609 return 1;
610}
611
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200612/*! Add stats related commands to the VTY
Harald Welte96e2a002017-06-12 21:44:18 +0200613 * Call this once during your application initialization if you would
614 * like to have stats VTY commands enabled.
615 */
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100616void osmo_stats_vty_add_cmds()
Jacob Erlbeck45513e62015-10-19 15:14:13 +0200617{
618 install_element_ve(&show_stats_cmd);
Jacob Erlbeck59b90bc2015-11-03 16:21:40 +0100619 install_element_ve(&show_stats_level_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200620
621 install_element(CONFIG_NODE, &cfg_stats_reporter_statsd_cmd);
622 install_element(CONFIG_NODE, &cfg_no_stats_reporter_statsd_cmd);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100623 install_element(CONFIG_NODE, &cfg_stats_reporter_log_cmd);
624 install_element(CONFIG_NODE, &cfg_no_stats_reporter_log_cmd);
Jacob Erlbeckb1dbfb42015-10-26 11:58:38 +0100625 install_element(CONFIG_NODE, &cfg_stats_interval_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200626
627 install_node(&cfg_stats_node, config_write_stats);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200628
629 install_element(CFG_STATS_NODE, &cfg_stats_reporter_local_ip_cmd);
630 install_element(CFG_STATS_NODE, &cfg_no_stats_reporter_local_ip_cmd);
631 install_element(CFG_STATS_NODE, &cfg_stats_reporter_remote_ip_cmd);
632 install_element(CFG_STATS_NODE, &cfg_stats_reporter_remote_port_cmd);
Jacob Erlbeckd01acfc2015-10-26 16:22:45 +0100633 install_element(CFG_STATS_NODE, &cfg_stats_reporter_mtu_cmd);
634 install_element(CFG_STATS_NODE, &cfg_no_stats_reporter_mtu_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200635 install_element(CFG_STATS_NODE, &cfg_stats_reporter_prefix_cmd);
636 install_element(CFG_STATS_NODE, &cfg_no_stats_reporter_prefix_cmd);
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100637 install_element(CFG_STATS_NODE, &cfg_stats_reporter_level_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200638 install_element(CFG_STATS_NODE, &cfg_stats_reporter_enable_cmd);
639 install_element(CFG_STATS_NODE, &cfg_stats_reporter_disable_cmd);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200640
641 install_element_ve(&show_stats_asciidoc_table_cmd);
Stefan Sperling73b7fa62018-05-24 18:40:03 +0200642 install_element_ve(&show_rate_counters_cmd);
Jacob Erlbeck45513e62015-10-19 15:14:13 +0200643}