blob: c51b437356a539fd1fcaa770ea256290e13dbb36 [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 Welte3fb0b6f2010-05-19 19:02:52 +020036
37#include <osmocom/vty/command.h>
38#include <osmocom/vty/buffer.h>
39#include <osmocom/vty/vty.h>
40#include <osmocom/vty/telnet_interface.h>
41#include <osmocom/vty/logging.h>
42
Harald Welte28222962011-02-18 20:37:04 +010043#define LOG_STR "Configure logging sub-system\n"
Neels Hofmeyrba0762d2018-09-10 13:56:03 +020044#define LEVEL_STR "Set the log level for a specified category\n"
45
Neels Hofmeyr9540c242018-09-12 00:20:50 +020046#define CATEGORY_ALL_STR "Deprecated alias for 'force-all'\n"
47#define FORCE_ALL_STR \
48 "Globally force all logging categories to a specific level. This is released by the" \
49 " 'no logging level force-all' command. Note: any 'logging level <category> <level>'" \
50 " commands will have no visible effect after this, until the forced level is released.\n"
51#define NO_FORCE_ALL_STR \
52 "Release any globally forced log level set with 'logging level force-all <level>'\n"
Neels Hofmeyrba0762d2018-09-10 13:56:03 +020053
Neels Hofmeyr9540c242018-09-12 00:20:50 +020054#define LOG_LEVEL_ARGS "(debug|info|notice|error|fatal)"
Neels Hofmeyrba0762d2018-09-10 13:56:03 +020055#define LOG_LEVEL_STRS \
56 "Log debug messages and higher levels\n" \
57 "Log informational messages and higher levels\n" \
58 "Log noticeable messages and higher levels\n" \
59 "Log error messages and higher levels\n" \
60 "Log only fatal messages\n"
61
Neels Hofmeyr9540c242018-09-12 00:20:50 +020062#define EVERYTHING_STR "Deprecated alias for 'no logging level force-all'\n"
Harald Welte28222962011-02-18 20:37:04 +010063
Harald Welte8c648252017-10-16 15:17:03 +020064/*! \file logging_vty.c
Neels Hofmeyr87e45502017-06-20 00:17:59 +020065 * Configuration of logging from VTY
Harald Welte96e2a002017-06-12 21:44:18 +020066 *
Harald Welte8c648252017-10-16 15:17:03 +020067 * This module implements
68 * - functions that permit configuration of the libosmocore logging
69 * framework from VTY commands in the configure -> logging node.
70 *
71 * - functions that permit logging *to* a VTY session. Basically each
72 * VTY session gets its own log target, with configurable
73 * per-subsystem log levels. This is performed internally via the
74 * \ref log_target_create_vty function.
75 *
76 * You have to call \ref logging_vty_add_cmds from your application
77 * once to enable both of the above.
78 *
Harald Welte96e2a002017-06-12 21:44:18 +020079 */
80
Harald Welte76e72ab2011-02-17 15:52:39 +010081static void _vty_output(struct log_target *tgt,
82 unsigned int level, const char *line)
Harald Welte3fb0b6f2010-05-19 19:02:52 +020083{
84 struct vty *vty = tgt->tgt_vty.vty;
85 vty_out(vty, "%s", line);
86 /* This is an ugly hack, but there is no easy way... */
87 if (strchr(line, '\n'))
88 vty_out(vty, "\r");
89}
90
91struct log_target *log_target_create_vty(struct vty *vty)
92{
93 struct log_target *target;
94
95 target = log_target_create();
96 if (!target)
97 return NULL;
98
99 target->tgt_vty.vty = vty;
100 target->output = _vty_output;
101 return target;
102}
103
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200104/*! Get tgt with log lock acquired, return and release lock with warning if tgt
105 * is not found. Lock must be released later with log_tgt_mutex_unlock().
106 */
107#define ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt) \
108 do { \
109 log_tgt_mutex_lock(); \
110 tgt = osmo_log_vty2tgt(vty); \
111 if (!(tgt)) { \
112 log_tgt_mutex_unlock(); \
113 return CMD_WARNING; \
114 } \
115 } while (0)
116
117#define RET_WITH_UNLOCK(ret) \
118 do { \
119 log_tgt_mutex_unlock(); \
120 return (ret); \
121 } while (0)
122
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200123DEFUN(enable_logging,
124 enable_logging_cmd,
125 "logging enable",
126 LOGGING_STR
127 "Enables logging to this vty\n")
128{
129 struct telnet_connection *conn;
130
131 conn = (struct telnet_connection *) vty->priv;
132 if (conn->dbg) {
133 vty_out(vty, "Logging already enabled.%s", VTY_NEWLINE);
134 return CMD_WARNING;
135 }
136
137 conn->dbg = log_target_create_vty(vty);
138 if (!conn->dbg)
139 return CMD_WARNING;
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200140 log_tgt_mutex_lock();
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200141 log_add_target(conn->dbg);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200142 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200143}
144
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200145/*! Get log target associated to VTY console.
146 * \param[in] vty Log target type
147 * \returns Log target (if logging enabled), NULL otherwise
148 * Must be called with mutex osmo_log_tgt_mutex held, see log_tgt_mutex_lock.
149 */
Harald Weltea62648b2011-02-18 21:03:27 +0100150struct log_target *osmo_log_vty2tgt(struct vty *vty)
151{
152 struct telnet_connection *conn;
153
154 if (vty->node == CFG_LOG_NODE)
155 return vty->index;
156
157
158 conn = (struct telnet_connection *) vty->priv;
159 if (!conn->dbg)
160 vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE);
161
162 return conn->dbg;
163}
164
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200165DEFUN(logging_fltr_all,
166 logging_fltr_all_cmd,
167 "logging filter all (0|1)",
168 LOGGING_STR FILTER_STR
169 "Do you want to log all messages?\n"
170 "Only print messages matched by other filters\n"
171 "Bypass filter and print all messages\n")
172{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200173 struct log_target *tgt;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200174
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200175 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200176
Harald Weltea62648b2011-02-18 21:03:27 +0100177 log_set_all_filter(tgt, atoi(argv[0]));
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200178 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200179}
180
181DEFUN(logging_use_clr,
182 logging_use_clr_cmd,
183 "logging color (0|1)",
184 LOGGING_STR "Configure color-printing for log messages\n"
185 "Don't use color for printing messages\n"
186 "Use color for printing messages\n")
187{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200188 struct log_target *tgt;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200189
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200190 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200191
Harald Weltea62648b2011-02-18 21:03:27 +0100192 log_set_use_color(tgt, atoi(argv[0]));
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200193 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200194}
195
196DEFUN(logging_prnt_timestamp,
197 logging_prnt_timestamp_cmd,
198 "logging timestamp (0|1)",
199 LOGGING_STR "Configure log message timestamping\n"
200 "Don't prefix each log message\n"
201 "Prefix each log message with current timestamp\n")
202{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200203 struct log_target *tgt;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200204
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200205 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200206
Harald Weltea62648b2011-02-18 21:03:27 +0100207 log_set_print_timestamp(tgt, atoi(argv[0]));
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200208 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200209}
210
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100211DEFUN(logging_prnt_ext_timestamp,
212 logging_prnt_ext_timestamp_cmd,
213 "logging print extended-timestamp (0|1)",
214 LOGGING_STR "Log output settings\n"
215 "Configure log message timestamping\n"
216 "Don't prefix each log message\n"
217 "Prefix each log message with current timestamp with YYYYMMDDhhmmssnnn\n")
218{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200219 struct log_target *tgt;
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100220
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200221 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100222
223 log_set_print_extended_timestamp(tgt, atoi(argv[0]));
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200224 RET_WITH_UNLOCK(CMD_SUCCESS);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100225}
226
227DEFUN(logging_prnt_cat,
228 logging_prnt_cat_cmd,
229 "logging print category (0|1)",
230 LOGGING_STR "Log output settings\n"
231 "Configure log message\n"
232 "Don't prefix each log message\n"
233 "Prefix each log message with category/subsystem name\n")
234{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200235 struct log_target *tgt;
236 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100237
238 log_set_print_category(tgt, atoi(argv[0]));
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200239 RET_WITH_UNLOCK(CMD_SUCCESS);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100240}
241
Neels Hofmeyrbd7bd392018-01-16 01:52:29 +0100242DEFUN(logging_prnt_cat_hex,
243 logging_prnt_cat_hex_cmd,
244 "logging print category-hex (0|1)",
245 LOGGING_STR "Log output settings\n"
246 "Configure log message\n"
247 "Don't prefix each log message\n"
248 "Prefix each log message with category/subsystem nr in hex ('<000b>')\n")
249{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200250 struct log_target *tgt;
Neels Hofmeyrbd7bd392018-01-16 01:52:29 +0100251
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200252 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
Neels Hofmeyrbd7bd392018-01-16 01:52:29 +0100253
254 log_set_print_category_hex(tgt, atoi(argv[0]));
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200255 RET_WITH_UNLOCK(CMD_SUCCESS);
Neels Hofmeyrbd7bd392018-01-16 01:52:29 +0100256}
257
Neels Hofmeyr886e5482018-01-16 01:49:37 +0100258DEFUN(logging_prnt_level,
259 logging_prnt_level_cmd,
260 "logging print level (0|1)",
261 LOGGING_STR "Log output settings\n"
262 "Configure log message\n"
263 "Don't prefix each log message\n"
264 "Prefix each log message with the log level name\n")
265{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200266 struct log_target *tgt;
Neels Hofmeyr886e5482018-01-16 01:49:37 +0100267
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200268 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
Neels Hofmeyr886e5482018-01-16 01:49:37 +0100269
270 log_set_print_level(tgt, atoi(argv[0]));
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200271 RET_WITH_UNLOCK(CMD_SUCCESS);
Neels Hofmeyr886e5482018-01-16 01:49:37 +0100272}
273
Neels Hofmeyr22772cc2018-02-06 00:52:08 +0100274static const struct value_string logging_print_file_args[] = {
275 { LOG_FILENAME_NONE, "0" },
276 { LOG_FILENAME_PATH, "1" },
277 { LOG_FILENAME_BASENAME, "basename" },
278 { 0, NULL }
279};
280
Neels Hofmeyrc6fd2452018-01-16 01:57:38 +0100281DEFUN(logging_prnt_file,
282 logging_prnt_file_cmd,
Neels Hofmeyr77ae45d2018-08-27 20:32:36 +0200283 "logging print file (0|1|basename) [last]",
Neels Hofmeyrc6fd2452018-01-16 01:57:38 +0100284 LOGGING_STR "Log output settings\n"
285 "Configure log message\n"
286 "Don't prefix each log message\n"
287 "Prefix each log message with the source file and line\n"
Neels Hofmeyr77ae45d2018-08-27 20:32:36 +0200288 "Prefix each log message with the source file's basename (strip leading paths) and line\n"
289 "Log source file info at the end of a log line. If omitted, log source file info just"
290 " before the log text.\n")
Neels Hofmeyrc6fd2452018-01-16 01:57:38 +0100291{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200292 struct log_target *tgt;
Neels Hofmeyrc6fd2452018-01-16 01:57:38 +0100293
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200294 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
Neels Hofmeyrc6fd2452018-01-16 01:57:38 +0100295
Neels Hofmeyr22772cc2018-02-06 00:52:08 +0100296 log_set_print_filename2(tgt, get_string_value(logging_print_file_args, argv[0]));
Neels Hofmeyr77ae45d2018-08-27 20:32:36 +0200297 if (argc > 1)
298 log_set_print_filename_pos(tgt, LOG_FILENAME_POS_LINE_END);
299 else
300 log_set_print_filename_pos(tgt, LOG_FILENAME_POS_HEADER_END);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200301 RET_WITH_UNLOCK(CMD_SUCCESS);
Neels Hofmeyrc6fd2452018-01-16 01:57:38 +0100302}
303
Neels Hofmeyrba0762d2018-09-10 13:56:03 +0200304static void add_category_strings(char **cmd_str_p, char **doc_str_p,
305 const struct log_info *categories)
306{
Pau Espin Pedrolc21ba152019-08-02 20:32:34 +0200307 char buf[128];
Neels Hofmeyrba0762d2018-09-10 13:56:03 +0200308 int i;
309 for (i = 0; i < categories->num_cat; i++) {
310 if (categories->cat[i].name == NULL)
311 continue;
312 /* skip the leading 'D' in each category name, hence '+ 1' */
Pau Espin Pedrolc21ba152019-08-02 20:32:34 +0200313 osmo_str_tolower_buf(buf, sizeof(buf), categories->cat[i].name + 1);
Neels Hofmeyrba0762d2018-09-10 13:56:03 +0200314 osmo_talloc_asprintf(tall_log_ctx, *cmd_str_p, "%s%s",
Pau Espin Pedrolc21ba152019-08-02 20:32:34 +0200315 i ? "|" : "", buf);
Neels Hofmeyrba0762d2018-09-10 13:56:03 +0200316 osmo_talloc_asprintf(tall_log_ctx, *doc_str_p, "%s\n",
317 categories->cat[i].description);
318 }
319}
320
321static void gen_logging_level_cmd_strs(struct cmd_element *cmd,
322 const char *level_args, const char *level_strs)
323{
324 char *cmd_str = NULL;
325 char *doc_str = NULL;
326
327 assert_loginfo(__func__);
328
329 OSMO_ASSERT(cmd->string == NULL);
330 OSMO_ASSERT(cmd->doc == NULL);
331
Neels Hofmeyr9540c242018-09-12 00:20:50 +0200332 osmo_talloc_asprintf(tall_log_ctx, cmd_str, "logging level (");
Neels Hofmeyrba0762d2018-09-10 13:56:03 +0200333 osmo_talloc_asprintf(tall_log_ctx, doc_str,
334 LOGGING_STR
Neels Hofmeyr9540c242018-09-12 00:20:50 +0200335 LEVEL_STR);
Neels Hofmeyrba0762d2018-09-10 13:56:03 +0200336 add_category_strings(&cmd_str, &doc_str, osmo_log_info);
337 osmo_talloc_asprintf(tall_log_ctx, cmd_str, ") %s", level_args);
338 osmo_talloc_asprintf(tall_log_ctx, doc_str, "%s", level_strs);
339
340 cmd->string = cmd_str;
341 cmd->doc = doc_str;
342}
343
Neels Hofmeyr9540c242018-09-12 00:20:50 +0200344/* logging level (<categories>) (debug|...|fatal) */
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200345DEFUN(logging_level,
346 logging_level_cmd,
Pablo Neira Ayuso04139f12011-03-09 13:05:08 +0100347 NULL, /* cmdstr is dynamically set in logging_vty_add_cmds(). */
348 NULL) /* same thing for helpstr. */
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200349{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200350 struct log_target *tgt;
Harald Weltea62648b2011-02-18 21:03:27 +0100351 int category = log_parse_category(argv[0]);
352 int level = log_parse_level(argv[1]);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200353
Harald Weltea62648b2011-02-18 21:03:27 +0100354 if (level < 0) {
355 vty_out(vty, "Invalid level `%s'%s", argv[1], VTY_NEWLINE);
Pau Espin Pedrol57d11182020-01-02 16:21:14 +0100356 return CMD_WARNING;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200357 }
358
Harald Weltea62648b2011-02-18 21:03:27 +0100359 if (category < 0) {
360 vty_out(vty, "Invalid category `%s'%s", argv[0], VTY_NEWLINE);
Pau Espin Pedrol57d11182020-01-02 16:21:14 +0100361 return CMD_WARNING;
Harald Weltea62648b2011-02-18 21:03:27 +0100362 }
363
Pau Espin Pedrol57d11182020-01-02 16:21:14 +0100364 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
365
Harald Weltea62648b2011-02-18 21:03:27 +0100366 tgt->categories[category].enabled = 1;
367 tgt->categories[category].loglevel = level;
368
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200369 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200370}
371
Neels Hofmeyr28fc0782018-09-12 02:32:02 +0200372DEFUN(logging_level_set_all, logging_level_set_all_cmd,
373 "logging level set-all " LOG_LEVEL_ARGS,
374 LOGGING_STR LEVEL_STR
375 "Once-off set all categories to the given log level. There is no single command"
376 " to take back these changes -- each category is set to the given level, period.\n"
377 LOG_LEVEL_STRS)
378{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200379 struct log_target *tgt;
Neels Hofmeyr28fc0782018-09-12 02:32:02 +0200380 int level = log_parse_level(argv[0]);
381 int i;
Neels Hofmeyrea6f5192018-10-01 15:51:18 +0200382
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200383 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
Neels Hofmeyrea6f5192018-10-01 15:51:18 +0200384
Neels Hofmeyr28fc0782018-09-12 02:32:02 +0200385 for (i = 0; i < osmo_log_info->num_cat; i++) {
386 struct log_category *cat = &tgt->categories[i];
387 /* skip empty entries in the array */
388 if (!osmo_log_info->cat[i].name)
389 continue;
390
391 cat->enabled = 1;
392 cat->loglevel = level;
393 }
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200394 RET_WITH_UNLOCK(CMD_SUCCESS);
Neels Hofmeyr28fc0782018-09-12 02:32:02 +0200395}
396
Neels Hofmeyr9540c242018-09-12 00:20:50 +0200397/* logging level (<categories>) everything */
Neels Hofmeyr7e0686c2018-09-10 20:58:52 +0200398DEFUN_DEPRECATED(deprecated_logging_level_everything, deprecated_logging_level_everything_cmd,
399 NULL, /* cmdstr is dynamically set in logging_vty_add_cmds(). */
400 NULL) /* same thing for helpstr. */
401{
402 vty_out(vty, "%% Ignoring deprecated logging level 'everything' keyword%s", VTY_NEWLINE);
403 return CMD_SUCCESS;
404}
405
Neels Hofmeyr9540c242018-09-12 00:20:50 +0200406DEFUN(logging_level_force_all, logging_level_force_all_cmd,
407 "logging level force-all " LOG_LEVEL_ARGS,
408 LOGGING_STR LEVEL_STR FORCE_ALL_STR LOG_LEVEL_STRS)
409{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200410 struct log_target *tgt;
Neels Hofmeyr9540c242018-09-12 00:20:50 +0200411 int level = log_parse_level(argv[0]);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200412
413 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
414
Neels Hofmeyr9540c242018-09-12 00:20:50 +0200415 log_set_log_level(tgt, level);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200416 RET_WITH_UNLOCK(CMD_SUCCESS);
Neels Hofmeyr9540c242018-09-12 00:20:50 +0200417}
418
419DEFUN(no_logging_level_force_all, no_logging_level_force_all_cmd,
420 "no logging level force-all",
421 NO_STR LOGGING_STR LEVEL_STR NO_FORCE_ALL_STR)
422{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200423 struct log_target *tgt;
424
425 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
426
Neels Hofmeyr9540c242018-09-12 00:20:50 +0200427 log_set_log_level(tgt, 0);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200428 RET_WITH_UNLOCK(CMD_SUCCESS);
Neels Hofmeyr9540c242018-09-12 00:20:50 +0200429}
430
431/* 'logging level all (debug|...|fatal)' */
432ALIAS_DEPRECATED(logging_level_force_all, deprecated_logging_level_all_cmd,
433 "logging level all " LOG_LEVEL_ARGS,
434 LOGGING_STR LEVEL_STR CATEGORY_ALL_STR LOG_LEVEL_STRS);
435
436/* 'logging level all everything' */
437ALIAS_DEPRECATED(no_logging_level_force_all, deprecated_logging_level_all_everything_cmd,
438 "logging level all everything",
439 LOGGING_STR LEVEL_STR CATEGORY_ALL_STR EVERYTHING_STR);
440
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200441DEFUN(logging_set_category_mask,
442 logging_set_category_mask_cmd,
Holger Hans Peter Freyther146d1d32011-10-03 23:15:41 +0200443 "logging set-log-mask MASK",
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200444 LOGGING_STR
Holger Hans Peter Freyther146d1d32011-10-03 23:15:41 +0200445 "Set the logmask of this logging target\n"
Neels Hofmeyr84ea2e02017-12-09 05:53:18 +0100446 "List of logging categories to log, e.g. 'abc:mno:xyz'. Available log categories depend on the specific"
447 " application, refer to the 'logging level' command. Optionally add individual log levels like"
448 " 'abc,1:mno,3:xyz,5', where the level numbers are"
449 " " OSMO_STRINGIFY(LOGL_DEBUG) "=" OSMO_STRINGIFY_VAL(LOGL_DEBUG)
450 " " OSMO_STRINGIFY(LOGL_INFO) "=" OSMO_STRINGIFY_VAL(LOGL_INFO)
451 " " OSMO_STRINGIFY(LOGL_NOTICE) "=" OSMO_STRINGIFY_VAL(LOGL_NOTICE)
452 " " OSMO_STRINGIFY(LOGL_ERROR) "=" OSMO_STRINGIFY_VAL(LOGL_ERROR)
453 " " OSMO_STRINGIFY(LOGL_FATAL) "=" OSMO_STRINGIFY_VAL(LOGL_FATAL)
454 "\n")
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200455{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200456 struct log_target *tgt;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200457
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200458 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200459
Harald Weltea62648b2011-02-18 21:03:27 +0100460 log_parse_category_mask(tgt, argv[0]);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200461 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200462}
463
Holger Hans Peter Freyther146d1d32011-10-03 23:15:41 +0200464ALIAS_DEPRECATED(logging_set_category_mask,
465 logging_set_category_mask_old_cmd,
466 "logging set log mask MASK",
467 LOGGING_STR
468 "Decide which categories to output.\n"
Neels Hofmeyr84ea2e02017-12-09 05:53:18 +0100469 "Log commands\n" "Mask commands\n"
470 "'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 +0200471
472
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200473DEFUN(diable_logging,
474 disable_logging_cmd,
475 "logging disable",
476 LOGGING_STR
477 "Disables logging to this vty\n")
478{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200479 struct log_target *tgt;
Harald Weltea62648b2011-02-18 21:03:27 +0100480 struct telnet_connection *conn = (struct telnet_connection *) vty->priv;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200481
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200482 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200483
Harald Weltea62648b2011-02-18 21:03:27 +0100484 log_del_target(tgt);
485 talloc_free(tgt);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200486 conn->dbg = NULL;
Harald Weltea62648b2011-02-18 21:03:27 +0100487
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200488 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200489}
490
491static void vty_print_logtarget(struct vty *vty, const struct log_info *info,
492 const struct log_target *tgt)
493{
494 unsigned int i;
495
496 vty_out(vty, " Global Loglevel: %s%s",
497 log_level_str(tgt->loglevel), VTY_NEWLINE);
498 vty_out(vty, " Use color: %s, Print Timestamp: %s%s",
499 tgt->use_color ? "On" : "Off",
500 tgt->print_timestamp ? "On" : "Off", VTY_NEWLINE);
501
502 vty_out(vty, " Log Level specific information:%s", VTY_NEWLINE);
503
504 for (i = 0; i < info->num_cat; i++) {
505 const struct log_category *cat = &tgt->categories[i];
Daniel Willmann55363a92016-11-15 10:05:51 +0100506 /* Skip categories that were not initialized */
507 if (!info->cat[i].name)
508 continue;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200509 vty_out(vty, " %-10s %-10s %-8s %s%s",
510 info->cat[i].name+1, log_level_str(cat->loglevel),
511 cat->enabled ? "Enabled" : "Disabled",
512 info->cat[i].description,
513 VTY_NEWLINE);
514 }
Harald Welte6d2d4d62013-03-10 09:53:24 +0000515
516 vty_out(vty, " Log Filter 'ALL': %s%s",
Neels Hofmeyr8b86cd72017-02-23 18:03:28 +0100517 tgt->filter_map & (1 << LOG_FLT_ALL) ? "Enabled" : "Disabled",
Harald Welte6d2d4d62013-03-10 09:53:24 +0000518 VTY_NEWLINE);
519
Harald Weltefb84f322013-06-06 07:33:54 +0200520 /* print application specific filters */
521 if (info->print_fn)
522 info->print_fn(vty, info, tgt);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200523}
524
525#define SHOW_LOG_STR "Show current logging configuration\n"
526
527DEFUN(show_logging_vty,
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000528 show_logging_vty_cmd,
529 "show logging vty",
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200530 SHOW_STR SHOW_LOG_STR
531 "Show current logging configuration for this vty\n")
532{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200533 struct log_target *tgt;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200534
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200535 ACQUIRE_VTY_LOG_TGT_WITH_LOCK(vty, tgt);
Harald Weltea62648b2011-02-18 21:03:27 +0100536
537 vty_print_logtarget(vty, osmo_log_info, tgt);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200538 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200539}
540
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000541DEFUN(show_alarms,
542 show_alarms_cmd,
543 "show alarms",
544 SHOW_STR SHOW_LOG_STR
545 "Show the contents of the logging ringbuffer\n")
546{
547 int i, num_alarms;
548 struct osmo_strrb *rb;
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200549 struct log_target *tgt;
550
551 log_tgt_mutex_lock();
552 tgt = log_target_find(LOG_TGT_TYPE_STRRB, NULL);
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000553 if (!tgt) {
554 vty_out(vty, "%% No alarms, run 'log alarms <2-32700>'%s",
555 VTY_NEWLINE);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200556 RET_WITH_UNLOCK(CMD_WARNING);
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000557 }
558
559 rb = tgt->tgt_rb.rb;
560 num_alarms = osmo_strrb_elements(rb);
561
562 vty_out(vty, "%% Showing %i alarms%s", num_alarms, VTY_NEWLINE);
563
564 for (i = 0; i < num_alarms; i++)
565 vty_out(vty, "%% %s%s", osmo_strrb_get_nth(rb, i),
566 VTY_NEWLINE);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200567 RET_WITH_UNLOCK(CMD_SUCCESS);
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000568}
569
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200570gDEFUN(cfg_description, cfg_description_cmd,
571 "description .TEXT",
Thorsten Alteholza81055d2017-03-02 22:13:48 +0100572 "Save human-readable description of the object\n"
Holger Hans Peter Freytherc9b3e062012-07-25 13:02:49 +0200573 "Text until the end of the line\n")
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200574{
575 char **dptr = vty->index_sub;
576
577 if (!dptr) {
578 vty_out(vty, "vty->index_sub == NULL%s", VTY_NEWLINE);
579 return CMD_WARNING;
580 }
581
Holger Hans Peter Freytherff0670e2011-02-24 14:20:41 +0100582 if (*dptr)
583 talloc_free(*dptr);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200584 *dptr = argv_concat(argv, argc, 0);
Holger Hans Peter Freyther6a75d162013-07-14 09:07:11 +0200585 if (!*dptr)
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200586 return CMD_WARNING;
587
588 return CMD_SUCCESS;
589}
590
591gDEFUN(cfg_no_description, cfg_no_description_cmd,
592 "no description",
593 NO_STR
594 "Remove description of the object\n")
595{
596 char **dptr = vty->index_sub;
597
598 if (!dptr) {
599 vty_out(vty, "vty->index_sub == NULL%s", VTY_NEWLINE);
600 return CMD_WARNING;
601 }
602
603 if (*dptr) {
604 talloc_free(*dptr);
605 *dptr = NULL;
606 }
607
608 return CMD_SUCCESS;
609}
610
Harald Welte28222962011-02-18 20:37:04 +0100611/* Support for configuration of log targets != the current vty */
612
613struct cmd_node cfg_log_node = {
614 CFG_LOG_NODE,
615 "%s(config-log)# ",
616 1
617};
618
Harald Welte28222962011-02-18 20:37:04 +0100619#ifdef HAVE_SYSLOG_H
620
621#include <syslog.h>
622
623static const int local_sysl_map[] = {
624 [0] = LOG_LOCAL0,
625 [1] = LOG_LOCAL1,
626 [2] = LOG_LOCAL2,
627 [3] = LOG_LOCAL3,
628 [4] = LOG_LOCAL4,
629 [5] = LOG_LOCAL5,
630 [6] = LOG_LOCAL6,
631 [7] = LOG_LOCAL7
632};
633
Harald Weltede79cee2011-02-24 23:47:57 +0100634/* From VTY core code */
635extern struct host host;
636
Harald Welte28222962011-02-18 20:37:04 +0100637static int _cfg_log_syslog(struct vty *vty, int facility)
638{
639 struct log_target *tgt;
640
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200641 log_tgt_mutex_lock();
Harald Welte28222962011-02-18 20:37:04 +0100642 /* First delete the old syslog target, if any */
643 tgt = log_target_find(LOG_TGT_TYPE_SYSLOG, NULL);
644 if (tgt)
645 log_target_destroy(tgt);
646
Harald Weltede79cee2011-02-24 23:47:57 +0100647 tgt = log_target_create_syslog(host.app_info->name, 0, facility);
Harald Welte28222962011-02-18 20:37:04 +0100648 if (!tgt) {
649 vty_out(vty, "%% Unable to open syslog%s", VTY_NEWLINE);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200650 RET_WITH_UNLOCK(CMD_WARNING);
Harald Welte28222962011-02-18 20:37:04 +0100651 }
652 log_add_target(tgt);
653
654 vty->index = tgt;
655 vty->node = CFG_LOG_NODE;
656
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200657 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte28222962011-02-18 20:37:04 +0100658}
659
660DEFUN(cfg_log_syslog_local, cfg_log_syslog_local_cmd,
661 "log syslog local <0-7>",
662 LOG_STR "Logging via syslog\n" "Syslog LOCAL facility\n"
663 "Local facility number\n")
664{
665 int local = atoi(argv[0]);
666 int facility = local_sysl_map[local];
667
668 return _cfg_log_syslog(vty, facility);
669}
670
671static struct value_string sysl_level_names[] = {
672 { LOG_AUTHPRIV, "authpriv" },
673 { LOG_CRON, "cron" },
674 { LOG_DAEMON, "daemon" },
675 { LOG_FTP, "ftp" },
676 { LOG_LPR, "lpr" },
677 { LOG_MAIL, "mail" },
678 { LOG_NEWS, "news" },
679 { LOG_USER, "user" },
680 { LOG_UUCP, "uucp" },
681 /* only for value -> string conversion */
682 { LOG_LOCAL0, "local 0" },
683 { LOG_LOCAL1, "local 1" },
684 { LOG_LOCAL2, "local 2" },
685 { LOG_LOCAL3, "local 3" },
686 { LOG_LOCAL4, "local 4" },
687 { LOG_LOCAL5, "local 5" },
688 { LOG_LOCAL6, "local 6" },
689 { LOG_LOCAL7, "local 7" },
690 { 0, NULL }
691};
692
693DEFUN(cfg_log_syslog, cfg_log_syslog_cmd,
694 "log syslog (authpriv|cron|daemon|ftp|lpr|mail|news|user|uucp)",
Holger Hans Peter Freythera4463fd2011-10-03 23:17:36 +0200695 LOG_STR "Logging via syslog\n"
696 "Security/authorization messages facility\n"
697 "Clock daemon (cron/at) facility\n"
698 "General system daemon facility\n"
699 "Ftp daemon facility\n"
700 "Line printer facility\n"
701 "Mail facility\n"
702 "News facility\n"
703 "Generic facility\n"
704 "UUCP facility\n")
Harald Welte28222962011-02-18 20:37:04 +0100705{
706 int facility = get_string_value(sysl_level_names, argv[0]);
707
708 return _cfg_log_syslog(vty, facility);
709}
710
711DEFUN(cfg_no_log_syslog, cfg_no_log_syslog_cmd,
712 "no log syslog",
713 NO_STR LOG_STR "Logging via syslog\n")
714{
715 struct log_target *tgt;
716
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200717 log_tgt_mutex_lock();
Harald Welte28222962011-02-18 20:37:04 +0100718 tgt = log_target_find(LOG_TGT_TYPE_SYSLOG, NULL);
719 if (!tgt) {
720 vty_out(vty, "%% No syslog target found%s",
721 VTY_NEWLINE);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200722 RET_WITH_UNLOCK(CMD_WARNING);
Harald Welte28222962011-02-18 20:37:04 +0100723 }
724
725 log_target_destroy(tgt);
726
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200727 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte28222962011-02-18 20:37:04 +0100728}
729#endif /* HAVE_SYSLOG_H */
730
Harald Welteaa00f992016-12-02 15:30:02 +0100731DEFUN(cfg_log_gsmtap, cfg_log_gsmtap_cmd,
732 "log gsmtap [HOSTNAME]",
Neels Hofmeyrfd9ec3b2016-12-11 01:48:26 +0100733 LOG_STR "Logging via GSMTAP\n"
734 "Host name to send the GSMTAP logging to (UDP port 4729)\n")
Harald Welteaa00f992016-12-02 15:30:02 +0100735{
Max2f153b52018-01-04 12:25:57 +0100736 const char *hostname = argc ? argv[0] : "127.0.0.1";
Harald Welteaa00f992016-12-02 15:30:02 +0100737 struct log_target *tgt;
738
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200739 log_tgt_mutex_lock();
Harald Welteaa00f992016-12-02 15:30:02 +0100740 tgt = log_target_find(LOG_TGT_TYPE_GSMTAP, hostname);
741 if (!tgt) {
742 tgt = log_target_create_gsmtap(hostname, GSMTAP_UDP_PORT,
743 host.app_info->name, false,
744 true);
745 if (!tgt) {
Max2f153b52018-01-04 12:25:57 +0100746 vty_out(vty, "%% Unable to create GSMTAP log for %s%s",
747 hostname, VTY_NEWLINE);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200748 RET_WITH_UNLOCK(CMD_WARNING);
Harald Welteaa00f992016-12-02 15:30:02 +0100749 }
750 log_add_target(tgt);
751 }
752
753 vty->index = tgt;
754 vty->node = CFG_LOG_NODE;
755
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200756 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welteaa00f992016-12-02 15:30:02 +0100757}
758
Harald Welte28222962011-02-18 20:37:04 +0100759DEFUN(cfg_log_stderr, cfg_log_stderr_cmd,
760 "log stderr",
761 LOG_STR "Logging via STDERR of the process\n")
762{
763 struct log_target *tgt;
764
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200765 log_tgt_mutex_lock();
Harald Welte28222962011-02-18 20:37:04 +0100766 tgt = log_target_find(LOG_TGT_TYPE_STDERR, NULL);
767 if (!tgt) {
768 tgt = log_target_create_stderr();
769 if (!tgt) {
770 vty_out(vty, "%% Unable to create stderr log%s",
771 VTY_NEWLINE);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200772 RET_WITH_UNLOCK(CMD_WARNING);
Harald Welte28222962011-02-18 20:37:04 +0100773 }
774 log_add_target(tgt);
775 }
776
777 vty->index = tgt;
778 vty->node = CFG_LOG_NODE;
779
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200780 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte28222962011-02-18 20:37:04 +0100781}
782
783DEFUN(cfg_no_log_stderr, cfg_no_log_stderr_cmd,
784 "no log stderr",
785 NO_STR LOG_STR "Logging via STDERR of the process\n")
786{
787 struct log_target *tgt;
788
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200789 log_tgt_mutex_lock();
Harald Welte28222962011-02-18 20:37:04 +0100790 tgt = log_target_find(LOG_TGT_TYPE_STDERR, NULL);
791 if (!tgt) {
792 vty_out(vty, "%% No stderr logging active%s", VTY_NEWLINE);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200793 RET_WITH_UNLOCK(CMD_WARNING);
Harald Welte28222962011-02-18 20:37:04 +0100794 }
795
796 log_target_destroy(tgt);
797
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200798 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte28222962011-02-18 20:37:04 +0100799}
800
801DEFUN(cfg_log_file, cfg_log_file_cmd,
802 "log file .FILENAME",
803 LOG_STR "Logging to text file\n" "Filename\n")
804{
805 const char *fname = argv[0];
806 struct log_target *tgt;
807
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200808 log_tgt_mutex_lock();
Harald Welte28222962011-02-18 20:37:04 +0100809 tgt = log_target_find(LOG_TGT_TYPE_FILE, fname);
810 if (!tgt) {
811 tgt = log_target_create_file(fname);
812 if (!tgt) {
813 vty_out(vty, "%% Unable to create file `%s'%s",
814 fname, VTY_NEWLINE);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200815 RET_WITH_UNLOCK(CMD_WARNING);
Harald Welte28222962011-02-18 20:37:04 +0100816 }
817 log_add_target(tgt);
818 }
819
820 vty->index = tgt;
821 vty->node = CFG_LOG_NODE;
822
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200823 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte28222962011-02-18 20:37:04 +0100824}
825
826
827DEFUN(cfg_no_log_file, cfg_no_log_file_cmd,
828 "no log file .FILENAME",
829 NO_STR LOG_STR "Logging to text file\n" "Filename\n")
830{
831 const char *fname = argv[0];
832 struct log_target *tgt;
833
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200834 log_tgt_mutex_lock();
Harald Welte28222962011-02-18 20:37:04 +0100835 tgt = log_target_find(LOG_TGT_TYPE_FILE, fname);
836 if (!tgt) {
837 vty_out(vty, "%% No such log file `%s'%s",
838 fname, VTY_NEWLINE);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200839 RET_WITH_UNLOCK(CMD_WARNING);
Harald Welte28222962011-02-18 20:37:04 +0100840 }
841
842 log_target_destroy(tgt);
843
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200844 RET_WITH_UNLOCK(CMD_SUCCESS);
Harald Welte28222962011-02-18 20:37:04 +0100845}
846
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000847DEFUN(cfg_log_alarms, cfg_log_alarms_cmd,
848 "log alarms <2-32700>",
849 LOG_STR "Logging alarms to osmo_strrb\n"
850 "Maximum number of messages to log\n")
851{
852 struct log_target *tgt;
853 unsigned int rbsize = atoi(argv[0]);
854
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200855
856 log_tgt_mutex_lock();
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000857 tgt = log_target_find(LOG_TGT_TYPE_STRRB, NULL);
858 if (tgt)
859 log_target_destroy(tgt);
860
861 tgt = log_target_create_rb(rbsize);
862 if (!tgt) {
863 vty_out(vty, "%% Unable to create osmo_strrb (size %u)%s",
864 rbsize, VTY_NEWLINE);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200865 RET_WITH_UNLOCK(CMD_WARNING);
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000866 }
867 log_add_target(tgt);
868
869 vty->index = tgt;
870 vty->node = CFG_LOG_NODE;
871
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200872 RET_WITH_UNLOCK(CMD_SUCCESS);
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000873}
874
875DEFUN(cfg_no_log_alarms, cfg_no_log_alarms_cmd,
876 "no log alarms",
877 NO_STR LOG_STR "Logging alarms to osmo_strrb\n")
878{
879 struct log_target *tgt;
880
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200881 log_tgt_mutex_lock();
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000882 tgt = log_target_find(LOG_TGT_TYPE_STRRB, NULL);
883 if (!tgt) {
884 vty_out(vty, "%% No osmo_strrb target found%s", VTY_NEWLINE);
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200885 RET_WITH_UNLOCK(CMD_WARNING);
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000886 }
887
888 log_target_destroy(tgt);
889
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200890 RET_WITH_UNLOCK(CMD_SUCCESS);
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000891}
892
Harald Welte28222962011-02-18 20:37:04 +0100893static int config_write_log_single(struct vty *vty, struct log_target *tgt)
894{
Pau Espin Pedrolc21ba152019-08-02 20:32:34 +0200895 char level_buf[128];
Harald Welte28222962011-02-18 20:37:04 +0100896 int i;
Harald Welte28222962011-02-18 20:37:04 +0100897
898 switch (tgt->type) {
899 case LOG_TGT_TYPE_VTY:
900 return 1;
901 break;
902 case LOG_TGT_TYPE_STDERR:
903 vty_out(vty, "log stderr%s", VTY_NEWLINE);
904 break;
905 case LOG_TGT_TYPE_SYSLOG:
906#ifdef HAVE_SYSLOG_H
907 vty_out(vty, "log syslog %s%s",
908 get_value_string(sysl_level_names,
909 tgt->tgt_syslog.facility),
910 VTY_NEWLINE);
911#endif
912 break;
913 case LOG_TGT_TYPE_FILE:
914 vty_out(vty, "log file %s%s", tgt->tgt_file.fname, VTY_NEWLINE);
915 break;
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000916 case LOG_TGT_TYPE_STRRB:
917 vty_out(vty, "log alarms %zu%s",
918 log_target_rb_avail_size(tgt), VTY_NEWLINE);
919 break;
Harald Welteaa00f992016-12-02 15:30:02 +0100920 case LOG_TGT_TYPE_GSMTAP:
921 vty_out(vty, "log gsmtap %s%s",
922 tgt->tgt_gsmtap.hostname, VTY_NEWLINE);
923 break;
Harald Welte28222962011-02-18 20:37:04 +0100924 }
925
Harald Welte0d67f482018-09-25 20:16:14 +0200926 vty_out(vty, " logging filter all %u%s",
Neels Hofmeyr8b86cd72017-02-23 18:03:28 +0100927 tgt->filter_map & (1 << LOG_FLT_ALL) ? 1 : 0, VTY_NEWLINE);
Harald Weltefb84f322013-06-06 07:33:54 +0200928 /* save filters outside of libosmocore, i.e. in app code */
929 if (osmo_log_info->save_fn)
930 osmo_log_info->save_fn(vty, osmo_log_info, tgt);
Harald Welte2da47f12012-10-22 19:31:54 +0200931
Harald Welte0d67f482018-09-25 20:16:14 +0200932 vty_out(vty, " logging color %u%s", tgt->use_color ? 1 : 0,
Harald Welte28222962011-02-18 20:37:04 +0100933 VTY_NEWLINE);
Vadim Yanitskiy5c4b9852019-07-28 04:36:37 +0700934 vty_out(vty, " logging print category-hex %d%s",
935 tgt->print_category_hex ? 1 : 0, VTY_NEWLINE);
Harald Welte0d67f482018-09-25 20:16:14 +0200936 vty_out(vty, " logging print category %d%s",
Michael McTernan78933462015-03-20 15:29:25 +0100937 tgt->print_category ? 1 : 0, VTY_NEWLINE);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100938 if (tgt->print_ext_timestamp)
Harald Welte0d67f482018-09-25 20:16:14 +0200939 vty_out(vty, " logging print extended-timestamp 1%s", VTY_NEWLINE);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100940 else
Harald Welte0d67f482018-09-25 20:16:14 +0200941 vty_out(vty, " logging timestamp %u%s",
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100942 tgt->print_timestamp ? 1 : 0, VTY_NEWLINE);
Neels Hofmeyr886e5482018-01-16 01:49:37 +0100943 if (tgt->print_level)
Harald Welte0d67f482018-09-25 20:16:14 +0200944 vty_out(vty, " logging print level 1%s", VTY_NEWLINE);
945 vty_out(vty, " logging print file %s%s",
Neels Hofmeyr22772cc2018-02-06 00:52:08 +0100946 get_value_string(logging_print_file_args, tgt->print_filename2),
947 VTY_NEWLINE);
Harald Welte28222962011-02-18 20:37:04 +0100948
Neels Hofmeyr098038a2018-09-11 23:49:13 +0200949 if (tgt->loglevel) {
950 const char *level_str = get_value_string_or_null(loglevel_strs, tgt->loglevel);
Pau Espin Pedrolc21ba152019-08-02 20:32:34 +0200951 if (!level_str) {
Neels Hofmeyr9540c242018-09-12 00:20:50 +0200952 vty_out(vty, "%% Invalid log level %u for 'force-all'%s",
953 tgt->loglevel, VTY_NEWLINE);
Pau Espin Pedrolc21ba152019-08-02 20:32:34 +0200954 } else {
955 osmo_str_tolower_buf(level_buf, sizeof(level_buf), level_str);
956 vty_out(vty, " logging level force-all %s%s", level_buf, VTY_NEWLINE);
957 }
Neels Hofmeyr098038a2018-09-11 23:49:13 +0200958 }
Harald Welte28222962011-02-18 20:37:04 +0100959
960 for (i = 0; i < osmo_log_info->num_cat; i++) {
961 const struct log_category *cat = &tgt->categories[i];
Pau Espin Pedrolc21ba152019-08-02 20:32:34 +0200962 char cat_name[128];
Neels Hofmeyr098038a2018-09-11 23:49:13 +0200963 const char *level_str;
Harald Welte28222962011-02-18 20:37:04 +0100964
Harald Welte1a02cfc2013-03-19 10:37:39 +0100965 /* skip empty entries in the array */
966 if (!osmo_log_info->cat[i].name)
967 continue;
968
Pau Espin Pedrolc21ba152019-08-02 20:32:34 +0200969 osmo_str_tolower_buf(cat_name, sizeof(cat_name), osmo_log_info->cat[i].name + 1);
Neels Hofmeyr098038a2018-09-11 23:49:13 +0200970
971 level_str = get_value_string_or_null(loglevel_strs, cat->loglevel);
972 if (!level_str) {
973 vty_out(vty, "%% Invalid log level %u for %s%s", cat->loglevel, cat_name,
974 VTY_NEWLINE);
975 continue;
976 }
977
Pau Espin Pedrolc21ba152019-08-02 20:32:34 +0200978 osmo_str_tolower_buf(level_buf, sizeof(level_buf), level_str);
Harald Welte0d67f482018-09-25 20:16:14 +0200979 vty_out(vty, " logging level %s", cat_name);
Pau Espin Pedrolc21ba152019-08-02 20:32:34 +0200980 vty_out(vty, " %s%s", level_buf, VTY_NEWLINE);
Harald Welte28222962011-02-18 20:37:04 +0100981 }
982
Harald Welte28222962011-02-18 20:37:04 +0100983 return 1;
984}
985
986static int config_write_log(struct vty *vty)
987{
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200988 log_tgt_mutex_lock();
Harald Welte28222962011-02-18 20:37:04 +0100989 struct log_target *dbg = vty->index;
990
991 llist_for_each_entry(dbg, &osmo_log_target_list, entry)
992 config_write_log_single(vty, dbg);
993
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200994 log_tgt_mutex_unlock();
Harald Welte28222962011-02-18 20:37:04 +0100995 return 1;
996}
997
Harald Welte11eb4b52018-06-09 17:41:31 +0200998static int log_deprecated_func(struct cmd_element *cmd, struct vty *vty, int argc, const char *argv[])
999{
1000 vty_out(vty, "%% Ignoring deprecated '%s'%s", cmd->string, VTY_NEWLINE);
Vadim Yanitskiy4abda9e2019-11-21 00:19:36 +07001001 return CMD_SUCCESS; /* Otherwise the process would terminate */
Harald Welte11eb4b52018-06-09 17:41:31 +02001002}
1003
1004void logging_vty_add_deprecated_subsys(void *ctx, const char *name)
1005{
1006 struct cmd_element *cmd = talloc_zero(ctx, struct cmd_element);
1007 OSMO_ASSERT(cmd);
Vadim Yanitskiy75c242e2019-11-21 00:06:53 +07001008 cmd->string = talloc_asprintf(cmd, "logging level %s " LOG_LEVEL_ARGS, name);
Harald Welte11eb4b52018-06-09 17:41:31 +02001009 cmd->func = log_deprecated_func;
Neels Hofmeyrba0762d2018-09-10 13:56:03 +02001010 cmd->doc = LEVEL_STR
Harald Welte11eb4b52018-06-09 17:41:31 +02001011 "Deprecated Category\n";
1012 cmd->attr = CMD_ATTR_DEPRECATED;
1013
1014 install_element(CFG_LOG_NODE, cmd);
1015}
1016
Neels Hofmeyrd0b3b9e2019-07-29 19:28:08 +02001017/* logp (<categories>) (debug|...|fatal) .LOGMESSAGE*/
1018DEFUN(vty_logp,
1019 vty_logp_cmd,
1020 NULL, /* cmdstr is dynamically set in gen_vty_logp_cmd_strs(). */
1021 NULL) /* same thing for helpstr. */
1022{
1023 int category = log_parse_category(argv[0]);
1024 int level = log_parse_level(argv[1]);
1025 char *str = argv_concat(argv, argc, 2);
1026 LOGP(category, level, "%s\n", str);
1027 return CMD_SUCCESS;
1028}
1029
1030static void gen_vty_logp_cmd_strs(struct cmd_element *cmd)
1031{
1032 char *cmd_str = NULL;
1033 char *doc_str = NULL;
1034
1035 assert_loginfo(__func__);
1036
1037 OSMO_ASSERT(cmd->string == NULL);
1038 OSMO_ASSERT(cmd->doc == NULL);
1039
1040 osmo_talloc_asprintf(tall_log_ctx, cmd_str, "logp (");
1041 osmo_talloc_asprintf(tall_log_ctx, doc_str,
1042 "Print a message on all log outputs; useful for placing markers in test logs\n");
1043 add_category_strings(&cmd_str, &doc_str, osmo_log_info);
1044 osmo_talloc_asprintf(tall_log_ctx, cmd_str, ") %s", LOG_LEVEL_ARGS);
1045 osmo_talloc_asprintf(tall_log_ctx, doc_str, "%s", LOG_LEVEL_STRS);
1046
1047 osmo_talloc_asprintf(tall_log_ctx, cmd_str, " .LOGMESSAGE");
1048 osmo_talloc_asprintf(tall_log_ctx, doc_str,
1049 "Arbitrary message to log on given category and log level\n");
1050
1051 cmd->string = cmd_str;
1052 cmd->doc = doc_str;
1053}
1054
Harald Welte8c648252017-10-16 15:17:03 +02001055/*! Register logging related commands to the VTY. Call this once from
1056 * your application if you want to support those commands. */
Maxc65c5b42017-03-15 13:20:23 +01001057void logging_vty_add_cmds()
Harald Welte3fb0b6f2010-05-19 19:02:52 +02001058{
1059 install_element_ve(&enable_logging_cmd);
1060 install_element_ve(&disable_logging_cmd);
1061 install_element_ve(&logging_fltr_all_cmd);
1062 install_element_ve(&logging_use_clr_cmd);
1063 install_element_ve(&logging_prnt_timestamp_cmd);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +01001064 install_element_ve(&logging_prnt_ext_timestamp_cmd);
1065 install_element_ve(&logging_prnt_cat_cmd);
Neels Hofmeyrbd7bd392018-01-16 01:52:29 +01001066 install_element_ve(&logging_prnt_cat_hex_cmd);
Neels Hofmeyr886e5482018-01-16 01:49:37 +01001067 install_element_ve(&logging_prnt_level_cmd);
Neels Hofmeyrc6fd2452018-01-16 01:57:38 +01001068 install_element_ve(&logging_prnt_file_cmd);
Harald Welte3fb0b6f2010-05-19 19:02:52 +02001069 install_element_ve(&logging_set_category_mask_cmd);
Holger Hans Peter Freyther146d1d32011-10-03 23:15:41 +02001070 install_element_ve(&logging_set_category_mask_old_cmd);
Pablo Neira Ayuso04139f12011-03-09 13:05:08 +01001071
Neels Hofmeyr9540c242018-09-12 00:20:50 +02001072 /* logging level (<categories>) (debug|...|fatal) */
Neels Hofmeyrba0762d2018-09-10 13:56:03 +02001073 gen_logging_level_cmd_strs(&logging_level_cmd,
Neels Hofmeyr9540c242018-09-12 00:20:50 +02001074 LOG_LEVEL_ARGS,
Neels Hofmeyr7e0686c2018-09-10 20:58:52 +02001075 LOG_LEVEL_STRS);
Neels Hofmeyr9540c242018-09-12 00:20:50 +02001076 /* logging level (<categories>) everything */
Neels Hofmeyr7e0686c2018-09-10 20:58:52 +02001077 gen_logging_level_cmd_strs(&deprecated_logging_level_everything_cmd,
1078 "everything", EVERYTHING_STR);
Neels Hofmeyrba0762d2018-09-10 13:56:03 +02001079
Harald Welte3fb0b6f2010-05-19 19:02:52 +02001080 install_element_ve(&logging_level_cmd);
Neels Hofmeyr28fc0782018-09-12 02:32:02 +02001081 install_element_ve(&logging_level_set_all_cmd);
Neels Hofmeyr9540c242018-09-12 00:20:50 +02001082 install_element_ve(&logging_level_force_all_cmd);
1083 install_element_ve(&no_logging_level_force_all_cmd);
Neels Hofmeyr7e0686c2018-09-10 20:58:52 +02001084 install_element_ve(&deprecated_logging_level_everything_cmd);
Neels Hofmeyr9540c242018-09-12 00:20:50 +02001085 install_element_ve(&deprecated_logging_level_all_cmd);
1086 install_element_ve(&deprecated_logging_level_all_everything_cmd);
Harald Welte28222962011-02-18 20:37:04 +01001087
Neels Hofmeyrd0b3b9e2019-07-29 19:28:08 +02001088 gen_vty_logp_cmd_strs(&vty_logp_cmd);
1089 install_element_ve(&vty_logp_cmd);
1090
Pau Espin Pedrol0c2a46d2019-08-20 10:39:05 +02001091 install_element_ve(&show_logging_vty_cmd);
1092 install_element_ve(&show_alarms_cmd);
1093
Harald Welte28222962011-02-18 20:37:04 +01001094 install_node(&cfg_log_node, config_write_log);
Harald Weltea62648b2011-02-18 21:03:27 +01001095 install_element(CFG_LOG_NODE, &logging_fltr_all_cmd);
1096 install_element(CFG_LOG_NODE, &logging_use_clr_cmd);
1097 install_element(CFG_LOG_NODE, &logging_prnt_timestamp_cmd);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +01001098 install_element(CFG_LOG_NODE, &logging_prnt_ext_timestamp_cmd);
1099 install_element(CFG_LOG_NODE, &logging_prnt_cat_cmd);
Neels Hofmeyrbd7bd392018-01-16 01:52:29 +01001100 install_element(CFG_LOG_NODE, &logging_prnt_cat_hex_cmd);
Neels Hofmeyr886e5482018-01-16 01:49:37 +01001101 install_element(CFG_LOG_NODE, &logging_prnt_level_cmd);
Neels Hofmeyrc6fd2452018-01-16 01:57:38 +01001102 install_element(CFG_LOG_NODE, &logging_prnt_file_cmd);
Harald Weltea62648b2011-02-18 21:03:27 +01001103 install_element(CFG_LOG_NODE, &logging_level_cmd);
Neels Hofmeyr28fc0782018-09-12 02:32:02 +02001104 install_element(CFG_LOG_NODE, &logging_level_set_all_cmd);
Neels Hofmeyr9540c242018-09-12 00:20:50 +02001105 install_element(CFG_LOG_NODE, &logging_level_force_all_cmd);
1106 install_element(CFG_LOG_NODE, &no_logging_level_force_all_cmd);
Neels Hofmeyr7e0686c2018-09-10 20:58:52 +02001107 install_element(CFG_LOG_NODE, &deprecated_logging_level_everything_cmd);
Neels Hofmeyr9540c242018-09-12 00:20:50 +02001108 install_element(CFG_LOG_NODE, &deprecated_logging_level_all_cmd);
1109 install_element(CFG_LOG_NODE, &deprecated_logging_level_all_everything_cmd);
Harald Welte28222962011-02-18 20:37:04 +01001110
1111 install_element(CONFIG_NODE, &cfg_log_stderr_cmd);
1112 install_element(CONFIG_NODE, &cfg_no_log_stderr_cmd);
1113 install_element(CONFIG_NODE, &cfg_log_file_cmd);
1114 install_element(CONFIG_NODE, &cfg_no_log_file_cmd);
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +00001115 install_element(CONFIG_NODE, &cfg_log_alarms_cmd);
1116 install_element(CONFIG_NODE, &cfg_no_log_alarms_cmd);
Harald Welte28222962011-02-18 20:37:04 +01001117#ifdef HAVE_SYSLOG_H
1118 install_element(CONFIG_NODE, &cfg_log_syslog_cmd);
1119 install_element(CONFIG_NODE, &cfg_log_syslog_local_cmd);
1120 install_element(CONFIG_NODE, &cfg_no_log_syslog_cmd);
1121#endif
Harald Welteaa00f992016-12-02 15:30:02 +01001122 install_element(CONFIG_NODE, &cfg_log_gsmtap_cmd);
Harald Welte3fb0b6f2010-05-19 19:02:52 +02001123}