blob: 95f04bc62bb9dda2a28c36d90ae47e5e1f1b9f01 [file] [log] [blame]
Neels Hofmeyr17518fe2017-06-20 04:35:06 +02001/*! \file stats_vty.c
2 * OpenBSC stats helper for the VTY. */
3/*
4 * (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
Jacob Erlbeck45513e62015-10-19 15:14:13 +02005 * (C) 2009-2014 by Holger Hans Peter Freyther
6 * (C) 2015 by Sysmocom s.f.m.c. GmbH
7 * All Rights Reserved
8 *
9 * 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 Welte96e2a002017-06-12 21:44:18 +020046/*! \addtogroup stats
47 * @{
Neels Hofmeyr87e45502017-06-20 00:17:59 +020048 * VTY interface for statsd / statistic items
Harald Welte96e2a002017-06-12 21:44:18 +020049 */
50
Alexander Couzense052dc22016-10-04 18:04:37 +020051/* containing version info */
52extern struct host host;
53
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020054struct cmd_node cfg_stats_node = {
55 CFG_STATS_NODE,
56 "%s(config-stats)# ",
57 1
58};
59
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +010060static const struct value_string stats_class_strs[] = {
61 { OSMO_STATS_CLASS_GLOBAL, "global" },
62 { OSMO_STATS_CLASS_PEER, "peer" },
63 { OSMO_STATS_CLASS_SUBSCRIBER, "subscriber" },
64 { 0, NULL }
65};
66
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +010067static struct osmo_stats_reporter *osmo_stats_vty2srep(struct vty *vty)
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020068{
69 if (vty->node == CFG_STATS_NODE)
70 return vty->index;
71
72 return NULL;
73}
74
75static int set_srep_parameter_str(struct vty *vty,
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +010076 int (*fun)(struct osmo_stats_reporter *, const char *),
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020077 const char *val, const char *param_name)
78{
79 int rc;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +010080 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020081 OSMO_ASSERT(srep);
82
83 rc = fun(srep, val);
84 if (rc < 0) {
85 vty_out(vty, "%% Unable to set %s: %s%s",
86 param_name, strerror(-rc), VTY_NEWLINE);
87 return CMD_WARNING;
88 }
89
90 return CMD_SUCCESS;
91}
92
93static int set_srep_parameter_int(struct vty *vty,
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +010094 int (*fun)(struct osmo_stats_reporter *, int),
Jacob Erlbeckadc900e2015-10-20 19:05:52 +020095 const char *val, const char *param_name)
96{
97 int rc;
98 int int_val;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +010099 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200100 OSMO_ASSERT(srep);
101
102 int_val = atoi(val);
103
104 rc = fun(srep, int_val);
105 if (rc < 0) {
106 vty_out(vty, "%% Unable to set %s: %s%s",
107 param_name, strerror(-rc), VTY_NEWLINE);
108 return CMD_WARNING;
109 }
110
111 return CMD_SUCCESS;
112}
113
114DEFUN(cfg_stats_reporter_local_ip, cfg_stats_reporter_local_ip_cmd,
115 "local-ip ADDR",
116 "Set the IP address to which we bind locally\n"
117 "IP Address\n")
118{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100119 return set_srep_parameter_str(vty, osmo_stats_reporter_set_local_addr,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200120 argv[0], "local address");
121}
122
123DEFUN(cfg_no_stats_reporter_local_ip, cfg_no_stats_reporter_local_ip_cmd,
124 "no local-ip",
125 NO_STR
126 "Set the IP address to which we bind locally\n")
127{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100128 return set_srep_parameter_str(vty, osmo_stats_reporter_set_local_addr,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200129 NULL, "local address");
130}
131
132DEFUN(cfg_stats_reporter_remote_ip, cfg_stats_reporter_remote_ip_cmd,
133 "remote-ip ADDR",
134 "Set the remote IP address to which we connect\n"
135 "IP Address\n")
136{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100137 return set_srep_parameter_str(vty, osmo_stats_reporter_set_remote_addr,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200138 argv[0], "remote address");
139}
140
141DEFUN(cfg_stats_reporter_remote_port, cfg_stats_reporter_remote_port_cmd,
142 "remote-port <1-65535>",
143 "Set the remote port to which we connect\n"
144 "Remote port number\n")
145{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100146 return set_srep_parameter_int(vty, osmo_stats_reporter_set_remote_port,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200147 argv[0], "remote port");
148}
149
Jacob Erlbeckd01acfc2015-10-26 16:22:45 +0100150DEFUN(cfg_stats_reporter_mtu, cfg_stats_reporter_mtu_cmd,
151 "mtu <100-65535>",
152 "Set the maximum packet size\n"
153 "Size in byte\n")
154{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100155 return set_srep_parameter_int(vty, osmo_stats_reporter_set_mtu,
Jacob Erlbeckd01acfc2015-10-26 16:22:45 +0100156 argv[0], "mtu");
157}
158
159DEFUN(cfg_no_stats_reporter_mtu, cfg_no_stats_reporter_mtu_cmd,
160 "no mtu",
161 NO_STR "Set the maximum packet size\n")
162{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100163 return set_srep_parameter_int(vty, osmo_stats_reporter_set_mtu,
Holger Hans Peter Freyther8f0374f2015-11-02 15:53:09 +0100164 "0", "mtu");
Jacob Erlbeckd01acfc2015-10-26 16:22:45 +0100165}
166
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200167DEFUN(cfg_stats_reporter_prefix, cfg_stats_reporter_prefix_cmd,
168 "prefix PREFIX",
169 "Set the item name prefix\n"
170 "The prefix string\n")
171{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100172 return set_srep_parameter_str(vty, osmo_stats_reporter_set_name_prefix,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200173 argv[0], "prefix string");
174}
175
176DEFUN(cfg_no_stats_reporter_prefix, cfg_no_stats_reporter_prefix_cmd,
177 "no prefix",
178 NO_STR
179 "Set the item name prefix\n")
180{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100181 return set_srep_parameter_str(vty, osmo_stats_reporter_set_name_prefix,
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200182 "", "prefix string");
183}
184
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100185DEFUN(cfg_stats_reporter_level, cfg_stats_reporter_level_cmd,
186 "level (global|peer|subscriber)",
187 "Set the maximum group level\n"
188 "Report global groups only\n"
189 "Report global and network peer related groups\n"
190 "Report global, peer, and subscriber groups\n")
191{
192 int level = get_string_value(stats_class_strs, argv[0]);
193 int rc;
194 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
195
196 OSMO_ASSERT(srep);
197 rc = osmo_stats_reporter_set_max_class(srep, level);
198 if (rc < 0) {
199 vty_out(vty, "%% Unable to set level: %s%s",
200 strerror(-rc), VTY_NEWLINE);
201 return CMD_WARNING;
202 }
203
204 return 0;
205}
206
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200207DEFUN(cfg_stats_reporter_enable, cfg_stats_reporter_enable_cmd,
208 "enable",
209 "Enable the reporter\n")
210{
211 int rc;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100212 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200213 OSMO_ASSERT(srep);
214
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100215 rc = osmo_stats_reporter_enable(srep);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200216 if (rc < 0) {
217 vty_out(vty, "%% Unable to enable the reporter: %s%s",
218 strerror(-rc), VTY_NEWLINE);
219 return CMD_WARNING;
220 }
221
222 return CMD_SUCCESS;
223}
224
225DEFUN(cfg_stats_reporter_disable, cfg_stats_reporter_disable_cmd,
226 "disable",
227 "Disable the reporter\n")
228{
229 int rc;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100230 struct osmo_stats_reporter *srep = osmo_stats_vty2srep(vty);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200231 OSMO_ASSERT(srep);
232
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100233 rc = osmo_stats_reporter_disable(srep);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200234 if (rc < 0) {
235 vty_out(vty, "%% Unable to disable the reporter: %s%s",
236 strerror(-rc), VTY_NEWLINE);
237 return CMD_WARNING;
238 }
239
240 return CMD_SUCCESS;
241}
242
243DEFUN(cfg_stats_reporter_statsd, cfg_stats_reporter_statsd_cmd,
244 "stats reporter statsd",
245 CFG_STATS_STR CFG_REPORTER_STR "Report to a STATSD server\n")
246{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100247 struct osmo_stats_reporter *srep;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200248
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100249 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_STATSD, NULL);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200250 if (!srep) {
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100251 srep = osmo_stats_reporter_create_statsd(NULL);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200252 if (!srep) {
253 vty_out(vty, "%% Unable to create statsd reporter%s",
254 VTY_NEWLINE);
255 return CMD_WARNING;
256 }
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100257 srep->max_class = OSMO_STATS_CLASS_GLOBAL;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100258 /* TODO: if needed, add osmo_stats_add_reporter(srep); */
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200259 }
260
261 vty->index = srep;
262 vty->node = CFG_STATS_NODE;
263
264 return CMD_SUCCESS;
265}
266
Jacob Erlbeckb1dbfb42015-10-26 11:58:38 +0100267DEFUN(cfg_stats_interval, cfg_stats_interval_cmd,
268 "stats interval <1-65535>",
269 CFG_STATS_STR "Set the reporting interval\n"
270 "Interval in seconds\n")
271{
272 int rc;
273 int interval = atoi(argv[0]);
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100274 rc = osmo_stats_set_interval(interval);
Jacob Erlbeckb1dbfb42015-10-26 11:58:38 +0100275 if (rc < 0) {
276 vty_out(vty, "%% Unable to set interval: %s%s",
277 strerror(-rc), VTY_NEWLINE);
278 return CMD_WARNING;
279 }
280
281 return CMD_SUCCESS;
282}
283
284
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200285DEFUN(cfg_no_stats_reporter_statsd, cfg_no_stats_reporter_statsd_cmd,
286 "no stats reporter statsd",
287 NO_STR CFG_STATS_STR CFG_REPORTER_STR "Report to a STATSD server\n")
288{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100289 struct osmo_stats_reporter *srep;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200290
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100291 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_STATSD, NULL);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200292 if (!srep) {
293 vty_out(vty, "%% No statsd logging active%s",
294 VTY_NEWLINE);
295 return CMD_WARNING;
296 }
297
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100298 osmo_stats_reporter_free(srep);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200299
300 return CMD_SUCCESS;
301}
302
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100303DEFUN(cfg_stats_reporter_log, cfg_stats_reporter_log_cmd,
304 "stats reporter log",
305 CFG_STATS_STR CFG_REPORTER_STR "Report to the logger\n")
306{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100307 struct osmo_stats_reporter *srep;
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100308
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100309 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_LOG, NULL);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100310 if (!srep) {
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100311 srep = osmo_stats_reporter_create_log(NULL);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100312 if (!srep) {
313 vty_out(vty, "%% Unable to create log reporter%s",
314 VTY_NEWLINE);
315 return CMD_WARNING;
316 }
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100317 srep->max_class = OSMO_STATS_CLASS_GLOBAL;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100318 /* TODO: if needed, add osmo_stats_add_reporter(srep); */
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100319 }
320
321 vty->index = srep;
322 vty->node = CFG_STATS_NODE;
323
324 return CMD_SUCCESS;
325}
326
327DEFUN(cfg_no_stats_reporter_log, cfg_no_stats_reporter_log_cmd,
328 "no stats reporter log",
329 NO_STR CFG_STATS_STR CFG_REPORTER_STR "Report to the logger\n")
330{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100331 struct osmo_stats_reporter *srep;
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100332
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100333 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_LOG, NULL);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100334 if (!srep) {
335 vty_out(vty, "%% No log reporting active%s",
336 VTY_NEWLINE);
337 return CMD_WARNING;
338 }
339
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100340 osmo_stats_reporter_free(srep);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100341
342 return CMD_SUCCESS;
343}
344
Jacob Erlbeck45513e62015-10-19 15:14:13 +0200345DEFUN(show_stats,
346 show_stats_cmd,
347 "show stats",
348 SHOW_STR SHOW_STATS_STR)
349{
350 vty_out_statistics_full(vty, "");
351
352 return CMD_SUCCESS;
353}
354
Jacob Erlbeck59b90bc2015-11-03 16:21:40 +0100355DEFUN(show_stats_level,
356 show_stats_level_cmd,
357 "show stats level (global|peer|subscriber)",
358 SHOW_STR SHOW_STATS_STR
Holger Hans Peter Freyther83481942015-11-07 21:10:01 +0100359 "Set the maximum group level\n"
Jacob Erlbeck59b90bc2015-11-03 16:21:40 +0100360 "Show global groups only\n"
361 "Show global and network peer related groups\n"
362 "Show global, peer, and subscriber groups\n")
363{
364 int level = get_string_value(stats_class_strs, argv[0]);
365 vty_out_statistics_partial(vty, "", level);
366
367 return CMD_SUCCESS;
368}
369
Alexander Couzensad580ba2016-05-16 16:01:45 +0200370static int asciidoc_handle_counter(struct osmo_counter *counter, void *sctx_)
371{
372 struct vty *vty = sctx_;
373 char *name = osmo_asciidoc_escape(counter->name);
374 char *description = osmo_asciidoc_escape(counter->description);
375
376 /* | name | This document & | description | */
377 vty_out(vty, "| %s | <<ungroup_counter_%s>> | %s%s",
378 name,
379 name,
380 description ? description : "",
381 VTY_NEWLINE);
382
383 talloc_free(name);
384 talloc_free(description);
385
386 return 0;
387}
388
389static void asciidoc_counter_generate(struct vty *vty)
390{
391 vty_out(vty, "// ungrouped osmo_counters%s", VTY_NEWLINE);
392 vty_out(vty, ".ungrouped osmo counters%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200393 vty_out(vty, "[options=\"header\"]%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200394 vty_out(vty, "|===%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200395 vty_out(vty, "| Name | Reference | Description%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200396 osmo_counters_for_each(asciidoc_handle_counter, vty);
397 vty_out(vty, "|===%s", VTY_NEWLINE);
398}
399
400static int asciidoc_rate_ctr_handler(
401 struct rate_ctr_group *ctrg, struct rate_ctr *ctr,
402 const struct rate_ctr_desc *desc, void *sctx_)
403{
404 struct vty *vty = sctx_;
405 char *name = osmo_asciidoc_escape(desc->name);
406 char *description = osmo_asciidoc_escape(desc->description);
407 char *group_name_prefix = osmo_asciidoc_escape(ctrg->desc->group_name_prefix);
408
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200409 /* | Name | This document & | Description | */
Alexander Couzensad580ba2016-05-16 16:01:45 +0200410 vty_out(vty, "| %s | <<%s_%s>> | %s%s",
411 name,
412 group_name_prefix,
413 name,
414 description ? description : NULL,
415 VTY_NEWLINE);
416
417 /* description seems to be optional */
418 talloc_free(name);
419 talloc_free(group_name_prefix);
420 talloc_free(description);
421
422 return 0;
423}
424
425static int asciidoc_rate_ctr_group_handler(struct rate_ctr_group *ctrg, void *sctx_)
426{
427 struct vty *vty = sctx_;
428
429 char *group_description = osmo_asciidoc_escape(ctrg->desc->group_description);
430 char *group_name_prefix = osmo_asciidoc_escape(ctrg->desc->group_name_prefix);
431
432 vty_out(vty, "// rate_ctr_group table %s%s", group_description, VTY_NEWLINE);
433 vty_out(vty, ".%s - %s %s", group_name_prefix, group_description, VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200434 vty_out(vty, "[options=\"header\"]%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200435 vty_out(vty, "|===%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200436 vty_out(vty, "| Name | Reference | Description%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200437 rate_ctr_for_each_counter(ctrg, asciidoc_rate_ctr_handler, sctx_);
438 vty_out(vty, "|===%s", VTY_NEWLINE);
439
440 talloc_free(group_name_prefix);
441 talloc_free(group_description);
442
443 return 0;
444}
445
446static int asciidoc_osmo_stat_item_handler(
447 struct osmo_stat_item_group *statg, struct osmo_stat_item *item, void *sctx_)
448{
449 struct vty *vty = sctx_;
450
451 char *name = osmo_asciidoc_escape(item->desc->name);
452 char *description = osmo_asciidoc_escape(item->desc->description);
453 char *group_name_prefix = osmo_asciidoc_escape(statg->desc->group_name_prefix);
454 char *unit = osmo_asciidoc_escape(item->desc->unit);
455
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200456 /* | Name | Reference | Description | Unit | */
Alexander Couzensad580ba2016-05-16 16:01:45 +0200457 vty_out(vty, "| %s | <<%s_%s>> | %s | %s%s",
458 name,
459 group_name_prefix,
460 name,
461 description ? description : "",
462 unit ? unit : "",
463 VTY_NEWLINE);
464
465 talloc_free(name);
466 talloc_free(group_name_prefix);
467 talloc_free(description);
468 talloc_free(unit);
469
470 return 0;
471}
472
473static int asciidoc_osmo_stat_item_group_handler(struct osmo_stat_item_group *statg, void *sctx_)
474{
475 char *group_name_prefix = osmo_asciidoc_escape(statg->desc->group_name_prefix);
476 char *group_description = osmo_asciidoc_escape(statg->desc->group_description);
477
478 struct vty *vty = sctx_;
479 vty_out(vty, "%s%s", group_description ? group_description : "" , VTY_NEWLINE);
480
481 vty_out(vty, "// osmo_stat_item_group table %s%s", group_description ? group_description : "", VTY_NEWLINE);
482 vty_out(vty, ".%s - %s %s", group_name_prefix, group_description ? group_description : "", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200483 vty_out(vty, "[options=\"header\"]%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200484 vty_out(vty, "|===%s", VTY_NEWLINE);
Alexander Couzenseb604cf2016-10-14 13:54:47 +0200485 vty_out(vty, "| Name | Reference | Description | Unit%s", VTY_NEWLINE);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200486 osmo_stat_item_for_each_item(statg, asciidoc_osmo_stat_item_handler, sctx_);
487 vty_out(vty, "|===%s", VTY_NEWLINE);
488
489 talloc_free(group_name_prefix);
490 talloc_free(group_description);
491
492 return 0;
493}
494
495DEFUN(show_stats_asciidoc_table,
496 show_stats_asciidoc_table_cmd,
497 "show asciidoc counters",
Harald Weltef624c332016-06-15 11:35:16 +0200498 SHOW_STR "Asciidoc generation\n" "Generate table of all registered counters\n")
Alexander Couzensad580ba2016-05-16 16:01:45 +0200499{
Alexander Couzense052dc22016-10-04 18:04:37 +0200500 vty_out(vty, "// autogenerated by show asciidoc counters%s", VTY_NEWLINE);
501 vty_out(vty, "These counters and their description based on %s %s (%s).%s%s",
502 host.app_info->name,
503 host.app_info->version,
504 host.app_info->name ? host.app_info->name : "", VTY_NEWLINE, VTY_NEWLINE);
505 /* 2x VTY_NEWLINE are intentional otherwise it would interpret the first table header
506 * as usual text*/
Alexander Couzensad580ba2016-05-16 16:01:45 +0200507 vty_out(vty, "// generating tables for rate_ctr_group%s", VTY_NEWLINE);
508 rate_ctr_for_each_group(asciidoc_rate_ctr_group_handler, vty);
509
510 vty_out(vty, "// generating tables for osmo_stat_items%s", VTY_NEWLINE);
511 osmo_stat_item_for_each_group(asciidoc_osmo_stat_item_group_handler, vty);
512
513 vty_out(vty, "// generating tables for osmo_counters%s", VTY_NEWLINE);
514 asciidoc_counter_generate(vty);
515 return CMD_SUCCESS;
516}
517
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100518static int config_write_stats_reporter(struct vty *vty, struct osmo_stats_reporter *srep)
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200519{
520 if (srep == NULL)
521 return 0;
522
523 switch (srep->type) {
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100524 case OSMO_STATS_REPORTER_STATSD:
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200525 vty_out(vty, "stats reporter statsd%s", VTY_NEWLINE);
526 break;
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100527 case OSMO_STATS_REPORTER_LOG:
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100528 vty_out(vty, "stats reporter log%s", VTY_NEWLINE);
529 break;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200530 }
531
532 vty_out(vty, " disable%s", VTY_NEWLINE);
533
Jacob Erlbecked197fd2015-10-27 14:43:24 +0100534 if (srep->have_net_config) {
535 if (srep->dest_addr_str)
536 vty_out(vty, " remote-ip %s%s",
537 srep->dest_addr_str, VTY_NEWLINE);
538 if (srep->dest_port)
539 vty_out(vty, " remote-port %d%s",
540 srep->dest_port, VTY_NEWLINE);
541 if (srep->bind_addr_str)
542 vty_out(vty, " local-ip %s%s",
543 srep->bind_addr_str, VTY_NEWLINE);
544 if (srep->mtu)
545 vty_out(vty, " mtu %d%s",
546 srep->mtu, VTY_NEWLINE);
547 }
548
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100549 if (srep->max_class)
550 vty_out(vty, " level %s%s",
551 get_value_string(stats_class_strs, srep->max_class),
552 VTY_NEWLINE);
553
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200554 if (srep->name_prefix && *srep->name_prefix)
555 vty_out(vty, " prefix %s%s",
556 srep->name_prefix, VTY_NEWLINE);
557 else
558 vty_out(vty, " no prefix%s", VTY_NEWLINE);
559
560 if (srep->enabled)
561 vty_out(vty, " enable%s", VTY_NEWLINE);
562
563 return 1;
564}
565
566static int config_write_stats(struct vty *vty)
567{
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100568 struct osmo_stats_reporter *srep;
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200569
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100570 /* TODO: loop through all reporters */
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100571 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_STATSD, NULL);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200572 config_write_stats_reporter(vty, srep);
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100573 srep = osmo_stats_reporter_find(OSMO_STATS_REPORTER_LOG, NULL);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100574 config_write_stats_reporter(vty, srep);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200575
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100576 vty_out(vty, "stats interval %d%s", osmo_stats_config->interval, VTY_NEWLINE);
Jacob Erlbeckb1dbfb42015-10-26 11:58:38 +0100577
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200578 return 1;
579}
580
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200581/*! Add stats related commands to the VTY
Harald Welte96e2a002017-06-12 21:44:18 +0200582 * Call this once during your application initialization if you would
583 * like to have stats VTY commands enabled.
584 */
Jacob Erlbeckfc9533d2015-10-29 00:55:58 +0100585void osmo_stats_vty_add_cmds()
Jacob Erlbeck45513e62015-10-19 15:14:13 +0200586{
587 install_element_ve(&show_stats_cmd);
Jacob Erlbeck59b90bc2015-11-03 16:21:40 +0100588 install_element_ve(&show_stats_level_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200589
590 install_element(CONFIG_NODE, &cfg_stats_reporter_statsd_cmd);
591 install_element(CONFIG_NODE, &cfg_no_stats_reporter_statsd_cmd);
Jacob Erlbeckbc4f7ae2015-10-28 21:47:45 +0100592 install_element(CONFIG_NODE, &cfg_stats_reporter_log_cmd);
593 install_element(CONFIG_NODE, &cfg_no_stats_reporter_log_cmd);
Jacob Erlbeckb1dbfb42015-10-26 11:58:38 +0100594 install_element(CONFIG_NODE, &cfg_stats_interval_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200595
596 install_node(&cfg_stats_node, config_write_stats);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200597
598 install_element(CFG_STATS_NODE, &cfg_stats_reporter_local_ip_cmd);
599 install_element(CFG_STATS_NODE, &cfg_no_stats_reporter_local_ip_cmd);
600 install_element(CFG_STATS_NODE, &cfg_stats_reporter_remote_ip_cmd);
601 install_element(CFG_STATS_NODE, &cfg_stats_reporter_remote_port_cmd);
Jacob Erlbeckd01acfc2015-10-26 16:22:45 +0100602 install_element(CFG_STATS_NODE, &cfg_stats_reporter_mtu_cmd);
603 install_element(CFG_STATS_NODE, &cfg_no_stats_reporter_mtu_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200604 install_element(CFG_STATS_NODE, &cfg_stats_reporter_prefix_cmd);
605 install_element(CFG_STATS_NODE, &cfg_no_stats_reporter_prefix_cmd);
Jacob Erlbeckbc9d9ac2015-11-02 14:49:35 +0100606 install_element(CFG_STATS_NODE, &cfg_stats_reporter_level_cmd);
Jacob Erlbeckadc900e2015-10-20 19:05:52 +0200607 install_element(CFG_STATS_NODE, &cfg_stats_reporter_enable_cmd);
608 install_element(CFG_STATS_NODE, &cfg_stats_reporter_disable_cmd);
Alexander Couzensad580ba2016-05-16 16:01:45 +0200609
610 install_element_ve(&show_stats_asciidoc_table_cmd);
Jacob Erlbeck45513e62015-10-19 15:14:13 +0200611}
Harald Welte96e2a002017-06-12 21:44:18 +0200612
613/*! @} */