blob: 8151fda0a8a7a10c9ca0cf811bbb940fb590ff5a [file] [log] [blame]
Neels Hofmeyr17518fe2017-06-20 04:35:06 +02001/*
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 *
Harald Weltee08da972017-11-13 01:00:26 +09006 * SPDX-License-Identifier: GPL-2.0+
7 *
Harald Welte3fb0b6f2010-05-19 19:02:52 +02008 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 */
23
24#include <stdlib.h>
25#include <string.h>
26
Harald Welte28222962011-02-18 20:37:04 +010027#include "../../config.h"
28
Pablo Neira Ayuso83419342011-03-22 16:36:13 +010029#include <osmocom/core/talloc.h>
30#include <osmocom/core/logging.h>
31#include <osmocom/core/utils.h>
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +000032#include <osmocom/core/strrb.h>
33#include <osmocom/core/loggingrb.h>
Harald Welteaa00f992016-12-02 15:30:02 +010034#include <osmocom/core/gsmtap.h>
Harald Welte3fb0b6f2010-05-19 19:02:52 +020035
36#include <osmocom/vty/command.h>
37#include <osmocom/vty/buffer.h>
38#include <osmocom/vty/vty.h>
39#include <osmocom/vty/telnet_interface.h>
40#include <osmocom/vty/logging.h>
41
Harald Welte28222962011-02-18 20:37:04 +010042#define LOG_STR "Configure logging sub-system\n"
43
Harald Welte8c648252017-10-16 15:17:03 +020044/*! \file logging_vty.c
Neels Hofmeyr87e45502017-06-20 00:17:59 +020045 * Configuration of logging from VTY
Harald Welte96e2a002017-06-12 21:44:18 +020046 *
Harald Welte8c648252017-10-16 15:17:03 +020047 * This module implements
48 * - functions that permit configuration of the libosmocore logging
49 * framework from VTY commands in the configure -> logging node.
50 *
51 * - functions that permit logging *to* a VTY session. Basically each
52 * VTY session gets its own log target, with configurable
53 * per-subsystem log levels. This is performed internally via the
54 * \ref log_target_create_vty function.
55 *
56 * You have to call \ref logging_vty_add_cmds from your application
57 * once to enable both of the above.
58 *
Harald Welte96e2a002017-06-12 21:44:18 +020059 */
60
Harald Welte4ebdf742010-05-19 19:54:00 +020061extern const struct log_info *osmo_log_info;
Harald Welte3fb0b6f2010-05-19 19:02:52 +020062
Harald Welte76e72ab2011-02-17 15:52:39 +010063static void _vty_output(struct log_target *tgt,
64 unsigned int level, const char *line)
Harald Welte3fb0b6f2010-05-19 19:02:52 +020065{
66 struct vty *vty = tgt->tgt_vty.vty;
67 vty_out(vty, "%s", line);
68 /* This is an ugly hack, but there is no easy way... */
69 if (strchr(line, '\n'))
70 vty_out(vty, "\r");
71}
72
73struct log_target *log_target_create_vty(struct vty *vty)
74{
75 struct log_target *target;
76
77 target = log_target_create();
78 if (!target)
79 return NULL;
80
81 target->tgt_vty.vty = vty;
82 target->output = _vty_output;
83 return target;
84}
85
86DEFUN(enable_logging,
87 enable_logging_cmd,
88 "logging enable",
89 LOGGING_STR
90 "Enables logging to this vty\n")
91{
92 struct telnet_connection *conn;
93
94 conn = (struct telnet_connection *) vty->priv;
95 if (conn->dbg) {
96 vty_out(vty, "Logging already enabled.%s", VTY_NEWLINE);
97 return CMD_WARNING;
98 }
99
100 conn->dbg = log_target_create_vty(vty);
101 if (!conn->dbg)
102 return CMD_WARNING;
103
104 log_add_target(conn->dbg);
105 return CMD_SUCCESS;
106}
107
Harald Weltea62648b2011-02-18 21:03:27 +0100108struct log_target *osmo_log_vty2tgt(struct vty *vty)
109{
110 struct telnet_connection *conn;
111
112 if (vty->node == CFG_LOG_NODE)
113 return vty->index;
114
115
116 conn = (struct telnet_connection *) vty->priv;
117 if (!conn->dbg)
118 vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE);
119
120 return conn->dbg;
121}
122
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200123DEFUN(logging_fltr_all,
124 logging_fltr_all_cmd,
125 "logging filter all (0|1)",
126 LOGGING_STR FILTER_STR
127 "Do you want to log all messages?\n"
128 "Only print messages matched by other filters\n"
129 "Bypass filter and print all messages\n")
130{
Harald Weltea62648b2011-02-18 21:03:27 +0100131 struct log_target *tgt = osmo_log_vty2tgt(vty);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200132
Harald Weltea62648b2011-02-18 21:03:27 +0100133 if (!tgt)
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200134 return CMD_WARNING;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200135
Harald Weltea62648b2011-02-18 21:03:27 +0100136 log_set_all_filter(tgt, atoi(argv[0]));
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200137 return CMD_SUCCESS;
138}
139
140DEFUN(logging_use_clr,
141 logging_use_clr_cmd,
142 "logging color (0|1)",
143 LOGGING_STR "Configure color-printing for log messages\n"
144 "Don't use color for printing messages\n"
145 "Use color for printing messages\n")
146{
Harald Weltea62648b2011-02-18 21:03:27 +0100147 struct log_target *tgt = osmo_log_vty2tgt(vty);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200148
Harald Weltea62648b2011-02-18 21:03:27 +0100149 if (!tgt)
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200150 return CMD_WARNING;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200151
Harald Weltea62648b2011-02-18 21:03:27 +0100152 log_set_use_color(tgt, atoi(argv[0]));
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200153 return CMD_SUCCESS;
154}
155
156DEFUN(logging_prnt_timestamp,
157 logging_prnt_timestamp_cmd,
158 "logging timestamp (0|1)",
159 LOGGING_STR "Configure log message timestamping\n"
160 "Don't prefix each log message\n"
161 "Prefix each log message with current timestamp\n")
162{
Harald Weltea62648b2011-02-18 21:03:27 +0100163 struct log_target *tgt = osmo_log_vty2tgt(vty);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200164
Harald Weltea62648b2011-02-18 21:03:27 +0100165 if (!tgt)
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200166 return CMD_WARNING;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200167
Harald Weltea62648b2011-02-18 21:03:27 +0100168 log_set_print_timestamp(tgt, atoi(argv[0]));
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200169 return CMD_SUCCESS;
170}
171
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100172DEFUN(logging_prnt_ext_timestamp,
173 logging_prnt_ext_timestamp_cmd,
174 "logging print extended-timestamp (0|1)",
175 LOGGING_STR "Log output settings\n"
176 "Configure log message timestamping\n"
177 "Don't prefix each log message\n"
178 "Prefix each log message with current timestamp with YYYYMMDDhhmmssnnn\n")
179{
180 struct log_target *tgt = osmo_log_vty2tgt(vty);
181
182 if (!tgt)
183 return CMD_WARNING;
184
185 log_set_print_extended_timestamp(tgt, atoi(argv[0]));
186 return CMD_SUCCESS;
187}
188
189DEFUN(logging_prnt_cat,
190 logging_prnt_cat_cmd,
191 "logging print category (0|1)",
192 LOGGING_STR "Log output settings\n"
193 "Configure log message\n"
194 "Don't prefix each log message\n"
195 "Prefix each log message with category/subsystem name\n")
196{
197 struct log_target *tgt = osmo_log_vty2tgt(vty);
198
199 if (!tgt)
200 return CMD_WARNING;
201
202 log_set_print_category(tgt, atoi(argv[0]));
203 return CMD_SUCCESS;
204}
205
Neels Hofmeyrbd7bd392018-01-16 01:52:29 +0100206DEFUN(logging_prnt_cat_hex,
207 logging_prnt_cat_hex_cmd,
208 "logging print category-hex (0|1)",
209 LOGGING_STR "Log output settings\n"
210 "Configure log message\n"
211 "Don't prefix each log message\n"
212 "Prefix each log message with category/subsystem nr in hex ('<000b>')\n")
213{
214 struct log_target *tgt = osmo_log_vty2tgt(vty);
215
216 if (!tgt)
217 return CMD_WARNING;
218
219 log_set_print_category_hex(tgt, atoi(argv[0]));
220 return CMD_SUCCESS;
221}
222
Neels Hofmeyr886e5482018-01-16 01:49:37 +0100223DEFUN(logging_prnt_level,
224 logging_prnt_level_cmd,
225 "logging print level (0|1)",
226 LOGGING_STR "Log output settings\n"
227 "Configure log message\n"
228 "Don't prefix each log message\n"
229 "Prefix each log message with the log level name\n")
230{
231 struct log_target *tgt = osmo_log_vty2tgt(vty);
232
233 if (!tgt)
234 return CMD_WARNING;
235
236 log_set_print_level(tgt, atoi(argv[0]));
237 return CMD_SUCCESS;
238}
239
Neels Hofmeyr22772cc2018-02-06 00:52:08 +0100240static const struct value_string logging_print_file_args[] = {
241 { LOG_FILENAME_NONE, "0" },
242 { LOG_FILENAME_PATH, "1" },
243 { LOG_FILENAME_BASENAME, "basename" },
244 { 0, NULL }
245};
246
Neels Hofmeyrc6fd2452018-01-16 01:57:38 +0100247DEFUN(logging_prnt_file,
248 logging_prnt_file_cmd,
249 "logging print file (0|1|basename)",
250 LOGGING_STR "Log output settings\n"
251 "Configure log message\n"
252 "Don't prefix each log message\n"
253 "Prefix each log message with the source file and line\n"
254 "Prefix each log message with the source file's basename (strip leading paths) and line\n")
255{
256 struct log_target *tgt = osmo_log_vty2tgt(vty);
Neels Hofmeyrc6fd2452018-01-16 01:57:38 +0100257
258 if (!tgt)
259 return CMD_WARNING;
260
Neels Hofmeyr22772cc2018-02-06 00:52:08 +0100261 log_set_print_filename2(tgt, get_string_value(logging_print_file_args, argv[0]));
Neels Hofmeyrc6fd2452018-01-16 01:57:38 +0100262 return CMD_SUCCESS;
263}
264
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200265DEFUN(logging_level,
266 logging_level_cmd,
Pablo Neira Ayuso04139f12011-03-09 13:05:08 +0100267 NULL, /* cmdstr is dynamically set in logging_vty_add_cmds(). */
268 NULL) /* same thing for helpstr. */
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200269{
Harald Weltea62648b2011-02-18 21:03:27 +0100270 int category = log_parse_category(argv[0]);
271 int level = log_parse_level(argv[1]);
272 struct log_target *tgt = osmo_log_vty2tgt(vty);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200273
Harald Weltea62648b2011-02-18 21:03:27 +0100274 if (!tgt)
275 return CMD_WARNING;
276
277 if (level < 0) {
278 vty_out(vty, "Invalid level `%s'%s", argv[1], VTY_NEWLINE);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200279 return CMD_WARNING;
280 }
281
Maxed0eda22017-07-06 17:09:01 +0200282 if (strcmp(argv[1], "everything") == 0) { /* FIXME: remove this check once 'everything' is phased out */
283 vty_out(vty, "%% Ignoring deprecated logging level %s%s", argv[1], VTY_NEWLINE);
284 return CMD_SUCCESS;
285 }
286
Harald Weltea62648b2011-02-18 21:03:27 +0100287 /* Check for special case where we want to set global log level */
288 if (!strcmp(argv[0], "all")) {
289 log_set_log_level(tgt, level);
290 return CMD_SUCCESS;
291 }
292
293 if (category < 0) {
294 vty_out(vty, "Invalid category `%s'%s", argv[0], VTY_NEWLINE);
295 return CMD_WARNING;
296 }
297
298 tgt->categories[category].enabled = 1;
299 tgt->categories[category].loglevel = level;
300
301 return CMD_SUCCESS;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200302}
303
304DEFUN(logging_set_category_mask,
305 logging_set_category_mask_cmd,
Holger Hans Peter Freyther146d1d32011-10-03 23:15:41 +0200306 "logging set-log-mask MASK",
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200307 LOGGING_STR
Holger Hans Peter Freyther146d1d32011-10-03 23:15:41 +0200308 "Set the logmask of this logging target\n"
Neels Hofmeyr84ea2e02017-12-09 05:53:18 +0100309 "List of logging categories to log, e.g. 'abc:mno:xyz'. Available log categories depend on the specific"
310 " application, refer to the 'logging level' command. Optionally add individual log levels like"
311 " 'abc,1:mno,3:xyz,5', where the level numbers are"
312 " " OSMO_STRINGIFY(LOGL_DEBUG) "=" OSMO_STRINGIFY_VAL(LOGL_DEBUG)
313 " " OSMO_STRINGIFY(LOGL_INFO) "=" OSMO_STRINGIFY_VAL(LOGL_INFO)
314 " " OSMO_STRINGIFY(LOGL_NOTICE) "=" OSMO_STRINGIFY_VAL(LOGL_NOTICE)
315 " " OSMO_STRINGIFY(LOGL_ERROR) "=" OSMO_STRINGIFY_VAL(LOGL_ERROR)
316 " " OSMO_STRINGIFY(LOGL_FATAL) "=" OSMO_STRINGIFY_VAL(LOGL_FATAL)
317 "\n")
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200318{
Harald Weltea62648b2011-02-18 21:03:27 +0100319 struct log_target *tgt = osmo_log_vty2tgt(vty);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200320
Harald Weltea62648b2011-02-18 21:03:27 +0100321 if (!tgt)
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200322 return CMD_WARNING;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200323
Harald Weltea62648b2011-02-18 21:03:27 +0100324 log_parse_category_mask(tgt, argv[0]);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200325 return CMD_SUCCESS;
326}
327
Holger Hans Peter Freyther146d1d32011-10-03 23:15:41 +0200328ALIAS_DEPRECATED(logging_set_category_mask,
329 logging_set_category_mask_old_cmd,
330 "logging set log mask MASK",
331 LOGGING_STR
332 "Decide which categories to output.\n"
Neels Hofmeyr84ea2e02017-12-09 05:53:18 +0100333 "Log commands\n" "Mask commands\n"
334 "'set log mask' is deprecated, please refer to the docs of 'set-log-mask' instead\n");
Holger Hans Peter Freyther146d1d32011-10-03 23:15:41 +0200335
336
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200337DEFUN(diable_logging,
338 disable_logging_cmd,
339 "logging disable",
340 LOGGING_STR
341 "Disables logging to this vty\n")
342{
Harald Weltea62648b2011-02-18 21:03:27 +0100343 struct log_target *tgt = osmo_log_vty2tgt(vty);
344 struct telnet_connection *conn = (struct telnet_connection *) vty->priv;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200345
Harald Weltea62648b2011-02-18 21:03:27 +0100346 if (!tgt)
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200347 return CMD_WARNING;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200348
Harald Weltea62648b2011-02-18 21:03:27 +0100349 log_del_target(tgt);
350 talloc_free(tgt);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200351 conn->dbg = NULL;
Harald Weltea62648b2011-02-18 21:03:27 +0100352
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200353 return CMD_SUCCESS;
354}
355
356static void vty_print_logtarget(struct vty *vty, const struct log_info *info,
357 const struct log_target *tgt)
358{
359 unsigned int i;
360
361 vty_out(vty, " Global Loglevel: %s%s",
362 log_level_str(tgt->loglevel), VTY_NEWLINE);
363 vty_out(vty, " Use color: %s, Print Timestamp: %s%s",
364 tgt->use_color ? "On" : "Off",
365 tgt->print_timestamp ? "On" : "Off", VTY_NEWLINE);
366
367 vty_out(vty, " Log Level specific information:%s", VTY_NEWLINE);
368
369 for (i = 0; i < info->num_cat; i++) {
370 const struct log_category *cat = &tgt->categories[i];
Daniel Willmann55363a92016-11-15 10:05:51 +0100371 /* Skip categories that were not initialized */
372 if (!info->cat[i].name)
373 continue;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200374 vty_out(vty, " %-10s %-10s %-8s %s%s",
375 info->cat[i].name+1, log_level_str(cat->loglevel),
376 cat->enabled ? "Enabled" : "Disabled",
377 info->cat[i].description,
378 VTY_NEWLINE);
379 }
Harald Welte6d2d4d62013-03-10 09:53:24 +0000380
381 vty_out(vty, " Log Filter 'ALL': %s%s",
Neels Hofmeyr8b86cd72017-02-23 18:03:28 +0100382 tgt->filter_map & (1 << LOG_FLT_ALL) ? "Enabled" : "Disabled",
Harald Welte6d2d4d62013-03-10 09:53:24 +0000383 VTY_NEWLINE);
384
Harald Weltefb84f322013-06-06 07:33:54 +0200385 /* print application specific filters */
386 if (info->print_fn)
387 info->print_fn(vty, info, tgt);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200388}
389
390#define SHOW_LOG_STR "Show current logging configuration\n"
391
392DEFUN(show_logging_vty,
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000393 show_logging_vty_cmd,
394 "show logging vty",
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200395 SHOW_STR SHOW_LOG_STR
396 "Show current logging configuration for this vty\n")
397{
Harald Weltea62648b2011-02-18 21:03:27 +0100398 struct log_target *tgt = osmo_log_vty2tgt(vty);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200399
Harald Weltea62648b2011-02-18 21:03:27 +0100400 if (!tgt)
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200401 return CMD_WARNING;
Harald Weltea62648b2011-02-18 21:03:27 +0100402
403 vty_print_logtarget(vty, osmo_log_info, tgt);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200404
405 return CMD_SUCCESS;
406}
407
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000408DEFUN(show_alarms,
409 show_alarms_cmd,
410 "show alarms",
411 SHOW_STR SHOW_LOG_STR
412 "Show the contents of the logging ringbuffer\n")
413{
414 int i, num_alarms;
415 struct osmo_strrb *rb;
416 struct log_target *tgt = log_target_find(LOG_TGT_TYPE_STRRB, NULL);
417 if (!tgt) {
418 vty_out(vty, "%% No alarms, run 'log alarms <2-32700>'%s",
419 VTY_NEWLINE);
420 return CMD_WARNING;
421 }
422
423 rb = tgt->tgt_rb.rb;
424 num_alarms = osmo_strrb_elements(rb);
425
426 vty_out(vty, "%% Showing %i alarms%s", num_alarms, VTY_NEWLINE);
427
428 for (i = 0; i < num_alarms; i++)
429 vty_out(vty, "%% %s%s", osmo_strrb_get_nth(rb, i),
430 VTY_NEWLINE);
431
432 return CMD_SUCCESS;
433}
434
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200435gDEFUN(cfg_description, cfg_description_cmd,
436 "description .TEXT",
Thorsten Alteholza81055d2017-03-02 22:13:48 +0100437 "Save human-readable description of the object\n"
Holger Hans Peter Freytherc9b3e062012-07-25 13:02:49 +0200438 "Text until the end of the line\n")
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200439{
440 char **dptr = vty->index_sub;
441
442 if (!dptr) {
443 vty_out(vty, "vty->index_sub == NULL%s", VTY_NEWLINE);
444 return CMD_WARNING;
445 }
446
Holger Hans Peter Freytherff0670e2011-02-24 14:20:41 +0100447 if (*dptr)
448 talloc_free(*dptr);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200449 *dptr = argv_concat(argv, argc, 0);
Holger Hans Peter Freyther6a75d162013-07-14 09:07:11 +0200450 if (!*dptr)
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200451 return CMD_WARNING;
452
453 return CMD_SUCCESS;
454}
455
456gDEFUN(cfg_no_description, cfg_no_description_cmd,
457 "no description",
458 NO_STR
459 "Remove description of the object\n")
460{
461 char **dptr = vty->index_sub;
462
463 if (!dptr) {
464 vty_out(vty, "vty->index_sub == NULL%s", VTY_NEWLINE);
465 return CMD_WARNING;
466 }
467
468 if (*dptr) {
469 talloc_free(*dptr);
470 *dptr = NULL;
471 }
472
473 return CMD_SUCCESS;
474}
475
Harald Welte28222962011-02-18 20:37:04 +0100476/* Support for configuration of log targets != the current vty */
477
478struct cmd_node cfg_log_node = {
479 CFG_LOG_NODE,
480 "%s(config-log)# ",
481 1
482};
483
Harald Welte28222962011-02-18 20:37:04 +0100484#ifdef HAVE_SYSLOG_H
485
486#include <syslog.h>
487
488static const int local_sysl_map[] = {
489 [0] = LOG_LOCAL0,
490 [1] = LOG_LOCAL1,
491 [2] = LOG_LOCAL2,
492 [3] = LOG_LOCAL3,
493 [4] = LOG_LOCAL4,
494 [5] = LOG_LOCAL5,
495 [6] = LOG_LOCAL6,
496 [7] = LOG_LOCAL7
497};
498
Harald Weltede79cee2011-02-24 23:47:57 +0100499/* From VTY core code */
500extern struct host host;
501
Harald Welte28222962011-02-18 20:37:04 +0100502static int _cfg_log_syslog(struct vty *vty, int facility)
503{
504 struct log_target *tgt;
505
506 /* First delete the old syslog target, if any */
507 tgt = log_target_find(LOG_TGT_TYPE_SYSLOG, NULL);
508 if (tgt)
509 log_target_destroy(tgt);
510
Harald Weltede79cee2011-02-24 23:47:57 +0100511 tgt = log_target_create_syslog(host.app_info->name, 0, facility);
Harald Welte28222962011-02-18 20:37:04 +0100512 if (!tgt) {
513 vty_out(vty, "%% Unable to open syslog%s", VTY_NEWLINE);
514 return CMD_WARNING;
515 }
516 log_add_target(tgt);
517
518 vty->index = tgt;
519 vty->node = CFG_LOG_NODE;
520
521 return CMD_SUCCESS;
522}
523
524DEFUN(cfg_log_syslog_local, cfg_log_syslog_local_cmd,
525 "log syslog local <0-7>",
526 LOG_STR "Logging via syslog\n" "Syslog LOCAL facility\n"
527 "Local facility number\n")
528{
529 int local = atoi(argv[0]);
530 int facility = local_sysl_map[local];
531
532 return _cfg_log_syslog(vty, facility);
533}
534
535static struct value_string sysl_level_names[] = {
536 { LOG_AUTHPRIV, "authpriv" },
537 { LOG_CRON, "cron" },
538 { LOG_DAEMON, "daemon" },
539 { LOG_FTP, "ftp" },
540 { LOG_LPR, "lpr" },
541 { LOG_MAIL, "mail" },
542 { LOG_NEWS, "news" },
543 { LOG_USER, "user" },
544 { LOG_UUCP, "uucp" },
545 /* only for value -> string conversion */
546 { LOG_LOCAL0, "local 0" },
547 { LOG_LOCAL1, "local 1" },
548 { LOG_LOCAL2, "local 2" },
549 { LOG_LOCAL3, "local 3" },
550 { LOG_LOCAL4, "local 4" },
551 { LOG_LOCAL5, "local 5" },
552 { LOG_LOCAL6, "local 6" },
553 { LOG_LOCAL7, "local 7" },
554 { 0, NULL }
555};
556
557DEFUN(cfg_log_syslog, cfg_log_syslog_cmd,
558 "log syslog (authpriv|cron|daemon|ftp|lpr|mail|news|user|uucp)",
Holger Hans Peter Freythera4463fd2011-10-03 23:17:36 +0200559 LOG_STR "Logging via syslog\n"
560 "Security/authorization messages facility\n"
561 "Clock daemon (cron/at) facility\n"
562 "General system daemon facility\n"
563 "Ftp daemon facility\n"
564 "Line printer facility\n"
565 "Mail facility\n"
566 "News facility\n"
567 "Generic facility\n"
568 "UUCP facility\n")
Harald Welte28222962011-02-18 20:37:04 +0100569{
570 int facility = get_string_value(sysl_level_names, argv[0]);
571
572 return _cfg_log_syslog(vty, facility);
573}
574
575DEFUN(cfg_no_log_syslog, cfg_no_log_syslog_cmd,
576 "no log syslog",
577 NO_STR LOG_STR "Logging via syslog\n")
578{
579 struct log_target *tgt;
580
581 tgt = log_target_find(LOG_TGT_TYPE_SYSLOG, NULL);
582 if (!tgt) {
583 vty_out(vty, "%% No syslog target found%s",
584 VTY_NEWLINE);
585 return CMD_WARNING;
586 }
587
588 log_target_destroy(tgt);
589
590 return CMD_SUCCESS;
591}
592#endif /* HAVE_SYSLOG_H */
593
Harald Welteaa00f992016-12-02 15:30:02 +0100594DEFUN(cfg_log_gsmtap, cfg_log_gsmtap_cmd,
595 "log gsmtap [HOSTNAME]",
Neels Hofmeyrfd9ec3b2016-12-11 01:48:26 +0100596 LOG_STR "Logging via GSMTAP\n"
597 "Host name to send the GSMTAP logging to (UDP port 4729)\n")
Harald Welteaa00f992016-12-02 15:30:02 +0100598{
Max2f153b52018-01-04 12:25:57 +0100599 const char *hostname = argc ? argv[0] : "127.0.0.1";
Harald Welteaa00f992016-12-02 15:30:02 +0100600 struct log_target *tgt;
601
602 tgt = log_target_find(LOG_TGT_TYPE_GSMTAP, hostname);
603 if (!tgt) {
604 tgt = log_target_create_gsmtap(hostname, GSMTAP_UDP_PORT,
605 host.app_info->name, false,
606 true);
607 if (!tgt) {
Max2f153b52018-01-04 12:25:57 +0100608 vty_out(vty, "%% Unable to create GSMTAP log for %s%s",
609 hostname, VTY_NEWLINE);
Harald Welteaa00f992016-12-02 15:30:02 +0100610 return CMD_WARNING;
611 }
612 log_add_target(tgt);
613 }
614
615 vty->index = tgt;
616 vty->node = CFG_LOG_NODE;
617
618 return CMD_SUCCESS;
619}
620
Harald Welte28222962011-02-18 20:37:04 +0100621DEFUN(cfg_log_stderr, cfg_log_stderr_cmd,
622 "log stderr",
623 LOG_STR "Logging via STDERR of the process\n")
624{
625 struct log_target *tgt;
626
627 tgt = log_target_find(LOG_TGT_TYPE_STDERR, NULL);
628 if (!tgt) {
629 tgt = log_target_create_stderr();
630 if (!tgt) {
631 vty_out(vty, "%% Unable to create stderr log%s",
632 VTY_NEWLINE);
633 return CMD_WARNING;
634 }
635 log_add_target(tgt);
636 }
637
638 vty->index = tgt;
639 vty->node = CFG_LOG_NODE;
640
641 return CMD_SUCCESS;
642}
643
644DEFUN(cfg_no_log_stderr, cfg_no_log_stderr_cmd,
645 "no log stderr",
646 NO_STR LOG_STR "Logging via STDERR of the process\n")
647{
648 struct log_target *tgt;
649
650 tgt = log_target_find(LOG_TGT_TYPE_STDERR, NULL);
651 if (!tgt) {
652 vty_out(vty, "%% No stderr logging active%s", VTY_NEWLINE);
653 return CMD_WARNING;
654 }
655
656 log_target_destroy(tgt);
657
658 return CMD_SUCCESS;
659}
660
661DEFUN(cfg_log_file, cfg_log_file_cmd,
662 "log file .FILENAME",
663 LOG_STR "Logging to text file\n" "Filename\n")
664{
665 const char *fname = argv[0];
666 struct log_target *tgt;
667
668 tgt = log_target_find(LOG_TGT_TYPE_FILE, fname);
669 if (!tgt) {
670 tgt = log_target_create_file(fname);
671 if (!tgt) {
672 vty_out(vty, "%% Unable to create file `%s'%s",
673 fname, VTY_NEWLINE);
674 return CMD_WARNING;
675 }
676 log_add_target(tgt);
677 }
678
679 vty->index = tgt;
680 vty->node = CFG_LOG_NODE;
681
682 return CMD_SUCCESS;
683}
684
685
686DEFUN(cfg_no_log_file, cfg_no_log_file_cmd,
687 "no log file .FILENAME",
688 NO_STR LOG_STR "Logging to text file\n" "Filename\n")
689{
690 const char *fname = argv[0];
691 struct log_target *tgt;
692
693 tgt = log_target_find(LOG_TGT_TYPE_FILE, fname);
694 if (!tgt) {
695 vty_out(vty, "%% No such log file `%s'%s",
696 fname, VTY_NEWLINE);
697 return CMD_WARNING;
698 }
699
700 log_target_destroy(tgt);
701
702 return CMD_SUCCESS;
703}
704
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000705DEFUN(cfg_log_alarms, cfg_log_alarms_cmd,
706 "log alarms <2-32700>",
707 LOG_STR "Logging alarms to osmo_strrb\n"
708 "Maximum number of messages to log\n")
709{
710 struct log_target *tgt;
711 unsigned int rbsize = atoi(argv[0]);
712
713 tgt = log_target_find(LOG_TGT_TYPE_STRRB, NULL);
714 if (tgt)
715 log_target_destroy(tgt);
716
717 tgt = log_target_create_rb(rbsize);
718 if (!tgt) {
719 vty_out(vty, "%% Unable to create osmo_strrb (size %u)%s",
720 rbsize, VTY_NEWLINE);
721 return CMD_WARNING;
722 }
723 log_add_target(tgt);
724
725 vty->index = tgt;
726 vty->node = CFG_LOG_NODE;
727
728 return CMD_SUCCESS;
729}
730
731DEFUN(cfg_no_log_alarms, cfg_no_log_alarms_cmd,
732 "no log alarms",
733 NO_STR LOG_STR "Logging alarms to osmo_strrb\n")
734{
735 struct log_target *tgt;
736
737 tgt = log_target_find(LOG_TGT_TYPE_STRRB, NULL);
738 if (!tgt) {
739 vty_out(vty, "%% No osmo_strrb target found%s", VTY_NEWLINE);
740 return CMD_WARNING;
741 }
742
743 log_target_destroy(tgt);
744
745 return CMD_SUCCESS;
746}
747
Harald Welte28222962011-02-18 20:37:04 +0100748static int config_write_log_single(struct vty *vty, struct log_target *tgt)
749{
750 int i;
751 char level_lower[32];
752
753 switch (tgt->type) {
754 case LOG_TGT_TYPE_VTY:
755 return 1;
756 break;
757 case LOG_TGT_TYPE_STDERR:
758 vty_out(vty, "log stderr%s", VTY_NEWLINE);
759 break;
760 case LOG_TGT_TYPE_SYSLOG:
761#ifdef HAVE_SYSLOG_H
762 vty_out(vty, "log syslog %s%s",
763 get_value_string(sysl_level_names,
764 tgt->tgt_syslog.facility),
765 VTY_NEWLINE);
766#endif
767 break;
768 case LOG_TGT_TYPE_FILE:
769 vty_out(vty, "log file %s%s", tgt->tgt_file.fname, VTY_NEWLINE);
770 break;
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000771 case LOG_TGT_TYPE_STRRB:
772 vty_out(vty, "log alarms %zu%s",
773 log_target_rb_avail_size(tgt), VTY_NEWLINE);
774 break;
Harald Welteaa00f992016-12-02 15:30:02 +0100775 case LOG_TGT_TYPE_GSMTAP:
776 vty_out(vty, "log gsmtap %s%s",
777 tgt->tgt_gsmtap.hostname, VTY_NEWLINE);
778 break;
Harald Welte28222962011-02-18 20:37:04 +0100779 }
780
Harald Welte2da47f12012-10-22 19:31:54 +0200781 vty_out(vty, " logging filter all %u%s",
Neels Hofmeyr8b86cd72017-02-23 18:03:28 +0100782 tgt->filter_map & (1 << LOG_FLT_ALL) ? 1 : 0, VTY_NEWLINE);
Harald Weltefb84f322013-06-06 07:33:54 +0200783 /* save filters outside of libosmocore, i.e. in app code */
784 if (osmo_log_info->save_fn)
785 osmo_log_info->save_fn(vty, osmo_log_info, tgt);
Harald Welte2da47f12012-10-22 19:31:54 +0200786
Harald Welte28222962011-02-18 20:37:04 +0100787 vty_out(vty, " logging color %u%s", tgt->use_color ? 1 : 0,
788 VTY_NEWLINE);
Holger Hans Peter Freyther879acef2015-01-27 11:06:51 +0100789 vty_out(vty, " logging print category %d%s",
Michael McTernan78933462015-03-20 15:29:25 +0100790 tgt->print_category ? 1 : 0, VTY_NEWLINE);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100791 if (tgt->print_ext_timestamp)
792 vty_out(vty, " logging print extended-timestamp 1%s", VTY_NEWLINE);
793 else
794 vty_out(vty, " logging timestamp %u%s",
795 tgt->print_timestamp ? 1 : 0, VTY_NEWLINE);
Neels Hofmeyr886e5482018-01-16 01:49:37 +0100796 if (tgt->print_level)
797 vty_out(vty, " logging print level 1%s", VTY_NEWLINE);
Neels Hofmeyr22772cc2018-02-06 00:52:08 +0100798 vty_out(vty, " logging print file %s%s",
799 get_value_string(logging_print_file_args, tgt->print_filename2),
800 VTY_NEWLINE);
Harald Welte28222962011-02-18 20:37:04 +0100801
802 /* stupid old osmo logging API uses uppercase strings... */
803 osmo_str2lower(level_lower, log_level_str(tgt->loglevel));
804 vty_out(vty, " logging level all %s%s", level_lower, VTY_NEWLINE);
805
806 for (i = 0; i < osmo_log_info->num_cat; i++) {
807 const struct log_category *cat = &tgt->categories[i];
808 char cat_lower[32];
809
Harald Welte1a02cfc2013-03-19 10:37:39 +0100810 /* skip empty entries in the array */
811 if (!osmo_log_info->cat[i].name)
812 continue;
813
Harald Welte28222962011-02-18 20:37:04 +0100814 /* stupid old osmo logging API uses uppercase strings... */
815 osmo_str2lower(cat_lower, osmo_log_info->cat[i].name+1);
816 osmo_str2lower(level_lower, log_level_str(cat->loglevel));
817
Maxed0eda22017-07-06 17:09:01 +0200818 if (strcmp(level_lower, "everything") != 0) /* FIXME: remove this check once 'everything' is phased out */
819 vty_out(vty, " logging level %s %s%s", cat_lower, level_lower, VTY_NEWLINE);
820 else
821 LOGP(DLSTATS, LOGL_ERROR, "logging level everything is deprecated and should not be used\n");
Harald Welte28222962011-02-18 20:37:04 +0100822 }
823
824 /* FIXME: levels */
825
826 return 1;
827}
828
829static int config_write_log(struct vty *vty)
830{
831 struct log_target *dbg = vty->index;
832
833 llist_for_each_entry(dbg, &osmo_log_target_list, entry)
834 config_write_log_single(vty, dbg);
835
836 return 1;
837}
838
Harald Welte11eb4b52018-06-09 17:41:31 +0200839static int log_deprecated_func(struct cmd_element *cmd, struct vty *vty, int argc, const char *argv[])
840{
841 vty_out(vty, "%% Ignoring deprecated '%s'%s", cmd->string, VTY_NEWLINE);
842 return CMD_WARNING;
843}
844
845void logging_vty_add_deprecated_subsys(void *ctx, const char *name)
846{
847 struct cmd_element *cmd = talloc_zero(ctx, struct cmd_element);
848 OSMO_ASSERT(cmd);
849 cmd->string = talloc_asprintf(cmd, "logging level %s (everything|debug|info|notice|error|fatal)",
850 name);
851 printf("%s\n", cmd->string);
852 cmd->func = log_deprecated_func;
853 cmd->doc = "Set the log level for a specified category\n"
854 "Deprecated Category\n";
855 cmd->attr = CMD_ATTR_DEPRECATED;
856
857 install_element(CFG_LOG_NODE, cmd);
858}
859
Harald Welte8c648252017-10-16 15:17:03 +0200860/*! Register logging related commands to the VTY. Call this once from
861 * your application if you want to support those commands. */
Maxc65c5b42017-03-15 13:20:23 +0100862void logging_vty_add_cmds()
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200863{
864 install_element_ve(&enable_logging_cmd);
865 install_element_ve(&disable_logging_cmd);
866 install_element_ve(&logging_fltr_all_cmd);
867 install_element_ve(&logging_use_clr_cmd);
868 install_element_ve(&logging_prnt_timestamp_cmd);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100869 install_element_ve(&logging_prnt_ext_timestamp_cmd);
870 install_element_ve(&logging_prnt_cat_cmd);
Neels Hofmeyrbd7bd392018-01-16 01:52:29 +0100871 install_element_ve(&logging_prnt_cat_hex_cmd);
Neels Hofmeyr886e5482018-01-16 01:49:37 +0100872 install_element_ve(&logging_prnt_level_cmd);
Neels Hofmeyrc6fd2452018-01-16 01:57:38 +0100873 install_element_ve(&logging_prnt_file_cmd);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200874 install_element_ve(&logging_set_category_mask_cmd);
Holger Hans Peter Freyther146d1d32011-10-03 23:15:41 +0200875 install_element_ve(&logging_set_category_mask_old_cmd);
Pablo Neira Ayuso04139f12011-03-09 13:05:08 +0100876
877 /* Logging level strings are generated dynamically. */
Maxc65c5b42017-03-15 13:20:23 +0100878 logging_level_cmd.string = log_vty_command_string();
879 logging_level_cmd.doc = log_vty_command_description();
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200880 install_element_ve(&logging_level_cmd);
881 install_element_ve(&show_logging_vty_cmd);
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000882 install_element_ve(&show_alarms_cmd);
Harald Welte28222962011-02-18 20:37:04 +0100883
884 install_node(&cfg_log_node, config_write_log);
Harald Weltea62648b2011-02-18 21:03:27 +0100885 install_element(CFG_LOG_NODE, &logging_fltr_all_cmd);
886 install_element(CFG_LOG_NODE, &logging_use_clr_cmd);
887 install_element(CFG_LOG_NODE, &logging_prnt_timestamp_cmd);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100888 install_element(CFG_LOG_NODE, &logging_prnt_ext_timestamp_cmd);
889 install_element(CFG_LOG_NODE, &logging_prnt_cat_cmd);
Neels Hofmeyrbd7bd392018-01-16 01:52:29 +0100890 install_element(CFG_LOG_NODE, &logging_prnt_cat_hex_cmd);
Neels Hofmeyr886e5482018-01-16 01:49:37 +0100891 install_element(CFG_LOG_NODE, &logging_prnt_level_cmd);
Neels Hofmeyrc6fd2452018-01-16 01:57:38 +0100892 install_element(CFG_LOG_NODE, &logging_prnt_file_cmd);
Harald Weltea62648b2011-02-18 21:03:27 +0100893 install_element(CFG_LOG_NODE, &logging_level_cmd);
Harald Welte28222962011-02-18 20:37:04 +0100894
895 install_element(CONFIG_NODE, &cfg_log_stderr_cmd);
896 install_element(CONFIG_NODE, &cfg_no_log_stderr_cmd);
897 install_element(CONFIG_NODE, &cfg_log_file_cmd);
898 install_element(CONFIG_NODE, &cfg_no_log_file_cmd);
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000899 install_element(CONFIG_NODE, &cfg_log_alarms_cmd);
900 install_element(CONFIG_NODE, &cfg_no_log_alarms_cmd);
Harald Welte28222962011-02-18 20:37:04 +0100901#ifdef HAVE_SYSLOG_H
902 install_element(CONFIG_NODE, &cfg_log_syslog_cmd);
903 install_element(CONFIG_NODE, &cfg_log_syslog_local_cmd);
904 install_element(CONFIG_NODE, &cfg_no_log_syslog_cmd);
905#endif
Harald Welteaa00f992016-12-02 15:30:02 +0100906 install_element(CONFIG_NODE, &cfg_log_gsmtap_cmd);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200907}