blob: bd513e306544b1e6e079ea22a1c4fa3caca36d47 [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>
Neels Hofmeyrba0762d2018-09-10 13:56:03 +020031#include <osmocom/core/logging_internal.h>
Pablo Neira Ayuso83419342011-03-22 16:36:13 +010032#include <osmocom/core/utils.h>
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +000033#include <osmocom/core/strrb.h>
34#include <osmocom/core/loggingrb.h>
Harald Welteaa00f992016-12-02 15:30:02 +010035#include <osmocom/core/gsmtap.h>
Harald Weltee4d9a2c2020-09-27 11:28:58 +020036#include <osmocom/core/application.h>
Harald Welte3fb0b6f2010-05-19 19:02:52 +020037
38#include <osmocom/vty/command.h>
39#include <osmocom/vty/buffer.h>
40#include <osmocom/vty/vty.h>
41#include <osmocom/vty/telnet_interface.h>
42#include <osmocom/vty/logging.h>
43
Harald Welte28222962011-02-18 20:37:04 +010044#define LOG_STR "Configure logging sub-system\n"
Neels Hofmeyrba0762d2018-09-10 13:56:03 +020045#define LEVEL_STR "Set the log level for a specified category\n"
46
Neels Hofmeyr9540c242018-09-12 00:20:50 +020047#define CATEGORY_ALL_STR "Deprecated alias for 'force-all'\n"
48#define FORCE_ALL_STR \
49 "Globally force all logging categories to a specific level. This is released by the" \
50 " 'no logging level force-all' command. Note: any 'logging level <category> <level>'" \
51 " commands will have no visible effect after this, until the forced level is released.\n"
52#define NO_FORCE_ALL_STR \
53 "Release any globally forced log level set with 'logging level force-all <level>'\n"
Neels Hofmeyrba0762d2018-09-10 13:56:03 +020054
Neels Hofmeyr9540c242018-09-12 00:20:50 +020055#define LOG_LEVEL_ARGS "(debug|info|notice|error|fatal)"
Neels Hofmeyrba0762d2018-09-10 13:56:03 +020056#define LOG_LEVEL_STRS \
57 "Log debug messages and higher levels\n" \
58 "Log informational messages and higher levels\n" \
59 "Log noticeable messages and higher levels\n" \
60 "Log error messages and higher levels\n" \
61 "Log only fatal messages\n"
62
Neels Hofmeyr9540c242018-09-12 00:20:50 +020063#define EVERYTHING_STR "Deprecated alias for 'no logging level force-all'\n"
Harald Welte28222962011-02-18 20:37:04 +010064
Harald Welte8c648252017-10-16 15:17:03 +020065/*! \file logging_vty.c
Neels Hofmeyr87e45502017-06-20 00:17:59 +020066 * Configuration of logging from VTY
Harald Welte96e2a002017-06-12 21:44:18 +020067 *
Harald Welte8c648252017-10-16 15:17:03 +020068 * This module implements
69 * - functions that permit configuration of the libosmocore logging
70 * framework from VTY commands in the configure -> logging node.
71 *
72 * - functions that permit logging *to* a VTY session. Basically each
73 * VTY session gets its own log target, with configurable
74 * per-subsystem log levels. This is performed internally via the
75 * \ref log_target_create_vty function.
76 *
77 * You have to call \ref logging_vty_add_cmds from your application
78 * once to enable both of the above.
79 *
Harald Welte96e2a002017-06-12 21:44:18 +020080 */
81
Harald Welte76e72ab2011-02-17 15:52:39 +010082static void _vty_output(struct log_target *tgt,
83 unsigned int level, const char *line)
Harald Welte3fb0b6f2010-05-19 19:02:52 +020084{
85 struct vty *vty = tgt->tgt_vty.vty;
86 vty_out(vty, "%s", line);
87 /* This is an ugly hack, but there is no easy way... */
88 if (strchr(line, '\n'))
89 vty_out(vty, "\r");
90}
91
92struct log_target *log_target_create_vty(struct vty *vty)
93{
94 struct log_target *target;
95
96 target = log_target_create();
97 if (!target)
98 return NULL;
99
100 target->tgt_vty.vty = vty;
101 target->output = _vty_output;
102 return target;
103}
104
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200105/*! Get tgt with log lock acquired, return and release lock with warning if tgt
106 * is not found. Lock must be released later with log_tgt_mutex_unlock().
107 */
108#define ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt) \
109 do { \
110 log_tgt_mutex_lock(); \
111 tgt = osmo_log_vty2tgt(vty); \
112 if (!(tgt)) { \
113 log_tgt_mutex_unlock(); \
114 return CMD_WARNING; \
115 } \
116 } while (0)
117
118#define RET_WITH_UNLOCK(ret) \
119 do { \
120 log_tgt_mutex_unlock(); \
121 return (ret); \
122 } while (0)
123
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200124DEFUN(enable_logging,
125 enable_logging_cmd,
126 "logging enable",
127 LOGGING_STR
128 "Enables logging to this vty\n")
129{
130 struct telnet_connection *conn;
131
132 conn = (struct telnet_connection *) vty->priv;
133 if (conn->dbg) {
134 vty_out(vty, "Logging already enabled.%s", VTY_NEWLINE);
135 return CMD_WARNING;
136 }
137
138 conn->dbg = log_target_create_vty(vty);
139 if (!conn->dbg)
140 return CMD_WARNING;
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200141 log_tgt_mutex_lock();
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200142 log_add_target(conn->dbg);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200143 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200144}
145
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200146/*! Get log target associated to VTY console.
147 * \param[in] vty Log target type
148 * \returns Log target (if logging enabled), NULL otherwise
149 * Must be called with mutex osmo_log_tgt_mutex held, see log_tgt_mutex_lock.
150 */
Harald Weltea62648b2011-02-18 21:03:27 +0100151struct log_target *osmo_log_vty2tgt(struct vty *vty)
152{
153 struct telnet_connection *conn;
154
155 if (vty->node == CFG_LOG_NODE)
156 return vty->index;
157
158
159 conn = (struct telnet_connection *) vty->priv;
160 if (!conn->dbg)
161 vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE);
162
163 return conn->dbg;
164}
165
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200166DEFUN(logging_fltr_all,
167 logging_fltr_all_cmd,
168 "logging filter all (0|1)",
169 LOGGING_STR FILTER_STR
170 "Do you want to log all messages?\n"
171 "Only print messages matched by other filters\n"
172 "Bypass filter and print all messages\n")
173{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200174 struct log_target *tgt;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200175
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200176 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200177
Harald Weltea62648b2011-02-18 21:03:27 +0100178 log_set_all_filter(tgt, atoi(argv[0]));
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200179 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200180}
181
182DEFUN(logging_use_clr,
183 logging_use_clr_cmd,
184 "logging color (0|1)",
185 LOGGING_STR "Configure color-printing for log messages\n"
186 "Don't use color for printing messages\n"
187 "Use color for printing messages\n")
188{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200189 struct log_target *tgt;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200190
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200191 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200192
Harald Weltea62648b2011-02-18 21:03:27 +0100193 log_set_use_color(tgt, atoi(argv[0]));
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200194 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200195}
196
197DEFUN(logging_prnt_timestamp,
198 logging_prnt_timestamp_cmd,
199 "logging timestamp (0|1)",
200 LOGGING_STR "Configure log message timestamping\n"
201 "Don't prefix each log message\n"
202 "Prefix each log message with current timestamp\n")
203{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200204 struct log_target *tgt;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200205
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200206 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200207
Harald Weltea62648b2011-02-18 21:03:27 +0100208 log_set_print_timestamp(tgt, atoi(argv[0]));
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200209 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200210}
211
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100212DEFUN(logging_prnt_ext_timestamp,
213 logging_prnt_ext_timestamp_cmd,
214 "logging print extended-timestamp (0|1)",
215 LOGGING_STR "Log output settings\n"
216 "Configure log message timestamping\n"
217 "Don't prefix each log message\n"
218 "Prefix each log message with current timestamp with YYYYMMDDhhmmssnnn\n")
219{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200220 struct log_target *tgt;
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100221
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200222 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100223
224 log_set_print_extended_timestamp(tgt, atoi(argv[0]));
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200225 RET_WITH_UNLOCK(CMD_SUCCESS);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100226}
227
228DEFUN(logging_prnt_cat,
229 logging_prnt_cat_cmd,
230 "logging print category (0|1)",
231 LOGGING_STR "Log output settings\n"
232 "Configure log message\n"
233 "Don't prefix each log message\n"
234 "Prefix each log message with category/subsystem name\n")
235{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200236 struct log_target *tgt;
237 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100238
239 log_set_print_category(tgt, atoi(argv[0]));
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200240 RET_WITH_UNLOCK(CMD_SUCCESS);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100241}
242
Neels Hofmeyrbd7bd392018-01-16 01:52:29 +0100243DEFUN(logging_prnt_cat_hex,
244 logging_prnt_cat_hex_cmd,
245 "logging print category-hex (0|1)",
246 LOGGING_STR "Log output settings\n"
247 "Configure log message\n"
248 "Don't prefix each log message\n"
249 "Prefix each log message with category/subsystem nr in hex ('<000b>')\n")
250{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200251 struct log_target *tgt;
Neels Hofmeyrbd7bd392018-01-16 01:52:29 +0100252
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200253 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
Neels Hofmeyrbd7bd392018-01-16 01:52:29 +0100254
255 log_set_print_category_hex(tgt, atoi(argv[0]));
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200256 RET_WITH_UNLOCK(CMD_SUCCESS);
Neels Hofmeyrbd7bd392018-01-16 01:52:29 +0100257}
258
Neels Hofmeyr886e5482018-01-16 01:49:37 +0100259DEFUN(logging_prnt_level,
260 logging_prnt_level_cmd,
261 "logging print level (0|1)",
262 LOGGING_STR "Log output settings\n"
263 "Configure log message\n"
264 "Don't prefix each log message\n"
265 "Prefix each log message with the log level name\n")
266{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200267 struct log_target *tgt;
Neels Hofmeyr886e5482018-01-16 01:49:37 +0100268
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200269 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
Neels Hofmeyr886e5482018-01-16 01:49:37 +0100270
271 log_set_print_level(tgt, atoi(argv[0]));
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200272 RET_WITH_UNLOCK(CMD_SUCCESS);
Neels Hofmeyr886e5482018-01-16 01:49:37 +0100273}
274
Neels Hofmeyr22772cc2018-02-06 00:52:08 +0100275static const struct value_string logging_print_file_args[] = {
276 { LOG_FILENAME_NONE, "0" },
277 { LOG_FILENAME_PATH, "1" },
278 { LOG_FILENAME_BASENAME, "basename" },
279 { 0, NULL }
280};
281
Neels Hofmeyrc6fd2452018-01-16 01:57:38 +0100282DEFUN(logging_prnt_file,
283 logging_prnt_file_cmd,
Neels Hofmeyr77ae45d2018-08-27 20:32:36 +0200284 "logging print file (0|1|basename) [last]",
Neels Hofmeyrc6fd2452018-01-16 01:57:38 +0100285 LOGGING_STR "Log output settings\n"
286 "Configure log message\n"
287 "Don't prefix each log message\n"
288 "Prefix each log message with the source file and line\n"
Neels Hofmeyr77ae45d2018-08-27 20:32:36 +0200289 "Prefix each log message with the source file's basename (strip leading paths) and line\n"
290 "Log source file info at the end of a log line. If omitted, log source file info just"
291 " before the log text.\n")
Neels Hofmeyrc6fd2452018-01-16 01:57:38 +0100292{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200293 struct log_target *tgt;
Neels Hofmeyrc6fd2452018-01-16 01:57:38 +0100294
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200295 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
Neels Hofmeyrc6fd2452018-01-16 01:57:38 +0100296
Neels Hofmeyr22772cc2018-02-06 00:52:08 +0100297 log_set_print_filename2(tgt, get_string_value(logging_print_file_args, argv[0]));
Neels Hofmeyr77ae45d2018-08-27 20:32:36 +0200298 if (argc > 1)
299 log_set_print_filename_pos(tgt, LOG_FILENAME_POS_LINE_END);
300 else
301 log_set_print_filename_pos(tgt, LOG_FILENAME_POS_HEADER_END);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200302 RET_WITH_UNLOCK(CMD_SUCCESS);
Neels Hofmeyrc6fd2452018-01-16 01:57:38 +0100303}
304
Neels Hofmeyrba0762d2018-09-10 13:56:03 +0200305static void add_category_strings(char **cmd_str_p, char **doc_str_p,
306 const struct log_info *categories)
307{
Pau Espin Pedrolc21ba152019-08-02 20:32:34 +0200308 char buf[128];
Neels Hofmeyrba0762d2018-09-10 13:56:03 +0200309 int i;
310 for (i = 0; i < categories->num_cat; i++) {
311 if (categories->cat[i].name == NULL)
312 continue;
313 /* skip the leading 'D' in each category name, hence '+ 1' */
Pau Espin Pedrolc21ba152019-08-02 20:32:34 +0200314 osmo_str_tolower_buf(buf, sizeof(buf), categories->cat[i].name + 1);
Neels Hofmeyrba0762d2018-09-10 13:56:03 +0200315 osmo_talloc_asprintf(tall_log_ctx, *cmd_str_p, "%s%s",
Pau Espin Pedrolc21ba152019-08-02 20:32:34 +0200316 i ? "|" : "", buf);
Neels Hofmeyrba0762d2018-09-10 13:56:03 +0200317 osmo_talloc_asprintf(tall_log_ctx, *doc_str_p, "%s\n",
318 categories->cat[i].description);
319 }
320}
321
322static void gen_logging_level_cmd_strs(struct cmd_element *cmd,
323 const char *level_args, const char *level_strs)
324{
325 char *cmd_str = NULL;
326 char *doc_str = NULL;
327
328 assert_loginfo(__func__);
329
330 OSMO_ASSERT(cmd->string == NULL);
331 OSMO_ASSERT(cmd->doc == NULL);
332
Neels Hofmeyr9540c242018-09-12 00:20:50 +0200333 osmo_talloc_asprintf(tall_log_ctx, cmd_str, "logging level (");
Neels Hofmeyrba0762d2018-09-10 13:56:03 +0200334 osmo_talloc_asprintf(tall_log_ctx, doc_str,
335 LOGGING_STR
Neels Hofmeyr9540c242018-09-12 00:20:50 +0200336 LEVEL_STR);
Neels Hofmeyrba0762d2018-09-10 13:56:03 +0200337 add_category_strings(&cmd_str, &doc_str, osmo_log_info);
338 osmo_talloc_asprintf(tall_log_ctx, cmd_str, ") %s", level_args);
339 osmo_talloc_asprintf(tall_log_ctx, doc_str, "%s", level_strs);
340
Harald Weltebebec212020-07-15 12:21:29 +0200341 talloc_set_name_const(cmd_str, "vty_log_level_cmd_str");
342 talloc_set_name_const(doc_str, "vty_log_level_doc_str");
343
Neels Hofmeyrba0762d2018-09-10 13:56:03 +0200344 cmd->string = cmd_str;
345 cmd->doc = doc_str;
346}
347
Neels Hofmeyr9540c242018-09-12 00:20:50 +0200348/* logging level (<categories>) (debug|...|fatal) */
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200349DEFUN(logging_level,
350 logging_level_cmd,
Pablo Neira Ayuso04139f12011-03-09 13:05:08 +0100351 NULL, /* cmdstr is dynamically set in logging_vty_add_cmds(). */
352 NULL) /* same thing for helpstr. */
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200353{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200354 struct log_target *tgt;
Harald Weltea62648b2011-02-18 21:03:27 +0100355 int category = log_parse_category(argv[0]);
356 int level = log_parse_level(argv[1]);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200357
Harald Weltea62648b2011-02-18 21:03:27 +0100358 if (level < 0) {
359 vty_out(vty, "Invalid level `%s'%s", argv[1], VTY_NEWLINE);
Pau Espin Pedrol57d11182020-01-02 16:21:14 +0100360 return CMD_WARNING;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200361 }
362
Harald Weltea62648b2011-02-18 21:03:27 +0100363 if (category < 0) {
364 vty_out(vty, "Invalid category `%s'%s", argv[0], VTY_NEWLINE);
Pau Espin Pedrol57d11182020-01-02 16:21:14 +0100365 return CMD_WARNING;
Harald Weltea62648b2011-02-18 21:03:27 +0100366 }
367
Pau Espin Pedrol57d11182020-01-02 16:21:14 +0100368 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
369
Harald Weltea62648b2011-02-18 21:03:27 +0100370 tgt->categories[category].enabled = 1;
371 tgt->categories[category].loglevel = level;
372
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200373 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200374}
375
Neels Hofmeyr28fc0782018-09-12 02:32:02 +0200376DEFUN(logging_level_set_all, logging_level_set_all_cmd,
377 "logging level set-all " LOG_LEVEL_ARGS,
378 LOGGING_STR LEVEL_STR
379 "Once-off set all categories to the given log level. There is no single command"
380 " to take back these changes -- each category is set to the given level, period.\n"
381 LOG_LEVEL_STRS)
382{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200383 struct log_target *tgt;
Neels Hofmeyr28fc0782018-09-12 02:32:02 +0200384 int level = log_parse_level(argv[0]);
385 int i;
Neels Hofmeyrea6f5192018-10-01 15:51:18 +0200386
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200387 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
Neels Hofmeyrea6f5192018-10-01 15:51:18 +0200388
Neels Hofmeyr28fc0782018-09-12 02:32:02 +0200389 for (i = 0; i < osmo_log_info->num_cat; i++) {
390 struct log_category *cat = &tgt->categories[i];
391 /* skip empty entries in the array */
392 if (!osmo_log_info->cat[i].name)
393 continue;
394
395 cat->enabled = 1;
396 cat->loglevel = level;
397 }
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200398 RET_WITH_UNLOCK(CMD_SUCCESS);
Neels Hofmeyr28fc0782018-09-12 02:32:02 +0200399}
400
Neels Hofmeyr9540c242018-09-12 00:20:50 +0200401/* logging level (<categories>) everything */
Neels Hofmeyr7e0686c2018-09-10 20:58:52 +0200402DEFUN_DEPRECATED(deprecated_logging_level_everything, deprecated_logging_level_everything_cmd,
403 NULL, /* cmdstr is dynamically set in logging_vty_add_cmds(). */
404 NULL) /* same thing for helpstr. */
405{
406 vty_out(vty, "%% Ignoring deprecated logging level 'everything' keyword%s", VTY_NEWLINE);
407 return CMD_SUCCESS;
408}
409
Neels Hofmeyr9540c242018-09-12 00:20:50 +0200410DEFUN(logging_level_force_all, logging_level_force_all_cmd,
411 "logging level force-all " LOG_LEVEL_ARGS,
412 LOGGING_STR LEVEL_STR FORCE_ALL_STR LOG_LEVEL_STRS)
413{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200414 struct log_target *tgt;
Neels Hofmeyr9540c242018-09-12 00:20:50 +0200415 int level = log_parse_level(argv[0]);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200416
417 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
418
Neels Hofmeyr9540c242018-09-12 00:20:50 +0200419 log_set_log_level(tgt, level);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200420 RET_WITH_UNLOCK(CMD_SUCCESS);
Neels Hofmeyr9540c242018-09-12 00:20:50 +0200421}
422
423DEFUN(no_logging_level_force_all, no_logging_level_force_all_cmd,
424 "no logging level force-all",
425 NO_STR LOGGING_STR LEVEL_STR NO_FORCE_ALL_STR)
426{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200427 struct log_target *tgt;
428
429 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
430
Neels Hofmeyr9540c242018-09-12 00:20:50 +0200431 log_set_log_level(tgt, 0);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200432 RET_WITH_UNLOCK(CMD_SUCCESS);
Neels Hofmeyr9540c242018-09-12 00:20:50 +0200433}
434
435/* 'logging level all (debug|...|fatal)' */
436ALIAS_DEPRECATED(logging_level_force_all, deprecated_logging_level_all_cmd,
437 "logging level all " LOG_LEVEL_ARGS,
438 LOGGING_STR LEVEL_STR CATEGORY_ALL_STR LOG_LEVEL_STRS);
439
440/* 'logging level all everything' */
441ALIAS_DEPRECATED(no_logging_level_force_all, deprecated_logging_level_all_everything_cmd,
442 "logging level all everything",
443 LOGGING_STR LEVEL_STR CATEGORY_ALL_STR EVERYTHING_STR);
444
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200445DEFUN(logging_set_category_mask,
446 logging_set_category_mask_cmd,
Holger Hans Peter Freyther146d1d32011-10-03 23:15:41 +0200447 "logging set-log-mask MASK",
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200448 LOGGING_STR
Holger Hans Peter Freyther146d1d32011-10-03 23:15:41 +0200449 "Set the logmask of this logging target\n"
Neels Hofmeyr84ea2e02017-12-09 05:53:18 +0100450 "List of logging categories to log, e.g. 'abc:mno:xyz'. Available log categories depend on the specific"
451 " application, refer to the 'logging level' command. Optionally add individual log levels like"
452 " 'abc,1:mno,3:xyz,5', where the level numbers are"
453 " " OSMO_STRINGIFY(LOGL_DEBUG) "=" OSMO_STRINGIFY_VAL(LOGL_DEBUG)
454 " " OSMO_STRINGIFY(LOGL_INFO) "=" OSMO_STRINGIFY_VAL(LOGL_INFO)
455 " " OSMO_STRINGIFY(LOGL_NOTICE) "=" OSMO_STRINGIFY_VAL(LOGL_NOTICE)
456 " " OSMO_STRINGIFY(LOGL_ERROR) "=" OSMO_STRINGIFY_VAL(LOGL_ERROR)
457 " " OSMO_STRINGIFY(LOGL_FATAL) "=" OSMO_STRINGIFY_VAL(LOGL_FATAL)
458 "\n")
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200459{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200460 struct log_target *tgt;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200461
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200462 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200463
Harald Weltea62648b2011-02-18 21:03:27 +0100464 log_parse_category_mask(tgt, argv[0]);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200465 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200466}
467
Holger Hans Peter Freyther146d1d32011-10-03 23:15:41 +0200468ALIAS_DEPRECATED(logging_set_category_mask,
469 logging_set_category_mask_old_cmd,
470 "logging set log mask MASK",
471 LOGGING_STR
472 "Decide which categories to output.\n"
Neels Hofmeyr84ea2e02017-12-09 05:53:18 +0100473 "Log commands\n" "Mask commands\n"
474 "'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 +0200475
476
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200477DEFUN(diable_logging,
478 disable_logging_cmd,
479 "logging disable",
480 LOGGING_STR
481 "Disables logging to this vty\n")
482{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200483 struct log_target *tgt;
Harald Weltea62648b2011-02-18 21:03:27 +0100484 struct telnet_connection *conn = (struct telnet_connection *) vty->priv;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200485
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200486 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200487
Harald Weltea62648b2011-02-18 21:03:27 +0100488 log_del_target(tgt);
489 talloc_free(tgt);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200490 conn->dbg = NULL;
Harald Weltea62648b2011-02-18 21:03:27 +0100491
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200492 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200493}
494
495static void vty_print_logtarget(struct vty *vty, const struct log_info *info,
496 const struct log_target *tgt)
497{
498 unsigned int i;
499
500 vty_out(vty, " Global Loglevel: %s%s",
501 log_level_str(tgt->loglevel), VTY_NEWLINE);
502 vty_out(vty, " Use color: %s, Print Timestamp: %s%s",
503 tgt->use_color ? "On" : "Off",
504 tgt->print_timestamp ? "On" : "Off", VTY_NEWLINE);
505
506 vty_out(vty, " Log Level specific information:%s", VTY_NEWLINE);
507
508 for (i = 0; i < info->num_cat; i++) {
509 const struct log_category *cat = &tgt->categories[i];
Daniel Willmann55363a92016-11-15 10:05:51 +0100510 /* Skip categories that were not initialized */
511 if (!info->cat[i].name)
512 continue;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200513 vty_out(vty, " %-10s %-10s %-8s %s%s",
514 info->cat[i].name+1, log_level_str(cat->loglevel),
515 cat->enabled ? "Enabled" : "Disabled",
516 info->cat[i].description,
517 VTY_NEWLINE);
518 }
Harald Welte6d2d4d62013-03-10 09:53:24 +0000519
520 vty_out(vty, " Log Filter 'ALL': %s%s",
Neels Hofmeyr8b86cd72017-02-23 18:03:28 +0100521 tgt->filter_map & (1 << LOG_FLT_ALL) ? "Enabled" : "Disabled",
Harald Welte6d2d4d62013-03-10 09:53:24 +0000522 VTY_NEWLINE);
523
Harald Weltefb84f322013-06-06 07:33:54 +0200524 /* print application specific filters */
525 if (info->print_fn)
526 info->print_fn(vty, info, tgt);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200527}
528
529#define SHOW_LOG_STR "Show current logging configuration\n"
530
531DEFUN(show_logging_vty,
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000532 show_logging_vty_cmd,
533 "show logging vty",
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200534 SHOW_STR SHOW_LOG_STR
535 "Show current logging configuration for this vty\n")
536{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200537 struct log_target *tgt;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200538
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200539 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
Harald Weltea62648b2011-02-18 21:03:27 +0100540
541 vty_print_logtarget(vty, osmo_log_info, tgt);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200542 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200543}
544
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000545DEFUN(show_alarms,
546 show_alarms_cmd,
547 "show alarms",
548 SHOW_STR SHOW_LOG_STR
549 "Show the contents of the logging ringbuffer\n")
550{
551 int i, num_alarms;
552 struct osmo_strrb *rb;
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200553 struct log_target *tgt;
554
555 log_tgt_mutex_lock();
556 tgt = log_target_find(LOG_TGT_TYPE_STRRB, NULL);
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000557 if (!tgt) {
558 vty_out(vty, "%% No alarms, run 'log alarms <2-32700>'%s",
559 VTY_NEWLINE);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200560 RET_WITH_UNLOCK(CMD_WARNING);
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000561 }
562
563 rb = tgt->tgt_rb.rb;
564 num_alarms = osmo_strrb_elements(rb);
565
566 vty_out(vty, "%% Showing %i alarms%s", num_alarms, VTY_NEWLINE);
567
568 for (i = 0; i < num_alarms; i++)
569 vty_out(vty, "%% %s%s", osmo_strrb_get_nth(rb, i),
570 VTY_NEWLINE);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200571 RET_WITH_UNLOCK(CMD_SUCCESS);
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000572}
573
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200574gDEFUN(cfg_description, cfg_description_cmd,
575 "description .TEXT",
Thorsten Alteholza81055d2017-03-02 22:13:48 +0100576 "Save human-readable description of the object\n"
Holger Hans Peter Freytherc9b3e062012-07-25 13:02:49 +0200577 "Text until the end of the line\n")
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200578{
579 char **dptr = vty->index_sub;
580
581 if (!dptr) {
582 vty_out(vty, "vty->index_sub == NULL%s", VTY_NEWLINE);
583 return CMD_WARNING;
584 }
585
Holger Hans Peter Freytherff0670e2011-02-24 14:20:41 +0100586 if (*dptr)
587 talloc_free(*dptr);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200588 *dptr = argv_concat(argv, argc, 0);
Holger Hans Peter Freyther6a75d162013-07-14 09:07:11 +0200589 if (!*dptr)
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200590 return CMD_WARNING;
591
592 return CMD_SUCCESS;
593}
594
595gDEFUN(cfg_no_description, cfg_no_description_cmd,
596 "no description",
597 NO_STR
598 "Remove description of the object\n")
599{
600 char **dptr = vty->index_sub;
601
602 if (!dptr) {
603 vty_out(vty, "vty->index_sub == NULL%s", VTY_NEWLINE);
604 return CMD_WARNING;
605 }
606
607 if (*dptr) {
608 talloc_free(*dptr);
609 *dptr = NULL;
610 }
611
612 return CMD_SUCCESS;
613}
614
Harald Welte28222962011-02-18 20:37:04 +0100615/* Support for configuration of log targets != the current vty */
616
617struct cmd_node cfg_log_node = {
618 CFG_LOG_NODE,
619 "%s(config-log)# ",
620 1
621};
622
Harald Welte28222962011-02-18 20:37:04 +0100623#ifdef HAVE_SYSLOG_H
624
625#include <syslog.h>
626
627static const int local_sysl_map[] = {
628 [0] = LOG_LOCAL0,
629 [1] = LOG_LOCAL1,
630 [2] = LOG_LOCAL2,
631 [3] = LOG_LOCAL3,
632 [4] = LOG_LOCAL4,
633 [5] = LOG_LOCAL5,
634 [6] = LOG_LOCAL6,
635 [7] = LOG_LOCAL7
636};
637
Harald Weltede79cee2011-02-24 23:47:57 +0100638/* From VTY core code */
639extern struct host host;
640
Harald Welte28222962011-02-18 20:37:04 +0100641static int _cfg_log_syslog(struct vty *vty, int facility)
642{
643 struct log_target *tgt;
644
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200645 log_tgt_mutex_lock();
Harald Welte28222962011-02-18 20:37:04 +0100646 /* First delete the old syslog target, if any */
647 tgt = log_target_find(LOG_TGT_TYPE_SYSLOG, NULL);
648 if (tgt)
649 log_target_destroy(tgt);
650
Harald Weltede79cee2011-02-24 23:47:57 +0100651 tgt = log_target_create_syslog(host.app_info->name, 0, facility);
Harald Welte28222962011-02-18 20:37:04 +0100652 if (!tgt) {
653 vty_out(vty, "%% Unable to open syslog%s", VTY_NEWLINE);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200654 RET_WITH_UNLOCK(CMD_WARNING);
Harald Welte28222962011-02-18 20:37:04 +0100655 }
656 log_add_target(tgt);
657
658 vty->index = tgt;
659 vty->node = CFG_LOG_NODE;
660
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200661 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte28222962011-02-18 20:37:04 +0100662}
663
664DEFUN(cfg_log_syslog_local, cfg_log_syslog_local_cmd,
665 "log syslog local <0-7>",
666 LOG_STR "Logging via syslog\n" "Syslog LOCAL facility\n"
667 "Local facility number\n")
668{
669 int local = atoi(argv[0]);
670 int facility = local_sysl_map[local];
671
672 return _cfg_log_syslog(vty, facility);
673}
674
675static struct value_string sysl_level_names[] = {
676 { LOG_AUTHPRIV, "authpriv" },
677 { LOG_CRON, "cron" },
678 { LOG_DAEMON, "daemon" },
679 { LOG_FTP, "ftp" },
680 { LOG_LPR, "lpr" },
681 { LOG_MAIL, "mail" },
682 { LOG_NEWS, "news" },
683 { LOG_USER, "user" },
684 { LOG_UUCP, "uucp" },
685 /* only for value -> string conversion */
686 { LOG_LOCAL0, "local 0" },
687 { LOG_LOCAL1, "local 1" },
688 { LOG_LOCAL2, "local 2" },
689 { LOG_LOCAL3, "local 3" },
690 { LOG_LOCAL4, "local 4" },
691 { LOG_LOCAL5, "local 5" },
692 { LOG_LOCAL6, "local 6" },
693 { LOG_LOCAL7, "local 7" },
694 { 0, NULL }
695};
696
697DEFUN(cfg_log_syslog, cfg_log_syslog_cmd,
698 "log syslog (authpriv|cron|daemon|ftp|lpr|mail|news|user|uucp)",
Holger Hans Peter Freythera4463fd2011-10-03 23:17:36 +0200699 LOG_STR "Logging via syslog\n"
700 "Security/authorization messages facility\n"
701 "Clock daemon (cron/at) facility\n"
702 "General system daemon facility\n"
703 "Ftp daemon facility\n"
704 "Line printer facility\n"
705 "Mail facility\n"
706 "News facility\n"
707 "Generic facility\n"
708 "UUCP facility\n")
Harald Welte28222962011-02-18 20:37:04 +0100709{
710 int facility = get_string_value(sysl_level_names, argv[0]);
711
712 return _cfg_log_syslog(vty, facility);
713}
714
715DEFUN(cfg_no_log_syslog, cfg_no_log_syslog_cmd,
716 "no log syslog",
717 NO_STR LOG_STR "Logging via syslog\n")
718{
719 struct log_target *tgt;
720
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200721 log_tgt_mutex_lock();
Harald Welte28222962011-02-18 20:37:04 +0100722 tgt = log_target_find(LOG_TGT_TYPE_SYSLOG, NULL);
723 if (!tgt) {
724 vty_out(vty, "%% No syslog target found%s",
725 VTY_NEWLINE);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200726 RET_WITH_UNLOCK(CMD_WARNING);
Harald Welte28222962011-02-18 20:37:04 +0100727 }
728
729 log_target_destroy(tgt);
730
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200731 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte28222962011-02-18 20:37:04 +0100732}
733#endif /* HAVE_SYSLOG_H */
734
Harald Welteaa00f992016-12-02 15:30:02 +0100735DEFUN(cfg_log_gsmtap, cfg_log_gsmtap_cmd,
736 "log gsmtap [HOSTNAME]",
Neels Hofmeyrfd9ec3b2016-12-11 01:48:26 +0100737 LOG_STR "Logging via GSMTAP\n"
738 "Host name to send the GSMTAP logging to (UDP port 4729)\n")
Harald Welteaa00f992016-12-02 15:30:02 +0100739{
Max2f153b52018-01-04 12:25:57 +0100740 const char *hostname = argc ? argv[0] : "127.0.0.1";
Harald Welteaa00f992016-12-02 15:30:02 +0100741 struct log_target *tgt;
742
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200743 log_tgt_mutex_lock();
Harald Welteaa00f992016-12-02 15:30:02 +0100744 tgt = log_target_find(LOG_TGT_TYPE_GSMTAP, hostname);
745 if (!tgt) {
746 tgt = log_target_create_gsmtap(hostname, GSMTAP_UDP_PORT,
747 host.app_info->name, false,
748 true);
749 if (!tgt) {
Max2f153b52018-01-04 12:25:57 +0100750 vty_out(vty, "%% Unable to create GSMTAP log for %s%s",
751 hostname, VTY_NEWLINE);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200752 RET_WITH_UNLOCK(CMD_WARNING);
Harald Welteaa00f992016-12-02 15:30:02 +0100753 }
754 log_add_target(tgt);
755 }
756
757 vty->index = tgt;
758 vty->node = CFG_LOG_NODE;
759
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200760 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welteaa00f992016-12-02 15:30:02 +0100761}
762
Harald Welte28222962011-02-18 20:37:04 +0100763DEFUN(cfg_log_stderr, cfg_log_stderr_cmd,
764 "log stderr",
765 LOG_STR "Logging via STDERR of the process\n")
766{
767 struct log_target *tgt;
768
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200769 log_tgt_mutex_lock();
Harald Welte28222962011-02-18 20:37:04 +0100770 tgt = log_target_find(LOG_TGT_TYPE_STDERR, NULL);
771 if (!tgt) {
772 tgt = log_target_create_stderr();
773 if (!tgt) {
774 vty_out(vty, "%% Unable to create stderr log%s",
775 VTY_NEWLINE);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200776 RET_WITH_UNLOCK(CMD_WARNING);
Harald Welte28222962011-02-18 20:37:04 +0100777 }
778 log_add_target(tgt);
779 }
780
781 vty->index = tgt;
782 vty->node = CFG_LOG_NODE;
783
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200784 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte28222962011-02-18 20:37:04 +0100785}
786
787DEFUN(cfg_no_log_stderr, cfg_no_log_stderr_cmd,
788 "no log stderr",
789 NO_STR LOG_STR "Logging via STDERR of the process\n")
790{
791 struct log_target *tgt;
792
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200793 log_tgt_mutex_lock();
Harald Welte28222962011-02-18 20:37:04 +0100794 tgt = log_target_find(LOG_TGT_TYPE_STDERR, NULL);
795 if (!tgt) {
796 vty_out(vty, "%% No stderr logging active%s", VTY_NEWLINE);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200797 RET_WITH_UNLOCK(CMD_WARNING);
Harald Welte28222962011-02-18 20:37:04 +0100798 }
799
800 log_target_destroy(tgt);
Harald Weltee4d9a2c2020-09-27 11:28:58 +0200801 osmo_stderr_target = NULL;
Harald Welte28222962011-02-18 20:37:04 +0100802
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200803 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte28222962011-02-18 20:37:04 +0100804}
805
806DEFUN(cfg_log_file, cfg_log_file_cmd,
807 "log file .FILENAME",
808 LOG_STR "Logging to text file\n" "Filename\n")
809{
810 const char *fname = argv[0];
811 struct log_target *tgt;
812
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200813 log_tgt_mutex_lock();
Harald Welte28222962011-02-18 20:37:04 +0100814 tgt = log_target_find(LOG_TGT_TYPE_FILE, fname);
815 if (!tgt) {
816 tgt = log_target_create_file(fname);
817 if (!tgt) {
818 vty_out(vty, "%% Unable to create file `%s'%s",
819 fname, VTY_NEWLINE);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200820 RET_WITH_UNLOCK(CMD_WARNING);
Harald Welte28222962011-02-18 20:37:04 +0100821 }
822 log_add_target(tgt);
823 }
824
825 vty->index = tgt;
826 vty->node = CFG_LOG_NODE;
827
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200828 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte28222962011-02-18 20:37:04 +0100829}
830
831
832DEFUN(cfg_no_log_file, cfg_no_log_file_cmd,
833 "no log file .FILENAME",
834 NO_STR LOG_STR "Logging to text file\n" "Filename\n")
835{
836 const char *fname = argv[0];
837 struct log_target *tgt;
838
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200839 log_tgt_mutex_lock();
Harald Welte28222962011-02-18 20:37:04 +0100840 tgt = log_target_find(LOG_TGT_TYPE_FILE, fname);
841 if (!tgt) {
842 vty_out(vty, "%% No such log file `%s'%s",
843 fname, VTY_NEWLINE);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200844 RET_WITH_UNLOCK(CMD_WARNING);
Harald Welte28222962011-02-18 20:37:04 +0100845 }
846
847 log_target_destroy(tgt);
848
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200849 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte28222962011-02-18 20:37:04 +0100850}
851
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000852DEFUN(cfg_log_alarms, cfg_log_alarms_cmd,
853 "log alarms <2-32700>",
854 LOG_STR "Logging alarms to osmo_strrb\n"
855 "Maximum number of messages to log\n")
856{
857 struct log_target *tgt;
858 unsigned int rbsize = atoi(argv[0]);
859
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200860
861 log_tgt_mutex_lock();
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000862 tgt = log_target_find(LOG_TGT_TYPE_STRRB, NULL);
863 if (tgt)
864 log_target_destroy(tgt);
865
866 tgt = log_target_create_rb(rbsize);
867 if (!tgt) {
868 vty_out(vty, "%% Unable to create osmo_strrb (size %u)%s",
869 rbsize, VTY_NEWLINE);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200870 RET_WITH_UNLOCK(CMD_WARNING);
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000871 }
872 log_add_target(tgt);
873
874 vty->index = tgt;
875 vty->node = CFG_LOG_NODE;
876
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200877 RET_WITH_UNLOCK(CMD_SUCCESS);
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000878}
879
880DEFUN(cfg_no_log_alarms, cfg_no_log_alarms_cmd,
881 "no log alarms",
882 NO_STR LOG_STR "Logging alarms to osmo_strrb\n")
883{
884 struct log_target *tgt;
885
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200886 log_tgt_mutex_lock();
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000887 tgt = log_target_find(LOG_TGT_TYPE_STRRB, NULL);
888 if (!tgt) {
889 vty_out(vty, "%% No osmo_strrb target found%s", VTY_NEWLINE);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200890 RET_WITH_UNLOCK(CMD_WARNING);
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000891 }
892
893 log_target_destroy(tgt);
894
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200895 RET_WITH_UNLOCK(CMD_SUCCESS);
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000896}
897
Harald Welte28222962011-02-18 20:37:04 +0100898static int config_write_log_single(struct vty *vty, struct log_target *tgt)
899{
Pau Espin Pedrolc21ba152019-08-02 20:32:34 +0200900 char level_buf[128];
Harald Welte28222962011-02-18 20:37:04 +0100901 int i;
Harald Welte28222962011-02-18 20:37:04 +0100902
903 switch (tgt->type) {
904 case LOG_TGT_TYPE_VTY:
905 return 1;
906 break;
907 case LOG_TGT_TYPE_STDERR:
908 vty_out(vty, "log stderr%s", VTY_NEWLINE);
909 break;
910 case LOG_TGT_TYPE_SYSLOG:
911#ifdef HAVE_SYSLOG_H
912 vty_out(vty, "log syslog %s%s",
913 get_value_string(sysl_level_names,
914 tgt->tgt_syslog.facility),
915 VTY_NEWLINE);
916#endif
917 break;
918 case LOG_TGT_TYPE_FILE:
919 vty_out(vty, "log file %s%s", tgt->tgt_file.fname, VTY_NEWLINE);
920 break;
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000921 case LOG_TGT_TYPE_STRRB:
922 vty_out(vty, "log alarms %zu%s",
923 log_target_rb_avail_size(tgt), VTY_NEWLINE);
924 break;
Harald Welteaa00f992016-12-02 15:30:02 +0100925 case LOG_TGT_TYPE_GSMTAP:
926 vty_out(vty, "log gsmtap %s%s",
927 tgt->tgt_gsmtap.hostname, VTY_NEWLINE);
928 break;
Harald Welte28222962011-02-18 20:37:04 +0100929 }
930
Harald Welte0d67f482018-09-25 20:16:14 +0200931 vty_out(vty, " logging filter all %u%s",
Neels Hofmeyr8b86cd72017-02-23 18:03:28 +0100932 tgt->filter_map & (1 << LOG_FLT_ALL) ? 1 : 0, VTY_NEWLINE);
Harald Weltefb84f322013-06-06 07:33:54 +0200933 /* save filters outside of libosmocore, i.e. in app code */
934 if (osmo_log_info->save_fn)
935 osmo_log_info->save_fn(vty, osmo_log_info, tgt);
Harald Welte2da47f12012-10-22 19:31:54 +0200936
Harald Welte0d67f482018-09-25 20:16:14 +0200937 vty_out(vty, " logging color %u%s", tgt->use_color ? 1 : 0,
Harald Welte28222962011-02-18 20:37:04 +0100938 VTY_NEWLINE);
Vadim Yanitskiy5c4b9852019-07-28 04:36:37 +0700939 vty_out(vty, " logging print category-hex %d%s",
940 tgt->print_category_hex ? 1 : 0, VTY_NEWLINE);
Harald Welte0d67f482018-09-25 20:16:14 +0200941 vty_out(vty, " logging print category %d%s",
Michael McTernan78933462015-03-20 15:29:25 +0100942 tgt->print_category ? 1 : 0, VTY_NEWLINE);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100943 if (tgt->print_ext_timestamp)
Harald Welte0d67f482018-09-25 20:16:14 +0200944 vty_out(vty, " logging print extended-timestamp 1%s", VTY_NEWLINE);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100945 else
Harald Welte0d67f482018-09-25 20:16:14 +0200946 vty_out(vty, " logging timestamp %u%s",
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100947 tgt->print_timestamp ? 1 : 0, VTY_NEWLINE);
Neels Hofmeyr886e5482018-01-16 01:49:37 +0100948 if (tgt->print_level)
Harald Welte0d67f482018-09-25 20:16:14 +0200949 vty_out(vty, " logging print level 1%s", VTY_NEWLINE);
950 vty_out(vty, " logging print file %s%s",
Neels Hofmeyr22772cc2018-02-06 00:52:08 +0100951 get_value_string(logging_print_file_args, tgt->print_filename2),
952 VTY_NEWLINE);
Harald Welte28222962011-02-18 20:37:04 +0100953
Neels Hofmeyr098038a2018-09-11 23:49:13 +0200954 if (tgt->loglevel) {
955 const char *level_str = get_value_string_or_null(loglevel_strs, tgt->loglevel);
Pau Espin Pedrolc21ba152019-08-02 20:32:34 +0200956 if (!level_str) {
Neels Hofmeyr9540c242018-09-12 00:20:50 +0200957 vty_out(vty, "%% Invalid log level %u for 'force-all'%s",
958 tgt->loglevel, VTY_NEWLINE);
Pau Espin Pedrolc21ba152019-08-02 20:32:34 +0200959 } else {
960 osmo_str_tolower_buf(level_buf, sizeof(level_buf), level_str);
961 vty_out(vty, " logging level force-all %s%s", level_buf, VTY_NEWLINE);
962 }
Neels Hofmeyr098038a2018-09-11 23:49:13 +0200963 }
Harald Welte28222962011-02-18 20:37:04 +0100964
965 for (i = 0; i < osmo_log_info->num_cat; i++) {
966 const struct log_category *cat = &tgt->categories[i];
Pau Espin Pedrolc21ba152019-08-02 20:32:34 +0200967 char cat_name[128];
Neels Hofmeyr098038a2018-09-11 23:49:13 +0200968 const char *level_str;
Harald Welte28222962011-02-18 20:37:04 +0100969
Harald Welte1a02cfc2013-03-19 10:37:39 +0100970 /* skip empty entries in the array */
971 if (!osmo_log_info->cat[i].name)
972 continue;
973
Pau Espin Pedrolc21ba152019-08-02 20:32:34 +0200974 osmo_str_tolower_buf(cat_name, sizeof(cat_name), osmo_log_info->cat[i].name + 1);
Neels Hofmeyr098038a2018-09-11 23:49:13 +0200975
976 level_str = get_value_string_or_null(loglevel_strs, cat->loglevel);
977 if (!level_str) {
978 vty_out(vty, "%% Invalid log level %u for %s%s", cat->loglevel, cat_name,
979 VTY_NEWLINE);
980 continue;
981 }
982
Pau Espin Pedrolc21ba152019-08-02 20:32:34 +0200983 osmo_str_tolower_buf(level_buf, sizeof(level_buf), level_str);
Harald Welte0d67f482018-09-25 20:16:14 +0200984 vty_out(vty, " logging level %s", cat_name);
Pau Espin Pedrolc21ba152019-08-02 20:32:34 +0200985 vty_out(vty, " %s%s", level_buf, VTY_NEWLINE);
Harald Welte28222962011-02-18 20:37:04 +0100986 }
987
Harald Welte28222962011-02-18 20:37:04 +0100988 return 1;
989}
990
991static int config_write_log(struct vty *vty)
992{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200993 log_tgt_mutex_lock();
Harald Welte28222962011-02-18 20:37:04 +0100994 struct log_target *dbg = vty->index;
995
996 llist_for_each_entry(dbg, &osmo_log_target_list, entry)
997 config_write_log_single(vty, dbg);
998
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200999 log_tgt_mutex_unlock();
Harald Welte28222962011-02-18 20:37:04 +01001000 return 1;
1001}
1002
Harald Welte11eb4b52018-06-09 17:41:31 +02001003static int log_deprecated_func(struct cmd_element *cmd, struct vty *vty, int argc, const char *argv[])
1004{
1005 vty_out(vty, "%% Ignoring deprecated '%s'%s", cmd->string, VTY_NEWLINE);
Vadim Yanitskiy4abda9e2019-11-21 00:19:36 +07001006 return CMD_SUCCESS; /* Otherwise the process would terminate */
Harald Welte11eb4b52018-06-09 17:41:31 +02001007}
1008
1009void logging_vty_add_deprecated_subsys(void *ctx, const char *name)
1010{
1011 struct cmd_element *cmd = talloc_zero(ctx, struct cmd_element);
1012 OSMO_ASSERT(cmd);
Vadim Yanitskiy75c242e2019-11-21 00:06:53 +07001013 cmd->string = talloc_asprintf(cmd, "logging level %s " LOG_LEVEL_ARGS, name);
Harald Welte11eb4b52018-06-09 17:41:31 +02001014 cmd->func = log_deprecated_func;
Neels Hofmeyrba0762d2018-09-10 13:56:03 +02001015 cmd->doc = LEVEL_STR
Harald Welte11eb4b52018-06-09 17:41:31 +02001016 "Deprecated Category\n";
1017 cmd->attr = CMD_ATTR_DEPRECATED;
1018
1019 install_element(CFG_LOG_NODE, cmd);
1020}
1021
Neels Hofmeyrd0b3b9e2019-07-29 19:28:08 +02001022/* logp (<categories>) (debug|...|fatal) .LOGMESSAGE*/
1023DEFUN(vty_logp,
1024 vty_logp_cmd,
1025 NULL, /* cmdstr is dynamically set in gen_vty_logp_cmd_strs(). */
1026 NULL) /* same thing for helpstr. */
1027{
1028 int category = log_parse_category(argv[0]);
1029 int level = log_parse_level(argv[1]);
1030 char *str = argv_concat(argv, argc, 2);
1031 LOGP(category, level, "%s\n", str);
1032 return CMD_SUCCESS;
1033}
1034
1035static void gen_vty_logp_cmd_strs(struct cmd_element *cmd)
1036{
1037 char *cmd_str = NULL;
1038 char *doc_str = NULL;
1039
1040 assert_loginfo(__func__);
1041
1042 OSMO_ASSERT(cmd->string == NULL);
1043 OSMO_ASSERT(cmd->doc == NULL);
1044
1045 osmo_talloc_asprintf(tall_log_ctx, cmd_str, "logp (");
1046 osmo_talloc_asprintf(tall_log_ctx, doc_str,
1047 "Print a message on all log outputs; useful for placing markers in test logs\n");
1048 add_category_strings(&cmd_str, &doc_str, osmo_log_info);
1049 osmo_talloc_asprintf(tall_log_ctx, cmd_str, ") %s", LOG_LEVEL_ARGS);
1050 osmo_talloc_asprintf(tall_log_ctx, doc_str, "%s", LOG_LEVEL_STRS);
1051
1052 osmo_talloc_asprintf(tall_log_ctx, cmd_str, " .LOGMESSAGE");
1053 osmo_talloc_asprintf(tall_log_ctx, doc_str,
1054 "Arbitrary message to log on given category and log level\n");
1055
Harald Weltebebec212020-07-15 12:21:29 +02001056 talloc_set_name_const(cmd_str, "vty_logp_cmd_str");
1057 talloc_set_name_const(doc_str, "vty_logp_doc_str");
1058
Neels Hofmeyrd0b3b9e2019-07-29 19:28:08 +02001059 cmd->string = cmd_str;
1060 cmd->doc = doc_str;
1061}
1062
Harald Welte8c648252017-10-16 15:17:03 +02001063/*! Register logging related commands to the VTY. Call this once from
1064 * your application if you want to support those commands. */
Maxc65c5b42017-03-15 13:20:23 +01001065void logging_vty_add_cmds()
Harald Welte3fb0b6f2010-05-19 19:02:52 +02001066{
1067 install_element_ve(&enable_logging_cmd);
1068 install_element_ve(&disable_logging_cmd);
1069 install_element_ve(&logging_fltr_all_cmd);
1070 install_element_ve(&logging_use_clr_cmd);
1071 install_element_ve(&logging_prnt_timestamp_cmd);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +01001072 install_element_ve(&logging_prnt_ext_timestamp_cmd);
1073 install_element_ve(&logging_prnt_cat_cmd);
Neels Hofmeyrbd7bd392018-01-16 01:52:29 +01001074 install_element_ve(&logging_prnt_cat_hex_cmd);
Neels Hofmeyr886e5482018-01-16 01:49:37 +01001075 install_element_ve(&logging_prnt_level_cmd);
Neels Hofmeyrc6fd2452018-01-16 01:57:38 +01001076 install_element_ve(&logging_prnt_file_cmd);
Harald Welte3fb0b6f2010-05-19 19:02:52 +02001077 install_element_ve(&logging_set_category_mask_cmd);
Holger Hans Peter Freyther146d1d32011-10-03 23:15:41 +02001078 install_element_ve(&logging_set_category_mask_old_cmd);
Pablo Neira Ayuso04139f12011-03-09 13:05:08 +01001079
Neels Hofmeyr9540c242018-09-12 00:20:50 +02001080 /* logging level (<categories>) (debug|...|fatal) */
Neels Hofmeyrba0762d2018-09-10 13:56:03 +02001081 gen_logging_level_cmd_strs(&logging_level_cmd,
Neels Hofmeyr9540c242018-09-12 00:20:50 +02001082 LOG_LEVEL_ARGS,
Neels Hofmeyr7e0686c2018-09-10 20:58:52 +02001083 LOG_LEVEL_STRS);
Neels Hofmeyr9540c242018-09-12 00:20:50 +02001084 /* logging level (<categories>) everything */
Neels Hofmeyr7e0686c2018-09-10 20:58:52 +02001085 gen_logging_level_cmd_strs(&deprecated_logging_level_everything_cmd,
1086 "everything", EVERYTHING_STR);
Neels Hofmeyrba0762d2018-09-10 13:56:03 +02001087
Harald Welte3fb0b6f2010-05-19 19:02:52 +02001088 install_element_ve(&logging_level_cmd);
Neels Hofmeyr28fc0782018-09-12 02:32:02 +02001089 install_element_ve(&logging_level_set_all_cmd);
Neels Hofmeyr9540c242018-09-12 00:20:50 +02001090 install_element_ve(&logging_level_force_all_cmd);
1091 install_element_ve(&no_logging_level_force_all_cmd);
Neels Hofmeyr7e0686c2018-09-10 20:58:52 +02001092 install_element_ve(&deprecated_logging_level_everything_cmd);
Neels Hofmeyr9540c242018-09-12 00:20:50 +02001093 install_element_ve(&deprecated_logging_level_all_cmd);
1094 install_element_ve(&deprecated_logging_level_all_everything_cmd);
Harald Welte28222962011-02-18 20:37:04 +01001095
Neels Hofmeyrd0b3b9e2019-07-29 19:28:08 +02001096 gen_vty_logp_cmd_strs(&vty_logp_cmd);
1097 install_element_ve(&vty_logp_cmd);
1098
Pau Espin Pedrol0c2a46d2019-08-20 10:39:05 +02001099 install_element_ve(&show_logging_vty_cmd);
1100 install_element_ve(&show_alarms_cmd);
1101
Harald Welte28222962011-02-18 20:37:04 +01001102 install_node(&cfg_log_node, config_write_log);
Harald Weltea62648b2011-02-18 21:03:27 +01001103 install_element(CFG_LOG_NODE, &logging_fltr_all_cmd);
1104 install_element(CFG_LOG_NODE, &logging_use_clr_cmd);
1105 install_element(CFG_LOG_NODE, &logging_prnt_timestamp_cmd);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +01001106 install_element(CFG_LOG_NODE, &logging_prnt_ext_timestamp_cmd);
1107 install_element(CFG_LOG_NODE, &logging_prnt_cat_cmd);
Neels Hofmeyrbd7bd392018-01-16 01:52:29 +01001108 install_element(CFG_LOG_NODE, &logging_prnt_cat_hex_cmd);
Neels Hofmeyr886e5482018-01-16 01:49:37 +01001109 install_element(CFG_LOG_NODE, &logging_prnt_level_cmd);
Neels Hofmeyrc6fd2452018-01-16 01:57:38 +01001110 install_element(CFG_LOG_NODE, &logging_prnt_file_cmd);
Harald Weltea62648b2011-02-18 21:03:27 +01001111 install_element(CFG_LOG_NODE, &logging_level_cmd);
Neels Hofmeyr28fc0782018-09-12 02:32:02 +02001112 install_element(CFG_LOG_NODE, &logging_level_set_all_cmd);
Neels Hofmeyr9540c242018-09-12 00:20:50 +02001113 install_element(CFG_LOG_NODE, &logging_level_force_all_cmd);
1114 install_element(CFG_LOG_NODE, &no_logging_level_force_all_cmd);
Neels Hofmeyr7e0686c2018-09-10 20:58:52 +02001115 install_element(CFG_LOG_NODE, &deprecated_logging_level_everything_cmd);
Neels Hofmeyr9540c242018-09-12 00:20:50 +02001116 install_element(CFG_LOG_NODE, &deprecated_logging_level_all_cmd);
1117 install_element(CFG_LOG_NODE, &deprecated_logging_level_all_everything_cmd);
Harald Welte28222962011-02-18 20:37:04 +01001118
1119 install_element(CONFIG_NODE, &cfg_log_stderr_cmd);
1120 install_element(CONFIG_NODE, &cfg_no_log_stderr_cmd);
1121 install_element(CONFIG_NODE, &cfg_log_file_cmd);
1122 install_element(CONFIG_NODE, &cfg_no_log_file_cmd);
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +00001123 install_element(CONFIG_NODE, &cfg_log_alarms_cmd);
1124 install_element(CONFIG_NODE, &cfg_no_log_alarms_cmd);
Harald Welte28222962011-02-18 20:37:04 +01001125#ifdef HAVE_SYSLOG_H
1126 install_element(CONFIG_NODE, &cfg_log_syslog_cmd);
1127 install_element(CONFIG_NODE, &cfg_log_syslog_local_cmd);
1128 install_element(CONFIG_NODE, &cfg_no_log_syslog_cmd);
1129#endif
Harald Welteaa00f992016-12-02 15:30:02 +01001130 install_element(CONFIG_NODE, &cfg_log_gsmtap_cmd);
Harald Welte3fb0b6f2010-05-19 19:02:52 +02001131}