blob: 5ae38c75011c3751f9736c11522cbcbce8f1b20e [file] [log] [blame]
Sylvain Munaut12ba7782014-06-16 10:13:40 +02001#pragma once
Harald Welte3ae27582010-03-26 21:24:24 +08002
Harald Welte18fc4652011-08-17 14:14:17 +02003/*! \defgroup logging Osmocom logging framework
4 * @{
Neels Hofmeyr17518fe2017-06-20 04:35:06 +02005 * \file logging.h */
Harald Welte18fc4652011-08-17 14:14:17 +02006
Harald Welte3ae27582010-03-26 21:24:24 +08007#include <stdio.h>
8#include <stdint.h>
Christoph Fritzab7c9c72011-09-01 16:22:17 +02009#include <stdarg.h>
Harald Welteaa00f992016-12-02 15:30:02 +010010#include <stdbool.h>
Maxaa1bc012017-01-13 11:01:12 +010011#include <osmocom/core/defs.h>
Pablo Neira Ayuso83419342011-03-22 16:36:13 +010012#include <osmocom/core/linuxlist.h>
Harald Welte3ae27582010-03-26 21:24:24 +080013
Philipp Maier4c44d462022-01-19 11:43:05 +010014extern struct log_info *osmo_log_info;
15
Kévin Redond1e220f2019-06-13 13:41:00 +020016#ifndef DEBUG
Harald Welte3ae27582010-03-26 21:24:24 +080017#define DEBUG
Kévin Redond1e220f2019-06-13 13:41:00 +020018#endif
Harald Welte3ae27582010-03-26 21:24:24 +080019
Ericd02090b2021-11-24 20:24:46 +010020#ifdef LIBOSMOCORE_NO_LOGGING
21#undef DEBUG
22#endif
23
Harald Welte3ae27582010-03-26 21:24:24 +080024#ifdef DEBUG
Neels Hofmeyr87e45502017-06-20 00:17:59 +020025/*! Log a debug message through the Osmocom logging framework
Harald Welte2d2e2cc2016-04-25 12:11:20 +020026 * \param[in] ss logging subsystem (e.g. \ref DLGLOBAL)
27 * \param[in] fmt format string
28 * \param[in] args variable argument list
29 */
Maxaa1bc012017-01-13 11:01:12 +010030#define DEBUGP(ss, fmt, args...) LOGP(ss, LOGL_DEBUG, fmt, ##args)
31#define DEBUGPC(ss, fmt, args...) LOGPC(ss, LOGL_DEBUG, fmt, ##args)
Harald Welte3ae27582010-03-26 21:24:24 +080032#else
33#define DEBUGP(xss, fmt, args...)
34#define DEBUGPC(ss, fmt, args...)
35#endif
36
Harald Welte3ae27582010-03-26 21:24:24 +080037
Holger Hans Peter Freytherfb4bfc22012-07-12 09:26:25 +020038void osmo_vlogp(int subsys, int level, const char *file, int line,
Harald Welte36c5a3e2011-08-27 14:33:19 +020039 int cont, const char *format, va_list ap);
40
Maxaa1bc012017-01-13 11:01:12 +010041void logp(int subsys, const char *file, int line, int cont, const char *format, ...) OSMO_DEPRECATED("Use DEBUGP* macros instead");
Harald Welte3ae27582010-03-26 21:24:24 +080042
Neels Hofmeyr87e45502017-06-20 00:17:59 +020043/*! Log a new message through the Osmocom logging framework
Harald Weltebd598e32011-08-16 23:26:52 +020044 * \param[in] ss logging subsystem (e.g. \ref DLGLOBAL)
45 * \param[in] level logging level (e.g. \ref LOGL_NOTICE)
46 * \param[in] fmt format string
47 * \param[in] args variable argument list
48 */
Harald Welte3ae27582010-03-26 21:24:24 +080049#define LOGP(ss, level, fmt, args...) \
Neels Hofmeyr725698a2016-12-14 17:24:54 +010050 LOGPSRC(ss, level, NULL, 0, fmt, ## args)
Harald Weltebd598e32011-08-16 23:26:52 +020051
Neels Hofmeyr87e45502017-06-20 00:17:59 +020052/*! Continue a log message through the Osmocom logging framework
Harald Weltebd598e32011-08-16 23:26:52 +020053 * \param[in] ss logging subsystem (e.g. \ref DLGLOBAL)
54 * \param[in] level logging level (e.g. \ref LOGL_NOTICE)
55 * \param[in] fmt format string
56 * \param[in] args variable argument list
57 */
Eric Wild63e1b2b2021-11-26 21:09:01 +010058#ifndef LIBOSMOCORE_NO_LOGGING
Harald Welte3ae27582010-03-26 21:24:24 +080059#define LOGPC(ss, level, fmt, args...) \
Jacob Erlbecka89d22c2015-11-17 11:52:25 +010060 do { \
Philipp Maier4c44d462022-01-19 11:43:05 +010061 if (!osmo_log_info) { \
62 logp_stub(__FILE__, __LINE__, 1, fmt, ##args); \
63 break; \
64 } \
Jacob Erlbecka89d22c2015-11-17 11:52:25 +010065 if (log_check_level(ss, level)) \
Neels Hofmeyr983dcb92018-08-20 12:33:22 +020066 logp2(ss, level, __FILE__, __LINE__, 1, fmt, ##args); \
Jacob Erlbecka89d22c2015-11-17 11:52:25 +010067 } while(0)
Eric Wild63e1b2b2021-11-26 21:09:01 +010068#else
69#define LOGPC(ss, level, fmt, args...)
70#endif
Harald Welte3ae27582010-03-26 21:24:24 +080071
Neels Hofmeyr87e45502017-06-20 00:17:59 +020072/*! Log through the Osmocom logging framework with explicit source.
Neels Hofmeyr983dcb92018-08-20 12:33:22 +020073 * If caller_file is passed as NULL, __FILE__ and __LINE__ are used
Neels Hofmeyr725698a2016-12-14 17:24:54 +010074 * instead of caller_file and caller_line (so that this macro here defines
75 * both cases in the same place, and to catch cases where callers fail to pass
76 * a non-null filename string).
77 * \param[in] ss logging subsystem (e.g. \ref DLGLOBAL)
78 * \param[in] level logging level (e.g. \ref LOGL_NOTICE)
Neels Hofmeyr983dcb92018-08-20 12:33:22 +020079 * \param[in] caller_file caller's source file string (e.g. __FILE__)
Neels Hofmeyr725698a2016-12-14 17:24:54 +010080 * \param[in] caller_line caller's source line nr (e.g. __LINE__)
81 * \param[in] fmt format string
82 * \param[in] args variable argument list
83 */
84#define LOGPSRC(ss, level, caller_file, caller_line, fmt, args...) \
Holger Hans Peter Freyther37a83402017-11-29 11:46:39 +080085 LOGPSRCC(ss, level, caller_file, caller_line, 0, fmt, ##args)
86
87/*! Log through the Osmocom logging framework with explicit source.
Neels Hofmeyr983dcb92018-08-20 12:33:22 +020088 * If caller_file is passed as NULL, __FILE__ and __LINE__ are used
Holger Hans Peter Freyther37a83402017-11-29 11:46:39 +080089 * instead of caller_file and caller_line (so that this macro here defines
90 * both cases in the same place, and to catch cases where callers fail to pass
91 * a non-null filename string).
92 * \param[in] ss logging subsystem (e.g. \ref DLGLOBAL)
93 * \param[in] level logging level (e.g. \ref LOGL_NOTICE)
Neels Hofmeyr983dcb92018-08-20 12:33:22 +020094 * \param[in] caller_file caller's source file string (e.g. __FILE__)
Holger Hans Peter Freyther37a83402017-11-29 11:46:39 +080095 * \param[in] caller_line caller's source line nr (e.g. __LINE__)
96 * \param[in] cont continuation (1) or new line (0)
97 * \param[in] fmt format string
98 * \param[in] args variable argument list
99 */
Eric Wild63e1b2b2021-11-26 21:09:01 +0100100#ifndef LIBOSMOCORE_NO_LOGGING
Holger Hans Peter Freyther37a83402017-11-29 11:46:39 +0800101#define LOGPSRCC(ss, level, caller_file, caller_line, cont, fmt, args...) \
Neels Hofmeyr725698a2016-12-14 17:24:54 +0100102 do { \
Philipp Maier4c44d462022-01-19 11:43:05 +0100103 if (!osmo_log_info) { \
104 if (caller_file) \
105 logp_stub(caller_file, caller_line, cont, fmt, ##args); \
106 else \
107 logp_stub(__FILE__, __LINE__, cont, fmt, ##args); \
108 break; \
109 } \
Neels Hofmeyr725698a2016-12-14 17:24:54 +0100110 if (log_check_level(ss, level)) {\
111 if (caller_file) \
Holger Hans Peter Freyther37a83402017-11-29 11:46:39 +0800112 logp2(ss, level, caller_file, caller_line, cont, fmt, ##args); \
Neels Hofmeyr725698a2016-12-14 17:24:54 +0100113 else \
Neels Hofmeyr983dcb92018-08-20 12:33:22 +0200114 logp2(ss, level, __FILE__, __LINE__, cont, fmt, ##args); \
Neels Hofmeyr725698a2016-12-14 17:24:54 +0100115 }\
116 } while(0)
Eric Wild63e1b2b2021-11-26 21:09:01 +0100117#else
118#define LOGPSRCC(ss, level, caller_file, caller_line, cont, fmt, args...)
119#endif
Neels Hofmeyr725698a2016-12-14 17:24:54 +0100120
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200121/*! different log levels */
122#define LOGL_DEBUG 1 /*!< debugging information */
123#define LOGL_INFO 3 /*!< general information */
124#define LOGL_NOTICE 5 /*!< abnormal/unexpected condition */
125#define LOGL_ERROR 7 /*!< error condition, requires user action */
126#define LOGL_FATAL 8 /*!< fatal, program aborted */
Harald Welte3ae27582010-03-26 21:24:24 +0800127
Neels Hofmeyre883de52019-11-20 04:28:52 +0100128/* logging subsystems defined by the library itself */
Harald Welte2d2e2cc2016-04-25 12:11:20 +0200129#define DLGLOBAL -1 /*!< global logging */
130#define DLLAPD -2 /*!< LAPD implementation */
131#define DLINP -3 /*!< (A-bis) Input sub-system */
132#define DLMUX -4 /*!< Osmocom Multiplex (Osmux) */
133#define DLMI -5 /*!< ISDN-layer below input sub-system */
134#define DLMIB -6 /*!< ISDN layer B-channel */
135#define DLSMS -7 /*!< SMS sub-system */
136#define DLCTRL -8 /*!< Control Interface */
137#define DLGTP -9 /*!< GTP (GPRS Tunneling Protocol */
138#define DLSTATS -10 /*!< Statistics */
Neels Hofmeyr9795cf12016-12-10 17:01:06 +0100139#define DLGSUP -11 /*!< Generic Subscriber Update Protocol */
Harald Weltec0f00072016-04-27 18:32:35 +0200140#define DLOAP -12 /*!< Osmocom Authentication Protocol */
Harald Welte62d32962017-04-03 19:37:11 +0200141#define DLSS7 -13 /*!< Osmocom SS7 */
142#define DLSCCP -14 /*!< Osmocom SCCP */
143#define DLSUA -15 /*!< Osmocom SUA */
144#define DLM3UA -16 /*!< Osmocom M3UA */
Neels Hofmeyra7ccf612017-07-11 18:43:09 +0200145#define DLMGCP -17 /*!< Osmocom MGCP */
Pau Espin Pedrol8fd85572018-02-27 19:43:10 +0100146#define DLJIBUF -18 /*!< Osmocom Jitter Buffer */
Harald Welteb99ed7f2018-08-13 20:54:44 +0200147#define DLRSPRO -19 /*!< Osmocom Remote SIM Protocol */
Alexander Couzens6a161492020-07-12 13:45:50 +0200148#define DLNS -20 /*!< Osmocom NS layer */
Harald Weltefde19ed2020-12-07 21:43:51 +0100149#define DLBSSGP -21 /*!< Osmocom BSSGP layer */
Alexander Couzens6cf65d92021-01-18 17:55:35 +0100150#define DLNSDATA -22 /*!< Osmocom NS layer data pdus */
151#define DLNSSIGNAL -23 /*!< Osmocom NS layer signal pdus */
Harald Welte9fe1f9f2018-11-29 13:47:39 +0100152#define DLIUUP -24 /*!< Osmocom IuUP layer */
Neels Hofmeyr13fa00e2021-11-26 11:02:47 +0100153#define DLPFCP -25 /*!< Osmocom Packet Forwarding Control Protocol */
Vadim Yanitskiy8137d9a2022-08-03 05:35:04 +0700154#define DLCSN1 -26 /*!< CSN.1 (Concrete Syntax Notation 1) codec */
Harald Welted98a8672022-09-03 14:58:24 +0200155#define DLM2PA -27 /*!< Osmocom M2PA (libosmo-sigtran) */
156#define DLM2UA -28 /*!< Reserved for future Osmocom M2UA (libosmo-sigtran) */
157#define OSMO_NUM_DLIB 28 /*!< Number of logging sub-systems in libraries */
Harald Welteb43bc042011-06-27 10:29:17 +0200158
Neels Hofmeyrf2644ae2019-11-20 04:00:29 +0100159/* Colors that can be used in log_info_cat.color */
160#define OSMO_LOGCOLOR_NORMAL NULL
161#define OSMO_LOGCOLOR_RED "\033[1;31m"
162#define OSMO_LOGCOLOR_GREEN "\033[1;32m"
163#define OSMO_LOGCOLOR_YELLOW "\033[1;33m"
164#define OSMO_LOGCOLOR_BLUE "\033[1;34m"
165#define OSMO_LOGCOLOR_PURPLE "\033[1;35m"
166#define OSMO_LOGCOLOR_CYAN "\033[1;36m"
167#define OSMO_LOGCOLOR_DARKRED "\033[31m"
168#define OSMO_LOGCOLOR_DARKGREEN "\033[32m"
169#define OSMO_LOGCOLOR_DARKYELLOW "\033[33m"
170#define OSMO_LOGCOLOR_DARKBLUE "\033[34m"
171#define OSMO_LOGCOLOR_DARKPURPLE "\033[35m"
172#define OSMO_LOGCOLOR_DARKCYAN "\033[36m"
173#define OSMO_LOGCOLOR_DARKGREY "\033[1;30m"
174#define OSMO_LOGCOLOR_GREY "\033[37m"
175#define OSMO_LOGCOLOR_BRIGHTWHITE "\033[1;37m"
176#define OSMO_LOGCOLOR_END "\033[0;m"
177
Neels Hofmeyrfc47b032017-06-20 04:29:38 +0200178/*! Configuration of single log category / sub-system */
Harald Welte3ae27582010-03-26 21:24:24 +0800179struct log_category {
Harald Welte2d2e2cc2016-04-25 12:11:20 +0200180 uint8_t loglevel; /*!< configured log-level */
181 uint8_t enabled; /*!< is logging enabled? */
Harald Welte3ae27582010-03-26 21:24:24 +0800182};
183
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200184/*! Information regarding one logging category */
Harald Welte3ae27582010-03-26 21:24:24 +0800185struct log_info_cat {
Harald Welte18fc4652011-08-17 14:14:17 +0200186 const char *name; /*!< name of category */
187 const char *color; /*!< color string for cateyory */
188 const char *description; /*!< description text */
189 uint8_t loglevel; /*!< currently selected log-level */
190 uint8_t enabled; /*!< is this category enabled or not */
Harald Welte3ae27582010-03-26 21:24:24 +0800191};
192
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200193/*! Indexes to indicate the object currently acted upon.
Neels Hofmeyr492e1802017-02-23 17:45:26 +0100194 * Array indexes for the global \a log_context array. */
Neels Hofmeyr8b86cd72017-02-23 18:03:28 +0100195enum log_ctx_index {
196 LOG_CTX_GB_NSVC,
197 LOG_CTX_GB_BVC,
198 LOG_CTX_BSC_SUBSCR,
199 LOG_CTX_VLR_SUBSCR,
Oliver Smith210acc62019-09-12 17:13:34 +0200200 LOG_CTX_L1_SAPI,
Daniel Willmann751977b2020-12-02 18:59:44 +0100201 LOG_CTX_GB_NSE,
Neels Hofmeyr8b86cd72017-02-23 18:03:28 +0100202 _LOG_CTX_COUNT
Neels Hofmeyr812ba6d2017-02-17 16:35:27 +0100203};
204
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200205/*! Indexes to indicate objects that should be logged.
Neels Hofmeyr492e1802017-02-23 17:45:26 +0100206 * Array indexes to log_target->filter_data and bit indexes for
207 * log_target->filter_map. */
Neels Hofmeyr8b86cd72017-02-23 18:03:28 +0100208enum log_filter_index {
209 LOG_FLT_ALL,
210 LOG_FLT_GB_NSVC,
211 LOG_FLT_GB_BVC,
212 LOG_FLT_BSC_SUBSCR,
213 LOG_FLT_VLR_SUBSCR,
Oliver Smith210acc62019-09-12 17:13:34 +0200214 LOG_FLT_L1_SAPI,
Daniel Willmann751977b2020-12-02 18:59:44 +0100215 LOG_FLT_GB_NSE,
Neels Hofmeyr8b86cd72017-02-23 18:03:28 +0100216 _LOG_FLT_COUNT
Neels Hofmeyr812ba6d2017-02-17 16:35:27 +0100217};
218
Daniel Willmannfd3478c2020-12-02 18:14:17 +0100219/*! Maximum number of logging contexts */
220#define LOG_MAX_CTX _LOG_CTX_COUNT
221/*! Maximum number of logging filters */
222#define LOG_MAX_FILTERS _LOG_FLT_COUNT
223
224/*! Log context information, passed to filter */
225struct log_context {
226 void *ctx[LOG_MAX_CTX+1];
227};
228
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200229/*! Compatibility with older libosmocore versions */
Neels Hofmeyr8b86cd72017-02-23 18:03:28 +0100230#define LOG_FILTER_ALL (1<<LOG_FLT_ALL)
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200231/*! Compatibility with older libosmocore versions */
Neels Hofmeyr8b86cd72017-02-23 18:03:28 +0100232#define GPRS_CTX_NSVC LOG_CTX_GB_NSVC
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200233/*! Compatibility with older libosmocore versions */
Neels Hofmeyr8b86cd72017-02-23 18:03:28 +0100234#define GPRS_CTX_BVC LOG_CTX_GB_BVC
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200235/*! Indexes to indicate the object currently acted upon.
Neels Hofmeyr8b86cd72017-02-23 18:03:28 +0100236 * Array indexes for the global \a log_context array. */
Neels Hofmeyr0d6420b2017-02-23 17:34:35 +0100237
Harald Welte3ae27582010-03-26 21:24:24 +0800238struct log_target;
239
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200240/*! Log filter function */
Harald Welte3ae27582010-03-26 21:24:24 +0800241typedef int log_filter(const struct log_context *ctx,
242 struct log_target *target);
243
Harald Weltefb84f322013-06-06 07:33:54 +0200244struct log_info;
245struct vty;
Harald Welteaa00f992016-12-02 15:30:02 +0100246struct gsmtap_inst;
Harald Weltefb84f322013-06-06 07:33:54 +0200247
248typedef void log_print_filters(struct vty *vty,
249 const struct log_info *info,
250 const struct log_target *tgt);
251
252typedef void log_save_filters(struct vty *vty,
253 const struct log_info *info,
254 const struct log_target *tgt);
255
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200256/*! Logging configuration, passed to \ref log_init */
Harald Welte3ae27582010-03-26 21:24:24 +0800257struct log_info {
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200258 /* filter callback function */
Harald Welte3ae27582010-03-26 21:24:24 +0800259 log_filter *filter_fn;
260
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200261 /*! per-category information */
Holger Hans Peter Freyther06f64552012-09-11 10:31:29 +0200262 const struct log_info_cat *cat;
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200263 /*! total number of categories */
Harald Welte3ae27582010-03-26 21:24:24 +0800264 unsigned int num_cat;
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200265 /*! total number of user categories (not library) */
Harald Welteb43bc042011-06-27 10:29:17 +0200266 unsigned int num_cat_user;
Harald Weltefb84f322013-06-06 07:33:54 +0200267
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200268 /*! filter saving function */
Harald Weltefb84f322013-06-06 07:33:54 +0200269 log_save_filters *save_fn;
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200270 /*! filter saving function */
Harald Weltefb84f322013-06-06 07:33:54 +0200271 log_print_filters *print_fn;
Harald Welte3ae27582010-03-26 21:24:24 +0800272};
273
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200274/*! Type of logging target */
Harald Welte28222962011-02-18 20:37:04 +0100275enum log_target_type {
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200276 LOG_TGT_TYPE_VTY, /*!< VTY logging */
277 LOG_TGT_TYPE_SYSLOG, /*!< syslog based logging */
278 LOG_TGT_TYPE_FILE, /*!< text file logging */
279 LOG_TGT_TYPE_STDERR, /*!< stderr logging */
280 LOG_TGT_TYPE_STRRB, /*!< osmo_strrb-backed logging */
281 LOG_TGT_TYPE_GSMTAP, /*!< GSMTAP network logging */
Vadim Yanitskiye7bf4352020-09-09 03:36:48 +0700282 LOG_TGT_TYPE_SYSTEMD, /*!< systemd journal logging */
Harald Welte28222962011-02-18 20:37:04 +0100283};
284
Neels Hofmeyrbd7bd392018-01-16 01:52:29 +0100285/*! Whether/how to log the source filename (and line number). */
286enum log_filename_type {
287 LOG_FILENAME_NONE,
288 LOG_FILENAME_PATH,
Neels Hofmeyr0e2a9432018-01-16 02:49:48 +0100289 LOG_FILENAME_BASENAME,
Neels Hofmeyrbd7bd392018-01-16 01:52:29 +0100290};
291
Neels Hofmeyr77ae45d2018-08-27 20:32:36 +0200292/*! Where on a log line source file and line should be logged. */
293enum log_filename_pos {
294 LOG_FILENAME_POS_HEADER_END,
295 LOG_FILENAME_POS_LINE_END,
296};
297
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200298/*! structure representing a logging target */
Harald Welte3ae27582010-03-26 21:24:24 +0800299struct log_target {
Pau Espin Pedrol9d3cfef2022-04-27 17:42:26 +0200300 struct llist_head entry; /*!< linked list */
Harald Welte3ae27582010-03-26 21:24:24 +0800301
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200302 /*! Internal data for filtering */
Harald Welte3ae27582010-03-26 21:24:24 +0800303 int filter_map;
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200304 /*! Internal data for filtering */
Harald Welte3ae27582010-03-26 21:24:24 +0800305 void *filter_data[LOG_MAX_FILTERS+1];
306
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200307 /*! logging categories */
Harald Welteb43bc042011-06-27 10:29:17 +0200308 struct log_category *categories;
309
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200310 /*! global log level */
Harald Welte3ae27582010-03-26 21:24:24 +0800311 uint8_t loglevel;
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200312 /*! should color be used when printing log messages? */
Harald Welte87dbca12011-07-16 11:57:53 +0200313 unsigned int use_color:1;
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200314 /*! should log messages be prefixed with a timestamp? */
Harald Welte87dbca12011-07-16 11:57:53 +0200315 unsigned int print_timestamp:1;
Pau Espin Pedrol662d10d2021-02-18 18:19:23 +0100316 /*! should log messages be prefixed with the logger Thread ID? */
317 unsigned int print_tid:1;
Neels Hofmeyrbd7bd392018-01-16 01:52:29 +0100318 /*! DEPRECATED: use print_filename2 instead. */
Holger Hans Peter Freytherdb153362012-09-11 11:24:51 +0200319 unsigned int print_filename:1;
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200320 /*! should log messages be prefixed with a category name? */
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100321 unsigned int print_category:1;
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200322 /*! should log messages be prefixed with an extended timestamp? */
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100323 unsigned int print_ext_timestamp:1;
Harald Welte3ae27582010-03-26 21:24:24 +0800324
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200325 /*! the type of this log taget */
Harald Welte28222962011-02-18 20:37:04 +0100326 enum log_target_type type;
327
Harald Welte3ae27582010-03-26 21:24:24 +0800328 union {
329 struct {
Harald Welteb72867f2020-09-26 21:45:16 +0200330 /* direct, blocking output via stdio */
Harald Welte3ae27582010-03-26 21:24:24 +0800331 FILE *out;
Harald Welte72d0c532010-08-25 19:24:00 +0200332 const char *fname;
Harald Welteb72867f2020-09-26 21:45:16 +0200333 /* indirect output via write_queue and osmo_select_main() */
334 struct osmo_wqueue *wqueue;
Harald Welte0083cd32010-08-25 14:55:44 +0200335 } tgt_file;
Harald Welte3ae27582010-03-26 21:24:24 +0800336
337 struct {
338 int priority;
Harald Welte28222962011-02-18 20:37:04 +0100339 int facility;
Harald Welte3ae27582010-03-26 21:24:24 +0800340 } tgt_syslog;
341
342 struct {
343 void *vty;
344 } tgt_vty;
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000345
346 struct {
347 void *rb;
348 } tgt_rb;
Harald Welteaa00f992016-12-02 15:30:02 +0100349
350 struct {
351 struct gsmtap_inst *gsmtap_inst;
352 const char *ident;
353 const char *hostname;
354 } tgt_gsmtap;
Vadim Yanitskiye7bf4352020-09-09 03:36:48 +0700355
356 struct {
357 bool raw;
358 } sd_journal;
Harald Welte3ae27582010-03-26 21:24:24 +0800359 };
360
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200361 /*! call-back function to be called when the logging framework
Harald Welted7c0a372016-12-02 13:52:59 +0100362 * wants to log a fully formatted string
Katerina Barone-Adesic28c6a02013-02-15 13:27:59 +0100363 * \param[in] target logging target
Harald Welte18fc4652011-08-17 14:14:17 +0200364 * \param[in] level log level of currnet message
365 * \param[in] string the string that is to be written to the log
366 */
Harald Welte76e72ab2011-02-17 15:52:39 +0100367 void (*output) (struct log_target *target, unsigned int level,
368 const char *string);
Harald Welted7c0a372016-12-02 13:52:59 +0100369
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200370 /*! alternative call-back function to which the logging
Harald Welted7c0a372016-12-02 13:52:59 +0100371 * framework passes the unfortmatted input arguments,
372 * i.e. bypassing the internal string formatter
373 * \param[in] target logging target
374 * \param[in] subsys logging sub-system
375 * \param[in] level logging level
376 * \param[in] file soure code file name
377 * \param[in] line source code file line number
378 * \param[in] cont continuation of previous statement?
379 * \param[in] format format string
380 * \param[in] ap vararg list of printf arguments
381 */
382 void (*raw_output)(struct log_target *target, int subsys,
383 unsigned int level, const char *file, int line,
384 int cont, const char *format, va_list ap);
Neels Hofmeyr886e5482018-01-16 01:49:37 +0100385
386 /* Should the log level be printed? */
387 bool print_level;
Neels Hofmeyrbd7bd392018-01-16 01:52:29 +0100388 /* Should we print the subsys in hex like '<000b>'? */
389 bool print_category_hex;
390 /* Should we print the source file and line, and in which way? */
391 enum log_filename_type print_filename2;
Neels Hofmeyr77ae45d2018-08-27 20:32:36 +0200392 /* Where on a log line to put the source file info. */
393 enum log_filename_pos print_filename_pos;
Harald Welte3ae27582010-03-26 21:24:24 +0800394};
395
396/* use the above macros */
Andreas Eversberg2d6563b2012-07-10 13:10:15 +0200397void logp2(int subsys, unsigned int level, const char *file,
Harald Welte3ae27582010-03-26 21:24:24 +0800398 int line, int cont, const char *format, ...)
399 __attribute__ ((format (printf, 6, 7)));
Philipp Maier4c44d462022-01-19 11:43:05 +0100400void logp_stub(const char *file, int line, int cont, const char *format, ...);
Harald Welteb43bc042011-06-27 10:29:17 +0200401int log_init(const struct log_info *inf, void *talloc_ctx);
Philipp Maier4c44d462022-01-19 11:43:05 +0100402int log_initialized(void);
Harald Welte69e6c3c2016-04-20 10:41:27 +0200403void log_fini(void);
Jacob Erlbeckde6dd722015-11-17 11:52:24 +0100404int log_check_level(int subsys, unsigned int level);
Harald Welte3ae27582010-03-26 21:24:24 +0800405
406/* context management */
407void log_reset_context(void);
408int log_set_context(uint8_t ctx, void *value);
409
410/* filter on the targets */
411void log_set_all_filter(struct log_target *target, int);
412
413void log_set_use_color(struct log_target *target, int);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100414void log_set_print_extended_timestamp(struct log_target *target, int);
Harald Welte3ae27582010-03-26 21:24:24 +0800415void log_set_print_timestamp(struct log_target *target, int);
Pau Espin Pedrol662d10d2021-02-18 18:19:23 +0100416void log_set_print_tid(struct log_target *target, int);
Pau Espin Pedrol6e9dd022021-02-18 19:27:38 +0100417void log_set_print_filename(struct log_target *target, int) OSMO_DEPRECATED("Use log_set_print_filename2() instead");
Neels Hofmeyrbd7bd392018-01-16 01:52:29 +0100418void log_set_print_filename2(struct log_target *target, enum log_filename_type lft);
Neels Hofmeyr77ae45d2018-08-27 20:32:36 +0200419void log_set_print_filename_pos(struct log_target *target, enum log_filename_pos pos);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100420void log_set_print_category(struct log_target *target, int);
Neels Hofmeyrbd7bd392018-01-16 01:52:29 +0100421void log_set_print_category_hex(struct log_target *target, int);
Neels Hofmeyr886e5482018-01-16 01:49:37 +0100422void log_set_print_level(struct log_target *target, int);
Harald Welte3ae27582010-03-26 21:24:24 +0800423void log_set_log_level(struct log_target *target, int log_level);
424void log_parse_category_mask(struct log_target *target, const char* mask);
Harald Welteaa00f992016-12-02 15:30:02 +0100425const char* log_category_name(int subsys);
Max15b6d412017-07-06 16:57:15 +0200426int log_parse_level(const char *lvl) OSMO_DEPRECATED_OUTSIDE_LIBOSMOCORE;
427const char *log_level_str(unsigned int lvl) OSMO_DEPRECATED_OUTSIDE_LIBOSMOCORE;
Harald Welte3ae27582010-03-26 21:24:24 +0800428int log_parse_category(const char *category);
429void log_set_category_filter(struct log_target *target, int category,
430 int enable, int level);
431
432/* management of the targets */
433struct log_target *log_target_create(void);
Harald Welte72d0c532010-08-25 19:24:00 +0200434void log_target_destroy(struct log_target *target);
Harald Welte3ae27582010-03-26 21:24:24 +0800435struct log_target *log_target_create_stderr(void);
Harald Welte72d0c532010-08-25 19:24:00 +0200436struct log_target *log_target_create_file(const char *fname);
Harald Welte46cfd772011-02-17 15:56:56 +0100437struct log_target *log_target_create_syslog(const char *ident, int option,
438 int facility);
Harald Welteaa00f992016-12-02 15:30:02 +0100439struct log_target *log_target_create_gsmtap(const char *host, uint16_t port,
440 const char *ident,
441 bool ofd_wq_mode,
442 bool add_sink);
Vadim Yanitskiye7bf4352020-09-09 03:36:48 +0700443struct log_target *log_target_create_systemd(bool raw);
444void log_target_systemd_set_raw(struct log_target *target, bool raw);
Harald Welte72d0c532010-08-25 19:24:00 +0200445int log_target_file_reopen(struct log_target *tgt);
Harald Welteb72867f2020-09-26 21:45:16 +0200446int log_target_file_switch_to_stream(struct log_target *tgt);
447int log_target_file_switch_to_wqueue(struct log_target *tgt);
Harald Welte4de854d2013-03-18 19:01:40 +0100448int log_targets_reopen(void);
Harald Welte72d0c532010-08-25 19:24:00 +0200449
Harald Welte3ae27582010-03-26 21:24:24 +0800450void log_add_target(struct log_target *target);
451void log_del_target(struct log_target *target);
452
Harald Weltee6fb8902022-01-09 12:00:03 +0100453struct log_target *log_target_find(enum log_target_type type, const char *fname);
Harald Welte28222962011-02-18 20:37:04 +0100454
Pau Espin Pedrold12f6982019-09-17 18:38:58 +0200455void log_enable_multithread(void);
456
457void log_tgt_mutex_lock_impl(void);
458void log_tgt_mutex_unlock_impl(void);
459#define LOG_MTX_DEBUG 0
460#if LOG_MTX_DEBUG
461 #include <pthread.h>
462 #define log_tgt_mutex_lock() do { fprintf(stderr, "[%lu] %s:%d [%s] lock\n", pthread_self(), __FILE__, __LINE__, __func__); log_tgt_mutex_lock_impl(); } while (0)
463 #define log_tgt_mutex_unlock() do { fprintf(stderr, "[%lu] %s:%d [%s] unlock\n", pthread_self(), __FILE__, __LINE__, __func__); log_tgt_mutex_unlock_impl(); } while (0)
464#else
465 #define log_tgt_mutex_lock() log_tgt_mutex_lock_impl()
466 #define log_tgt_mutex_unlock() log_tgt_mutex_unlock_impl()
467#endif
468
Sylvain Munautdca7d2c2012-04-18 21:53:23 +0200469/*! @} */