blob: 6c09c38e0b75a83cd6a55b84cc0e7103fea21c7c [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{
396 vty_out(vty, "// ungrouped osmo_counters%s", VTY_NEWLINE);
397 vty_out(vty, ".ungrouped osmo counters%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200398 vty_out(vty, "[options=\"header\"]%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200399 vty_out(vty, "|===%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200400 vty_out(vty, "| Name | Reference | Description%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200401 osmo_counters_for_each(asciidoc_handle_counter, vty);
402 vty_out(vty, "|===%s", VTY_NEWLINE);
403}
404
405static int asciidoc_rate_ctr_handler(
406 struct rate_ctr_group *ctrg, struct rate_ctr *ctr,
407 const struct rate_ctr_desc *desc, void *sctx_)
408{
409 struct vty *vty = sctx_;
410 char *name = osmo_asciidoc_escape(desc->name);
411 char *description = osmo_asciidoc_escape(desc->description);
412 char *group_name_prefix = osmo_asciidoc_escape(ctrg->desc->group_name_prefix);
413
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200414 /* | Name | This document & | Description | */
Alexander Couzensad580ba2016-05-16 16:01:45 +0200415 vty_out(vty, "| %s | <<%s_%s>> | %s%s",
416 name,
417 group_name_prefix,
418 name,
419 description ? description : NULL,
420 VTY_NEWLINE);
421
422 /* description seems to be optional */
423 talloc_free(name);
424 talloc_free(group_name_prefix);
425 talloc_free(description);
426
427 return 0;
428}
429
430static int asciidoc_rate_ctr_group_handler(struct rate_ctr_group *ctrg, void *sctx_)
431{
432 struct vty *vty = sctx_;
433
434 char *group_description = osmo_asciidoc_escape(ctrg->desc->group_description);
435 char *group_name_prefix = osmo_asciidoc_escape(ctrg->desc->group_name_prefix);
436
437 vty_out(vty, "// rate_ctr_group table %s%s", group_description, VTY_NEWLINE);
438 vty_out(vty, ".%s - %s %s", group_name_prefix, group_description, VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200439 vty_out(vty, "[options=\"header\"]%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200440 vty_out(vty, "|===%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200441 vty_out(vty, "| Name | Reference | Description%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200442 rate_ctr_for_each_counter(ctrg, asciidoc_rate_ctr_handler, sctx_);
443 vty_out(vty, "|===%s", VTY_NEWLINE);
444
445 talloc_free(group_name_prefix);
446 talloc_free(group_description);
447
448 return 0;
449}
450
451static int asciidoc_osmo_stat_item_handler(
452 struct osmo_stat_item_group *statg, struct osmo_stat_item *item, void *sctx_)
453{
454 struct vty *vty = sctx_;
455
456 char *name = osmo_asciidoc_escape(item->desc->name);
457 char *description = osmo_asciidoc_escape(item->desc->description);
458 char *group_name_prefix = osmo_asciidoc_escape(statg->desc->group_name_prefix);
459 char *unit = osmo_asciidoc_escape(item->desc->unit);
460
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200461 /* | Name | Reference | Description | Unit | */
Alexander Couzensad580ba2016-05-16 16:01:45 +0200462 vty_out(vty, "| %s | <<%s_%s>> | %s | %s%s",
463 name,
464 group_name_prefix,
465 name,
466 description ? description : "",
467 unit ? unit : "",
468 VTY_NEWLINE);
469
470 talloc_free(name);
471 talloc_free(group_name_prefix);
472 talloc_free(description);
473 talloc_free(unit);
474
475 return 0;
476}
477
478static int asciidoc_osmo_stat_item_group_handler(struct osmo_stat_item_group *statg, void *sctx_)
479{
480 char *group_name_prefix = osmo_asciidoc_escape(statg->desc->group_name_prefix);
481 char *group_description = osmo_asciidoc_escape(statg->desc->group_description);
482
483 struct vty *vty = sctx_;
484 vty_out(vty, "%s%s", group_description ? group_description : "" , VTY_NEWLINE);
485
486 vty_out(vty, "// osmo_stat_item_group table %s%s", group_description ? group_description : "", VTY_NEWLINE);
487 vty_out(vty, ".%s - %s %s", group_name_prefix, group_description ? group_description : "", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200488 vty_out(vty, "[options=\"header\"]%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200489 vty_out(vty, "|===%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200490 vty_out(vty, "| Name | Reference | Description | Unit%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200491 osmo_stat_item_for_each_item(statg, asciidoc_osmo_stat_item_handler, sctx_);
492 vty_out(vty, "|===%s", VTY_NEWLINE);
493
494 talloc_free(group_name_prefix);
495 talloc_free(group_description);
496
497 return 0;
498}
499
500DEFUN(show_stats_asciidoc_table,
501 show_stats_asciidoc_table_cmd,
502 "show asciidoc counters",
Harald Weltef624c332016-06-15 11:35:16 +0200503 SHOW_STR "Asciidoc generation\n" "Generate table of all registered counters\n")
Alexander Couzensad580ba2016-05-16 16:01:45 +0200504{
Alexander Couzense052dc22016-10-04 18:04:37 +0200505 vty_out(vty, "// autogenerated by show asciidoc counters%s", VTY_NEWLINE);
506 vty_out(vty, "These counters and their description based on %s %s (%s).%s%s",
507 host.app_info->name,
508 host.app_info->version,
509 host.app_info->name ? host.app_info->name : "", VTY_NEWLINE, VTY_NEWLINE);
510 /* 2x VTY_NEWLINE are intentional otherwise it would interpret the first table header
511 * as usual text*/
Alexander Couzensad580ba2016-05-16 16:01:45 +0200512 vty_out(vty, "// generating tables for rate_ctr_group%s", VTY_NEWLINE);
513 rate_ctr_for_each_group(asciidoc_rate_ctr_group_handler, vty);
514
515 vty_out(vty, "// generating tables for osmo_stat_items%s", VTY_NEWLINE);
516 osmo_stat_item_for_each_group(asciidoc_osmo_stat_item_group_handler, vty);
517
518 vty_out(vty, "// generating tables for osmo_counters%s", VTY_NEWLINE);
519 asciidoc_counter_generate(vty);
520 return CMD_SUCCESS;
521}
522
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100523static int config_write_stats_reporter(struct vty *vty, struct osmo_stats_reporter *srep)
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200524{
525 if (srep == NULL)
526 return 0;
527
528 switch (srep->type) {
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100529 case OSMO_STATS_REPORTER_STATSD:
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200530 vty_out(vty, "stats reporter statsd%s", VTY_NEWLINE);
531 break;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100532 case OSMO_STATS_REPORTER_LOG:
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100533 vty_out(vty, "stats reporter log%s", VTY_NEWLINE);
534 break;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200535 }
536
537 vty_out(vty, " disable%s", VTY_NEWLINE);
538
Jacob Erlbecked197fd2015-10-27 14:43:24 +0100539 if (srep->have_net_config) {
540 if (srep->dest_addr_str)
541 vty_out(vty, " remote-ip %s%s",
542 srep->dest_addr_str, VTY_NEWLINE);
543 if (srep->dest_port)
544 vty_out(vty, " remote-port %d%s",
545 srep->dest_port, VTY_NEWLINE);
546 if (srep->bind_addr_str)
547 vty_out(vty, " local-ip %s%s",
548 srep->bind_addr_str, VTY_NEWLINE);
549 if (srep->mtu)
550 vty_out(vty, " mtu %d%s",
551 srep->mtu, VTY_NEWLINE);
552 }
553
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100554 if (srep->max_class)
555 vty_out(vty, " level %s%s",
556 get_value_string(stats_class_strs, srep->max_class),
557 VTY_NEWLINE);
558
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200559 if (srep->name_prefix && *srep->name_prefix)
560 vty_out(vty, " prefix %s%s",
561 srep->name_prefix, VTY_NEWLINE);
562 else
563 vty_out(vty, " no prefix%s", VTY_NEWLINE);
564
565 if (srep->enabled)
566 vty_out(vty, " enable%s", VTY_NEWLINE);
567
568 return 1;
569}
570
571static int config_write_stats(struct vty *vty)
572{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100573 struct osmo_stats_reporter *srep;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200574
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100575 /* TODO: loop through all reporters */
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100576 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_STATSD, NULL);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200577 config_write_stats_reporter(vty, srep);
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100578 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_LOG, NULL);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100579 config_write_stats_reporter(vty, srep);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200580
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100581 vty_out(vty, "stats interval %d%s", osmo_stats_config->interval, VTY_NEWLINE);
Jacob Erlbeckb1dbfb42015-10-26 11:58:38 +0100582
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200583 return 1;
584}
585
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200586/*! Add stats related commands to the VTY
Harald Welte96e2a002017-06-12 21:44:18 +0200587 * Call this once during your application initialization if you would
588 * like to have stats VTY commands enabled.
589 */
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100590void osmo_stats_vty_add_cmds()
Jacob Erlbeck45513e62015-10-19 15:14:13 +0200591{
592 install_element_ve(&show_stats_cmd);
Jacob Erlbeck59b90bc2015-11-03 16:21:40 +0100593 install_element_ve(&show_stats_level_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200594
595 install_element(CONFIG_NODE, &cfg_stats_reporter_statsd_cmd);
596 install_element(CONFIG_NODE, &cfg_no_stats_reporter_statsd_cmd);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100597 install_element(CONFIG_NODE, &cfg_stats_reporter_log_cmd);
598 install_element(CONFIG_NODE, &cfg_no_stats_reporter_log_cmd);
Jacob Erlbeckb1dbfb42015-10-26 11:58:38 +0100599 install_element(CONFIG_NODE, &cfg_stats_interval_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200600
601 install_node(&cfg_stats_node, config_write_stats);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200602
603 install_element(CFG_STATS_NODE, &cfg_stats_reporter_local_ip_cmd);
604 install_element(CFG_STATS_NODE, &cfg_no_stats_reporter_local_ip_cmd);
605 install_element(CFG_STATS_NODE, &cfg_stats_reporter_remote_ip_cmd);
606 install_element(CFG_STATS_NODE, &cfg_stats_reporter_remote_port_cmd);
Jacob Erlbeckd01acfc2015-10-26 16:22:45 +0100607 install_element(CFG_STATS_NODE, &cfg_stats_reporter_mtu_cmd);
608 install_element(CFG_STATS_NODE, &cfg_no_stats_reporter_mtu_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200609 install_element(CFG_STATS_NODE, &cfg_stats_reporter_prefix_cmd);
610 install_element(CFG_STATS_NODE, &cfg_no_stats_reporter_prefix_cmd);
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100611 install_element(CFG_STATS_NODE, &cfg_stats_reporter_level_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200612 install_element(CFG_STATS_NODE, &cfg_stats_reporter_enable_cmd);
613 install_element(CFG_STATS_NODE, &cfg_stats_reporter_disable_cmd);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200614
615 install_element_ve(&show_stats_asciidoc_table_cmd);
Jacob Erlbeck45513e62015-10-19 15:14:13 +0200616}