blob: 6004c479afc8f05da433cade690dba9490e35002 [file] [log] [blame]
Harald Welte3fb0b6f2010-05-19 19:02:52 +02001/* OpenBSC logging helper for the VTY */
2/* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +01003 * (C) 2009-2014 by Holger Hans Peter Freyther
Harald Welte3fb0b6f2010-05-19 19:02:52 +02004 * All Rights Reserved
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 */
21
22#include <stdlib.h>
23#include <string.h>
24
Harald Welte28222962011-02-18 20:37:04 +010025#include "../../config.h"
26
Pablo Neira Ayuso83419342011-03-22 16:36:13 +010027#include <osmocom/core/talloc.h>
28#include <osmocom/core/logging.h>
29#include <osmocom/core/utils.h>
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +000030#include <osmocom/core/strrb.h>
31#include <osmocom/core/loggingrb.h>
Harald Welteaa00f992016-12-02 15:30:02 +010032#include <osmocom/core/gsmtap.h>
Harald Welte3fb0b6f2010-05-19 19:02:52 +020033
34#include <osmocom/vty/command.h>
35#include <osmocom/vty/buffer.h>
36#include <osmocom/vty/vty.h>
37#include <osmocom/vty/telnet_interface.h>
38#include <osmocom/vty/logging.h>
39
Harald Welte28222962011-02-18 20:37:04 +010040#define LOG_STR "Configure logging sub-system\n"
41
Harald Welte4ebdf742010-05-19 19:54:00 +020042extern const struct log_info *osmo_log_info;
Harald Welte3fb0b6f2010-05-19 19:02:52 +020043
Harald Welte76e72ab2011-02-17 15:52:39 +010044static void _vty_output(struct log_target *tgt,
45 unsigned int level, const char *line)
Harald Welte3fb0b6f2010-05-19 19:02:52 +020046{
47 struct vty *vty = tgt->tgt_vty.vty;
48 vty_out(vty, "%s", line);
49 /* This is an ugly hack, but there is no easy way... */
50 if (strchr(line, '\n'))
51 vty_out(vty, "\r");
52}
53
54struct log_target *log_target_create_vty(struct vty *vty)
55{
56 struct log_target *target;
57
58 target = log_target_create();
59 if (!target)
60 return NULL;
61
62 target->tgt_vty.vty = vty;
63 target->output = _vty_output;
64 return target;
65}
66
67DEFUN(enable_logging,
68 enable_logging_cmd,
69 "logging enable",
70 LOGGING_STR
71 "Enables logging to this vty\n")
72{
73 struct telnet_connection *conn;
74
75 conn = (struct telnet_connection *) vty->priv;
76 if (conn->dbg) {
77 vty_out(vty, "Logging already enabled.%s", VTY_NEWLINE);
78 return CMD_WARNING;
79 }
80
81 conn->dbg = log_target_create_vty(vty);
82 if (!conn->dbg)
83 return CMD_WARNING;
84
85 log_add_target(conn->dbg);
86 return CMD_SUCCESS;
87}
88
Harald Weltea62648b2011-02-18 21:03:27 +010089struct log_target *osmo_log_vty2tgt(struct vty *vty)
90{
91 struct telnet_connection *conn;
92
93 if (vty->node == CFG_LOG_NODE)
94 return vty->index;
95
96
97 conn = (struct telnet_connection *) vty->priv;
98 if (!conn->dbg)
99 vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE);
100
101 return conn->dbg;
102}
103
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200104DEFUN(logging_fltr_all,
105 logging_fltr_all_cmd,
106 "logging filter all (0|1)",
107 LOGGING_STR FILTER_STR
108 "Do you want to log all messages?\n"
109 "Only print messages matched by other filters\n"
110 "Bypass filter and print all messages\n")
111{
Harald Weltea62648b2011-02-18 21:03:27 +0100112 struct log_target *tgt = osmo_log_vty2tgt(vty);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200113
Harald Weltea62648b2011-02-18 21:03:27 +0100114 if (!tgt)
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200115 return CMD_WARNING;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200116
Harald Weltea62648b2011-02-18 21:03:27 +0100117 log_set_all_filter(tgt, atoi(argv[0]));
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200118 return CMD_SUCCESS;
119}
120
121DEFUN(logging_use_clr,
122 logging_use_clr_cmd,
123 "logging color (0|1)",
124 LOGGING_STR "Configure color-printing for log messages\n"
125 "Don't use color for printing messages\n"
126 "Use color for printing messages\n")
127{
Harald Weltea62648b2011-02-18 21:03:27 +0100128 struct log_target *tgt = osmo_log_vty2tgt(vty);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200129
Harald Weltea62648b2011-02-18 21:03:27 +0100130 if (!tgt)
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200131 return CMD_WARNING;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200132
Harald Weltea62648b2011-02-18 21:03:27 +0100133 log_set_use_color(tgt, atoi(argv[0]));
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200134 return CMD_SUCCESS;
135}
136
137DEFUN(logging_prnt_timestamp,
138 logging_prnt_timestamp_cmd,
139 "logging timestamp (0|1)",
140 LOGGING_STR "Configure log message timestamping\n"
141 "Don't prefix each log message\n"
142 "Prefix each log message with current timestamp\n")
143{
Harald Weltea62648b2011-02-18 21:03:27 +0100144 struct log_target *tgt = osmo_log_vty2tgt(vty);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200145
Harald Weltea62648b2011-02-18 21:03:27 +0100146 if (!tgt)
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200147 return CMD_WARNING;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200148
Harald Weltea62648b2011-02-18 21:03:27 +0100149 log_set_print_timestamp(tgt, atoi(argv[0]));
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200150 return CMD_SUCCESS;
151}
152
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100153DEFUN(logging_prnt_ext_timestamp,
154 logging_prnt_ext_timestamp_cmd,
155 "logging print extended-timestamp (0|1)",
156 LOGGING_STR "Log output settings\n"
157 "Configure log message timestamping\n"
158 "Don't prefix each log message\n"
159 "Prefix each log message with current timestamp with YYYYMMDDhhmmssnnn\n")
160{
161 struct log_target *tgt = osmo_log_vty2tgt(vty);
162
163 if (!tgt)
164 return CMD_WARNING;
165
166 log_set_print_extended_timestamp(tgt, atoi(argv[0]));
167 return CMD_SUCCESS;
168}
169
170DEFUN(logging_prnt_cat,
171 logging_prnt_cat_cmd,
172 "logging print category (0|1)",
173 LOGGING_STR "Log output settings\n"
174 "Configure log message\n"
175 "Don't prefix each log message\n"
176 "Prefix each log message with category/subsystem name\n")
177{
178 struct log_target *tgt = osmo_log_vty2tgt(vty);
179
180 if (!tgt)
181 return CMD_WARNING;
182
183 log_set_print_category(tgt, atoi(argv[0]));
184 return CMD_SUCCESS;
185}
186
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200187DEFUN(logging_level,
188 logging_level_cmd,
Pablo Neira Ayuso04139f12011-03-09 13:05:08 +0100189 NULL, /* cmdstr is dynamically set in logging_vty_add_cmds(). */
190 NULL) /* same thing for helpstr. */
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200191{
Harald Weltea62648b2011-02-18 21:03:27 +0100192 int category = log_parse_category(argv[0]);
193 int level = log_parse_level(argv[1]);
194 struct log_target *tgt = osmo_log_vty2tgt(vty);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200195
Harald Weltea62648b2011-02-18 21:03:27 +0100196 if (!tgt)
197 return CMD_WARNING;
198
199 if (level < 0) {
200 vty_out(vty, "Invalid level `%s'%s", argv[1], VTY_NEWLINE);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200201 return CMD_WARNING;
202 }
203
Harald Weltea62648b2011-02-18 21:03:27 +0100204 /* Check for special case where we want to set global log level */
205 if (!strcmp(argv[0], "all")) {
206 log_set_log_level(tgt, level);
207 return CMD_SUCCESS;
208 }
209
210 if (category < 0) {
211 vty_out(vty, "Invalid category `%s'%s", argv[0], VTY_NEWLINE);
212 return CMD_WARNING;
213 }
214
215 tgt->categories[category].enabled = 1;
216 tgt->categories[category].loglevel = level;
217
218 return CMD_SUCCESS;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200219}
220
221DEFUN(logging_set_category_mask,
222 logging_set_category_mask_cmd,
Holger Hans Peter Freyther146d1d32011-10-03 23:15:41 +0200223 "logging set-log-mask MASK",
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200224 LOGGING_STR
Holger Hans Peter Freyther146d1d32011-10-03 23:15:41 +0200225 "Set the logmask of this logging target\n"
226 "The logmask to use\n")
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200227{
Harald Weltea62648b2011-02-18 21:03:27 +0100228 struct log_target *tgt = osmo_log_vty2tgt(vty);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200229
Harald Weltea62648b2011-02-18 21:03:27 +0100230 if (!tgt)
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200231 return CMD_WARNING;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200232
Harald Weltea62648b2011-02-18 21:03:27 +0100233 log_parse_category_mask(tgt, argv[0]);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200234 return CMD_SUCCESS;
235}
236
Holger Hans Peter Freyther146d1d32011-10-03 23:15:41 +0200237ALIAS_DEPRECATED(logging_set_category_mask,
238 logging_set_category_mask_old_cmd,
239 "logging set log mask MASK",
240 LOGGING_STR
241 "Decide which categories to output.\n"
242 "Log commands\n" "Mask commands\n" "The logmask to use\n");
243
244
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200245DEFUN(diable_logging,
246 disable_logging_cmd,
247 "logging disable",
248 LOGGING_STR
249 "Disables logging to this vty\n")
250{
Harald Weltea62648b2011-02-18 21:03:27 +0100251 struct log_target *tgt = osmo_log_vty2tgt(vty);
252 struct telnet_connection *conn = (struct telnet_connection *) vty->priv;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200253
Harald Weltea62648b2011-02-18 21:03:27 +0100254 if (!tgt)
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200255 return CMD_WARNING;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200256
Harald Weltea62648b2011-02-18 21:03:27 +0100257 log_del_target(tgt);
258 talloc_free(tgt);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200259 conn->dbg = NULL;
Harald Weltea62648b2011-02-18 21:03:27 +0100260
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200261 return CMD_SUCCESS;
262}
263
264static void vty_print_logtarget(struct vty *vty, const struct log_info *info,
265 const struct log_target *tgt)
266{
267 unsigned int i;
268
269 vty_out(vty, " Global Loglevel: %s%s",
270 log_level_str(tgt->loglevel), VTY_NEWLINE);
271 vty_out(vty, " Use color: %s, Print Timestamp: %s%s",
272 tgt->use_color ? "On" : "Off",
273 tgt->print_timestamp ? "On" : "Off", VTY_NEWLINE);
274
275 vty_out(vty, " Log Level specific information:%s", VTY_NEWLINE);
276
277 for (i = 0; i < info->num_cat; i++) {
278 const struct log_category *cat = &tgt->categories[i];
Daniel Willmann55363a92016-11-15 10:05:51 +0100279 /* Skip categories that were not initialized */
280 if (!info->cat[i].name)
281 continue;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200282 vty_out(vty, " %-10s %-10s %-8s %s%s",
283 info->cat[i].name+1, log_level_str(cat->loglevel),
284 cat->enabled ? "Enabled" : "Disabled",
285 info->cat[i].description,
286 VTY_NEWLINE);
287 }
Harald Welte6d2d4d62013-03-10 09:53:24 +0000288
289 vty_out(vty, " Log Filter 'ALL': %s%s",
290 tgt->filter_map & LOG_FILTER_ALL ? "Enabled" : "Disabled",
291 VTY_NEWLINE);
292
Harald Weltefb84f322013-06-06 07:33:54 +0200293 /* print application specific filters */
294 if (info->print_fn)
295 info->print_fn(vty, info, tgt);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200296}
297
298#define SHOW_LOG_STR "Show current logging configuration\n"
299
300DEFUN(show_logging_vty,
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000301 show_logging_vty_cmd,
302 "show logging vty",
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200303 SHOW_STR SHOW_LOG_STR
304 "Show current logging configuration for this vty\n")
305{
Harald Weltea62648b2011-02-18 21:03:27 +0100306 struct log_target *tgt = osmo_log_vty2tgt(vty);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200307
Harald Weltea62648b2011-02-18 21:03:27 +0100308 if (!tgt)
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200309 return CMD_WARNING;
Harald Weltea62648b2011-02-18 21:03:27 +0100310
311 vty_print_logtarget(vty, osmo_log_info, tgt);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200312
313 return CMD_SUCCESS;
314}
315
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000316DEFUN(show_alarms,
317 show_alarms_cmd,
318 "show alarms",
319 SHOW_STR SHOW_LOG_STR
320 "Show the contents of the logging ringbuffer\n")
321{
322 int i, num_alarms;
323 struct osmo_strrb *rb;
324 struct log_target *tgt = log_target_find(LOG_TGT_TYPE_STRRB, NULL);
325 if (!tgt) {
326 vty_out(vty, "%% No alarms, run 'log alarms <2-32700>'%s",
327 VTY_NEWLINE);
328 return CMD_WARNING;
329 }
330
331 rb = tgt->tgt_rb.rb;
332 num_alarms = osmo_strrb_elements(rb);
333
334 vty_out(vty, "%% Showing %i alarms%s", num_alarms, VTY_NEWLINE);
335
336 for (i = 0; i < num_alarms; i++)
337 vty_out(vty, "%% %s%s", osmo_strrb_get_nth(rb, i),
338 VTY_NEWLINE);
339
340 return CMD_SUCCESS;
341}
342
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200343gDEFUN(cfg_description, cfg_description_cmd,
344 "description .TEXT",
Holger Hans Peter Freytherc9b3e062012-07-25 13:02:49 +0200345 "Save human-readable decription of the object\n"
346 "Text until the end of the line\n")
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200347{
348 char **dptr = vty->index_sub;
349
350 if (!dptr) {
351 vty_out(vty, "vty->index_sub == NULL%s", VTY_NEWLINE);
352 return CMD_WARNING;
353 }
354
Holger Hans Peter Freytherff0670e2011-02-24 14:20:41 +0100355 if (*dptr)
356 talloc_free(*dptr);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200357 *dptr = argv_concat(argv, argc, 0);
Holger Hans Peter Freyther6a75d162013-07-14 09:07:11 +0200358 if (!*dptr)
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200359 return CMD_WARNING;
360
361 return CMD_SUCCESS;
362}
363
364gDEFUN(cfg_no_description, cfg_no_description_cmd,
365 "no description",
366 NO_STR
367 "Remove description of the object\n")
368{
369 char **dptr = vty->index_sub;
370
371 if (!dptr) {
372 vty_out(vty, "vty->index_sub == NULL%s", VTY_NEWLINE);
373 return CMD_WARNING;
374 }
375
376 if (*dptr) {
377 talloc_free(*dptr);
378 *dptr = NULL;
379 }
380
381 return CMD_SUCCESS;
382}
383
Harald Welte28222962011-02-18 20:37:04 +0100384/* Support for configuration of log targets != the current vty */
385
386struct cmd_node cfg_log_node = {
387 CFG_LOG_NODE,
388 "%s(config-log)# ",
389 1
390};
391
Harald Welte28222962011-02-18 20:37:04 +0100392#ifdef HAVE_SYSLOG_H
393
394#include <syslog.h>
395
396static const int local_sysl_map[] = {
397 [0] = LOG_LOCAL0,
398 [1] = LOG_LOCAL1,
399 [2] = LOG_LOCAL2,
400 [3] = LOG_LOCAL3,
401 [4] = LOG_LOCAL4,
402 [5] = LOG_LOCAL5,
403 [6] = LOG_LOCAL6,
404 [7] = LOG_LOCAL7
405};
406
Harald Weltede79cee2011-02-24 23:47:57 +0100407/* From VTY core code */
408extern struct host host;
409
Harald Welte28222962011-02-18 20:37:04 +0100410static int _cfg_log_syslog(struct vty *vty, int facility)
411{
412 struct log_target *tgt;
413
414 /* First delete the old syslog target, if any */
415 tgt = log_target_find(LOG_TGT_TYPE_SYSLOG, NULL);
416 if (tgt)
417 log_target_destroy(tgt);
418
Harald Weltede79cee2011-02-24 23:47:57 +0100419 tgt = log_target_create_syslog(host.app_info->name, 0, facility);
Harald Welte28222962011-02-18 20:37:04 +0100420 if (!tgt) {
421 vty_out(vty, "%% Unable to open syslog%s", VTY_NEWLINE);
422 return CMD_WARNING;
423 }
424 log_add_target(tgt);
425
426 vty->index = tgt;
427 vty->node = CFG_LOG_NODE;
428
429 return CMD_SUCCESS;
430}
431
432DEFUN(cfg_log_syslog_local, cfg_log_syslog_local_cmd,
433 "log syslog local <0-7>",
434 LOG_STR "Logging via syslog\n" "Syslog LOCAL facility\n"
435 "Local facility number\n")
436{
437 int local = atoi(argv[0]);
438 int facility = local_sysl_map[local];
439
440 return _cfg_log_syslog(vty, facility);
441}
442
443static struct value_string sysl_level_names[] = {
444 { LOG_AUTHPRIV, "authpriv" },
445 { LOG_CRON, "cron" },
446 { LOG_DAEMON, "daemon" },
447 { LOG_FTP, "ftp" },
448 { LOG_LPR, "lpr" },
449 { LOG_MAIL, "mail" },
450 { LOG_NEWS, "news" },
451 { LOG_USER, "user" },
452 { LOG_UUCP, "uucp" },
453 /* only for value -> string conversion */
454 { LOG_LOCAL0, "local 0" },
455 { LOG_LOCAL1, "local 1" },
456 { LOG_LOCAL2, "local 2" },
457 { LOG_LOCAL3, "local 3" },
458 { LOG_LOCAL4, "local 4" },
459 { LOG_LOCAL5, "local 5" },
460 { LOG_LOCAL6, "local 6" },
461 { LOG_LOCAL7, "local 7" },
462 { 0, NULL }
463};
464
465DEFUN(cfg_log_syslog, cfg_log_syslog_cmd,
466 "log syslog (authpriv|cron|daemon|ftp|lpr|mail|news|user|uucp)",
Holger Hans Peter Freythera4463fd2011-10-03 23:17:36 +0200467 LOG_STR "Logging via syslog\n"
468 "Security/authorization messages facility\n"
469 "Clock daemon (cron/at) facility\n"
470 "General system daemon facility\n"
471 "Ftp daemon facility\n"
472 "Line printer facility\n"
473 "Mail facility\n"
474 "News facility\n"
475 "Generic facility\n"
476 "UUCP facility\n")
Harald Welte28222962011-02-18 20:37:04 +0100477{
478 int facility = get_string_value(sysl_level_names, argv[0]);
479
480 return _cfg_log_syslog(vty, facility);
481}
482
483DEFUN(cfg_no_log_syslog, cfg_no_log_syslog_cmd,
484 "no log syslog",
485 NO_STR LOG_STR "Logging via syslog\n")
486{
487 struct log_target *tgt;
488
489 tgt = log_target_find(LOG_TGT_TYPE_SYSLOG, NULL);
490 if (!tgt) {
491 vty_out(vty, "%% No syslog target found%s",
492 VTY_NEWLINE);
493 return CMD_WARNING;
494 }
495
496 log_target_destroy(tgt);
497
498 return CMD_SUCCESS;
499}
500#endif /* HAVE_SYSLOG_H */
501
Harald Welteaa00f992016-12-02 15:30:02 +0100502DEFUN(cfg_log_gsmtap, cfg_log_gsmtap_cmd,
503 "log gsmtap [HOSTNAME]",
Neels Hofmeyrfd9ec3b2016-12-11 01:48:26 +0100504 LOG_STR "Logging via GSMTAP\n"
505 "Host name to send the GSMTAP logging to (UDP port 4729)\n")
Harald Welteaa00f992016-12-02 15:30:02 +0100506{
507 const char *hostname = argv[0];
508 struct log_target *tgt;
509
510 tgt = log_target_find(LOG_TGT_TYPE_GSMTAP, hostname);
511 if (!tgt) {
512 tgt = log_target_create_gsmtap(hostname, GSMTAP_UDP_PORT,
513 host.app_info->name, false,
514 true);
515 if (!tgt) {
516 vty_out(vty, "%% Unable to create GSMTAP log%s",
517 VTY_NEWLINE);
518 return CMD_WARNING;
519 }
520 log_add_target(tgt);
521 }
522
523 vty->index = tgt;
524 vty->node = CFG_LOG_NODE;
525
526 return CMD_SUCCESS;
527}
528
Harald Welte28222962011-02-18 20:37:04 +0100529DEFUN(cfg_log_stderr, cfg_log_stderr_cmd,
530 "log stderr",
531 LOG_STR "Logging via STDERR of the process\n")
532{
533 struct log_target *tgt;
534
535 tgt = log_target_find(LOG_TGT_TYPE_STDERR, NULL);
536 if (!tgt) {
537 tgt = log_target_create_stderr();
538 if (!tgt) {
539 vty_out(vty, "%% Unable to create stderr log%s",
540 VTY_NEWLINE);
541 return CMD_WARNING;
542 }
543 log_add_target(tgt);
544 }
545
546 vty->index = tgt;
547 vty->node = CFG_LOG_NODE;
548
549 return CMD_SUCCESS;
550}
551
552DEFUN(cfg_no_log_stderr, cfg_no_log_stderr_cmd,
553 "no log stderr",
554 NO_STR LOG_STR "Logging via STDERR of the process\n")
555{
556 struct log_target *tgt;
557
558 tgt = log_target_find(LOG_TGT_TYPE_STDERR, NULL);
559 if (!tgt) {
560 vty_out(vty, "%% No stderr logging active%s", VTY_NEWLINE);
561 return CMD_WARNING;
562 }
563
564 log_target_destroy(tgt);
565
566 return CMD_SUCCESS;
567}
568
569DEFUN(cfg_log_file, cfg_log_file_cmd,
570 "log file .FILENAME",
571 LOG_STR "Logging to text file\n" "Filename\n")
572{
573 const char *fname = argv[0];
574 struct log_target *tgt;
575
576 tgt = log_target_find(LOG_TGT_TYPE_FILE, fname);
577 if (!tgt) {
578 tgt = log_target_create_file(fname);
579 if (!tgt) {
580 vty_out(vty, "%% Unable to create file `%s'%s",
581 fname, VTY_NEWLINE);
582 return CMD_WARNING;
583 }
584 log_add_target(tgt);
585 }
586
587 vty->index = tgt;
588 vty->node = CFG_LOG_NODE;
589
590 return CMD_SUCCESS;
591}
592
593
594DEFUN(cfg_no_log_file, cfg_no_log_file_cmd,
595 "no log file .FILENAME",
596 NO_STR LOG_STR "Logging to text file\n" "Filename\n")
597{
598 const char *fname = argv[0];
599 struct log_target *tgt;
600
601 tgt = log_target_find(LOG_TGT_TYPE_FILE, fname);
602 if (!tgt) {
603 vty_out(vty, "%% No such log file `%s'%s",
604 fname, VTY_NEWLINE);
605 return CMD_WARNING;
606 }
607
608 log_target_destroy(tgt);
609
610 return CMD_SUCCESS;
611}
612
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000613DEFUN(cfg_log_alarms, cfg_log_alarms_cmd,
614 "log alarms <2-32700>",
615 LOG_STR "Logging alarms to osmo_strrb\n"
616 "Maximum number of messages to log\n")
617{
618 struct log_target *tgt;
619 unsigned int rbsize = atoi(argv[0]);
620
621 tgt = log_target_find(LOG_TGT_TYPE_STRRB, NULL);
622 if (tgt)
623 log_target_destroy(tgt);
624
625 tgt = log_target_create_rb(rbsize);
626 if (!tgt) {
627 vty_out(vty, "%% Unable to create osmo_strrb (size %u)%s",
628 rbsize, VTY_NEWLINE);
629 return CMD_WARNING;
630 }
631 log_add_target(tgt);
632
633 vty->index = tgt;
634 vty->node = CFG_LOG_NODE;
635
636 return CMD_SUCCESS;
637}
638
639DEFUN(cfg_no_log_alarms, cfg_no_log_alarms_cmd,
640 "no log alarms",
641 NO_STR LOG_STR "Logging alarms to osmo_strrb\n")
642{
643 struct log_target *tgt;
644
645 tgt = log_target_find(LOG_TGT_TYPE_STRRB, NULL);
646 if (!tgt) {
647 vty_out(vty, "%% No osmo_strrb target found%s", VTY_NEWLINE);
648 return CMD_WARNING;
649 }
650
651 log_target_destroy(tgt);
652
653 return CMD_SUCCESS;
654}
655
Harald Welte28222962011-02-18 20:37:04 +0100656static int config_write_log_single(struct vty *vty, struct log_target *tgt)
657{
658 int i;
659 char level_lower[32];
660
661 switch (tgt->type) {
662 case LOG_TGT_TYPE_VTY:
663 return 1;
664 break;
665 case LOG_TGT_TYPE_STDERR:
666 vty_out(vty, "log stderr%s", VTY_NEWLINE);
667 break;
668 case LOG_TGT_TYPE_SYSLOG:
669#ifdef HAVE_SYSLOG_H
670 vty_out(vty, "log syslog %s%s",
671 get_value_string(sysl_level_names,
672 tgt->tgt_syslog.facility),
673 VTY_NEWLINE);
674#endif
675 break;
676 case LOG_TGT_TYPE_FILE:
677 vty_out(vty, "log file %s%s", tgt->tgt_file.fname, VTY_NEWLINE);
678 break;
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000679 case LOG_TGT_TYPE_STRRB:
680 vty_out(vty, "log alarms %zu%s",
681 log_target_rb_avail_size(tgt), VTY_NEWLINE);
682 break;
Harald Welteaa00f992016-12-02 15:30:02 +0100683 case LOG_TGT_TYPE_GSMTAP:
684 vty_out(vty, "log gsmtap %s%s",
685 tgt->tgt_gsmtap.hostname, VTY_NEWLINE);
686 break;
Harald Welte28222962011-02-18 20:37:04 +0100687 }
688
Harald Welte2da47f12012-10-22 19:31:54 +0200689 vty_out(vty, " logging filter all %u%s",
690 tgt->filter_map & LOG_FILTER_ALL ? 1 : 0, VTY_NEWLINE);
Harald Weltefb84f322013-06-06 07:33:54 +0200691 /* save filters outside of libosmocore, i.e. in app code */
692 if (osmo_log_info->save_fn)
693 osmo_log_info->save_fn(vty, osmo_log_info, tgt);
Harald Welte2da47f12012-10-22 19:31:54 +0200694
Harald Welte28222962011-02-18 20:37:04 +0100695 vty_out(vty, " logging color %u%s", tgt->use_color ? 1 : 0,
696 VTY_NEWLINE);
Holger Hans Peter Freyther879acef2015-01-27 11:06:51 +0100697 vty_out(vty, " logging print category %d%s",
Michael McTernan78933462015-03-20 15:29:25 +0100698 tgt->print_category ? 1 : 0, VTY_NEWLINE);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100699 if (tgt->print_ext_timestamp)
700 vty_out(vty, " logging print extended-timestamp 1%s", VTY_NEWLINE);
701 else
702 vty_out(vty, " logging timestamp %u%s",
703 tgt->print_timestamp ? 1 : 0, VTY_NEWLINE);
Harald Welte28222962011-02-18 20:37:04 +0100704
705 /* stupid old osmo logging API uses uppercase strings... */
706 osmo_str2lower(level_lower, log_level_str(tgt->loglevel));
707 vty_out(vty, " logging level all %s%s", level_lower, VTY_NEWLINE);
708
709 for (i = 0; i < osmo_log_info->num_cat; i++) {
710 const struct log_category *cat = &tgt->categories[i];
711 char cat_lower[32];
712
Harald Welte1a02cfc2013-03-19 10:37:39 +0100713 /* skip empty entries in the array */
714 if (!osmo_log_info->cat[i].name)
715 continue;
716
Harald Welte28222962011-02-18 20:37:04 +0100717 /* stupid old osmo logging API uses uppercase strings... */
718 osmo_str2lower(cat_lower, osmo_log_info->cat[i].name+1);
719 osmo_str2lower(level_lower, log_level_str(cat->loglevel));
720
721 vty_out(vty, " logging level %s %s%s", cat_lower, level_lower,
722 VTY_NEWLINE);
723 }
724
725 /* FIXME: levels */
726
727 return 1;
728}
729
730static int config_write_log(struct vty *vty)
731{
732 struct log_target *dbg = vty->index;
733
734 llist_for_each_entry(dbg, &osmo_log_target_list, entry)
735 config_write_log_single(vty, dbg);
736
737 return 1;
738}
739
Pablo Neira Ayuso04139f12011-03-09 13:05:08 +0100740void logging_vty_add_cmds(const struct log_info *cat)
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200741{
742 install_element_ve(&enable_logging_cmd);
743 install_element_ve(&disable_logging_cmd);
744 install_element_ve(&logging_fltr_all_cmd);
745 install_element_ve(&logging_use_clr_cmd);
746 install_element_ve(&logging_prnt_timestamp_cmd);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100747 install_element_ve(&logging_prnt_ext_timestamp_cmd);
748 install_element_ve(&logging_prnt_cat_cmd);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200749 install_element_ve(&logging_set_category_mask_cmd);
Holger Hans Peter Freyther146d1d32011-10-03 23:15:41 +0200750 install_element_ve(&logging_set_category_mask_old_cmd);
Pablo Neira Ayuso04139f12011-03-09 13:05:08 +0100751
752 /* Logging level strings are generated dynamically. */
753 logging_level_cmd.string = log_vty_command_string(cat);
754 logging_level_cmd.doc = log_vty_command_description(cat);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200755 install_element_ve(&logging_level_cmd);
756 install_element_ve(&show_logging_vty_cmd);
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000757 install_element_ve(&show_alarms_cmd);
Harald Welte28222962011-02-18 20:37:04 +0100758
759 install_node(&cfg_log_node, config_write_log);
Jacob Erlbeck0c987bd2013-09-06 16:52:00 +0200760 vty_install_default(CFG_LOG_NODE);
Harald Weltea62648b2011-02-18 21:03:27 +0100761 install_element(CFG_LOG_NODE, &logging_fltr_all_cmd);
762 install_element(CFG_LOG_NODE, &logging_use_clr_cmd);
763 install_element(CFG_LOG_NODE, &logging_prnt_timestamp_cmd);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100764 install_element(CFG_LOG_NODE, &logging_prnt_ext_timestamp_cmd);
765 install_element(CFG_LOG_NODE, &logging_prnt_cat_cmd);
Harald Weltea62648b2011-02-18 21:03:27 +0100766 install_element(CFG_LOG_NODE, &logging_level_cmd);
Harald Welte28222962011-02-18 20:37:04 +0100767
768 install_element(CONFIG_NODE, &cfg_log_stderr_cmd);
769 install_element(CONFIG_NODE, &cfg_no_log_stderr_cmd);
770 install_element(CONFIG_NODE, &cfg_log_file_cmd);
771 install_element(CONFIG_NODE, &cfg_no_log_file_cmd);
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000772 install_element(CONFIG_NODE, &cfg_log_alarms_cmd);
773 install_element(CONFIG_NODE, &cfg_no_log_alarms_cmd);
Harald Welte28222962011-02-18 20:37:04 +0100774#ifdef HAVE_SYSLOG_H
775 install_element(CONFIG_NODE, &cfg_log_syslog_cmd);
776 install_element(CONFIG_NODE, &cfg_log_syslog_local_cmd);
777 install_element(CONFIG_NODE, &cfg_no_log_syslog_cmd);
778#endif
Harald Welteaa00f992016-12-02 15:30:02 +0100779 install_element(CONFIG_NODE, &cfg_log_gsmtap_cmd);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200780}