blob: 7c8a7ef57965e65fe73f14e5a19682e400ba5562 [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 * @{
Harald Weltebd598e32011-08-16 23:26:52 +02005 */
6
Harald Welte18fc4652011-08-17 14:14:17 +02007/*! \file logging.h */
8
Harald Welte3ae27582010-03-26 21:24:24 +08009#include <stdio.h>
10#include <stdint.h>
Christoph Fritzab7c9c72011-09-01 16:22:17 +020011#include <stdarg.h>
Harald Welteaa00f992016-12-02 15:30:02 +010012#include <stdbool.h>
Maxaa1bc012017-01-13 11:01:12 +010013#include <osmocom/core/defs.h>
Pablo Neira Ayuso83419342011-03-22 16:36:13 +010014#include <osmocom/core/linuxlist.h>
Harald Welte3ae27582010-03-26 21:24:24 +080015
Harald Weltebd598e32011-08-16 23:26:52 +020016/*! \brief Maximum number of logging contexts */
Harald Welte3ae27582010-03-26 21:24:24 +080017#define LOG_MAX_CTX 8
Harald Weltebd598e32011-08-16 23:26:52 +020018/*! \brief Maximum number of logging filters */
Harald Welte3ae27582010-03-26 21:24:24 +080019#define LOG_MAX_FILTERS 8
20
21#define DEBUG
22
23#ifdef DEBUG
Harald Welte2d2e2cc2016-04-25 12:11:20 +020024/*! \brief Log a debug message through the Osmocom logging framework
25 * \param[in] ss logging subsystem (e.g. \ref DLGLOBAL)
26 * \param[in] fmt format string
27 * \param[in] args variable argument list
28 */
Maxaa1bc012017-01-13 11:01:12 +010029#define DEBUGP(ss, fmt, args...) LOGP(ss, LOGL_DEBUG, fmt, ##args)
30#define DEBUGPC(ss, fmt, args...) LOGPC(ss, LOGL_DEBUG, fmt, ##args)
Harald Welte3ae27582010-03-26 21:24:24 +080031#else
32#define DEBUGP(xss, fmt, args...)
33#define DEBUGPC(ss, fmt, args...)
34#endif
35
Harald Welte3ae27582010-03-26 21:24:24 +080036
Holger Hans Peter Freytherfb4bfc22012-07-12 09:26:25 +020037void osmo_vlogp(int subsys, int level, const char *file, int line,
Harald Welte36c5a3e2011-08-27 14:33:19 +020038 int cont, const char *format, va_list ap);
39
Maxaa1bc012017-01-13 11:01:12 +010040void 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 +080041
Harald Weltebd598e32011-08-16 23:26:52 +020042/*! \brief Log a new message through the Osmocom logging framework
43 * \param[in] ss logging subsystem (e.g. \ref DLGLOBAL)
44 * \param[in] level logging level (e.g. \ref LOGL_NOTICE)
45 * \param[in] fmt format string
46 * \param[in] args variable argument list
47 */
Harald Welte3ae27582010-03-26 21:24:24 +080048#define LOGP(ss, level, fmt, args...) \
Neels Hofmeyr725698a2016-12-14 17:24:54 +010049 LOGPSRC(ss, level, NULL, 0, fmt, ## args)
Harald Weltebd598e32011-08-16 23:26:52 +020050
51/*! \brief Continue a log message through the Osmocom logging framework
52 * \param[in] ss logging subsystem (e.g. \ref DLGLOBAL)
53 * \param[in] level logging level (e.g. \ref LOGL_NOTICE)
54 * \param[in] fmt format string
55 * \param[in] args variable argument list
56 */
Harald Welte3ae27582010-03-26 21:24:24 +080057#define LOGPC(ss, level, fmt, args...) \
Jacob Erlbecka89d22c2015-11-17 11:52:25 +010058 do { \
59 if (log_check_level(ss, level)) \
Harald Welte3d792402016-05-10 15:23:06 +020060 logp2(ss, level, __BASE_FILE__, __LINE__, 1, fmt, ##args); \
Jacob Erlbecka89d22c2015-11-17 11:52:25 +010061 } while(0)
Harald Welte3ae27582010-03-26 21:24:24 +080062
Neels Hofmeyr725698a2016-12-14 17:24:54 +010063/*! \brief Log through the Osmocom logging framework with explicit source.
64 * If caller_file is passed as NULL, __BASE_FILE__ and __LINE__ are used
65 * instead of caller_file and caller_line (so that this macro here defines
66 * both cases in the same place, and to catch cases where callers fail to pass
67 * a non-null filename string).
68 * \param[in] ss logging subsystem (e.g. \ref DLGLOBAL)
69 * \param[in] level logging level (e.g. \ref LOGL_NOTICE)
70 * \param[in] caller_file caller's source file string (e.g. __BASE_FILE__)
71 * \param[in] caller_line caller's source line nr (e.g. __LINE__)
72 * \param[in] fmt format string
73 * \param[in] args variable argument list
74 */
75#define LOGPSRC(ss, level, caller_file, caller_line, fmt, args...) \
76 do { \
77 if (log_check_level(ss, level)) {\
78 if (caller_file) \
79 logp2(ss, level, caller_file, caller_line, 0, fmt, ##args); \
80 else \
81 logp2(ss, level, __BASE_FILE__, __LINE__, 0, fmt, ##args); \
82 }\
83 } while(0)
84
Harald Welte18fc4652011-08-17 14:14:17 +020085/*! \brief different log levels */
86#define LOGL_DEBUG 1 /*!< \brief debugging information */
Harald Welte2d2e2cc2016-04-25 12:11:20 +020087#define LOGL_INFO 3 /*!< \brief general information */
Harald Welte18fc4652011-08-17 14:14:17 +020088#define LOGL_NOTICE 5 /*!< \brief abnormal/unexpected condition */
89#define LOGL_ERROR 7 /*!< \brief error condition, requires user action */
90#define LOGL_FATAL 8 /*!< \brief fatal, program aborted */
Harald Welte3ae27582010-03-26 21:24:24 +080091
Harald Welteb43bc042011-06-27 10:29:17 +020092/* logging levels defined by the library itself */
Harald Welte2d2e2cc2016-04-25 12:11:20 +020093#define DLGLOBAL -1 /*!< global logging */
94#define DLLAPD -2 /*!< LAPD implementation */
95#define DLINP -3 /*!< (A-bis) Input sub-system */
96#define DLMUX -4 /*!< Osmocom Multiplex (Osmux) */
97#define DLMI -5 /*!< ISDN-layer below input sub-system */
98#define DLMIB -6 /*!< ISDN layer B-channel */
99#define DLSMS -7 /*!< SMS sub-system */
100#define DLCTRL -8 /*!< Control Interface */
101#define DLGTP -9 /*!< GTP (GPRS Tunneling Protocol */
102#define DLSTATS -10 /*!< Statistics */
Neels Hofmeyr9795cf12016-12-10 17:01:06 +0100103#define DLGSUP -11 /*!< Generic Subscriber Update Protocol */
Harald Weltec0f00072016-04-27 18:32:35 +0200104#define DLOAP -12 /*!< Osmocom Authentication Protocol */
105#define OSMO_NUM_DLIB 12 /*!< Number of logging sub-systems in libraries */
Harald Welteb43bc042011-06-27 10:29:17 +0200106
Harald Welte2d2e2cc2016-04-25 12:11:20 +0200107/*! Configuration of singgle log category / sub-system */
Harald Welte3ae27582010-03-26 21:24:24 +0800108struct log_category {
Harald Welte2d2e2cc2016-04-25 12:11:20 +0200109 uint8_t loglevel; /*!< configured log-level */
110 uint8_t enabled; /*!< is logging enabled? */
Harald Welte3ae27582010-03-26 21:24:24 +0800111};
112
Harald Welte18fc4652011-08-17 14:14:17 +0200113/*! \brief Information regarding one logging category */
Harald Welte3ae27582010-03-26 21:24:24 +0800114struct log_info_cat {
Harald Welte18fc4652011-08-17 14:14:17 +0200115 const char *name; /*!< name of category */
116 const char *color; /*!< color string for cateyory */
117 const char *description; /*!< description text */
118 uint8_t loglevel; /*!< currently selected log-level */
119 uint8_t enabled; /*!< is this category enabled or not */
Harald Welte3ae27582010-03-26 21:24:24 +0800120};
121
Harald Welte18fc4652011-08-17 14:14:17 +0200122/*! \brief Log context information, passed to filter */
Harald Welte3ae27582010-03-26 21:24:24 +0800123struct log_context {
124 void *ctx[LOG_MAX_CTX+1];
125};
126
Neels Hofmeyr812ba6d2017-02-17 16:35:27 +0100127enum logging_ctx_items {
128 LOGGING_CTX_GB_NSVC,
129 LOGGING_CTX_GB_BVC,
130 LOGGING_CTX_BSC_SUBSCR,
131 LOGGING_CTX_VLR_SUBSCR,
132 _LOGGING_CTX_COUNT
133};
134
135enum logging_filters {
136 LOGGING_FILTER_ALL,
137 LOGGING_FILTER_GB_NSVC,
138 LOGGING_FILTER_GB_BVC,
139 LOGGING_FILTER_BSC_SUBSCR,
140 LOGGING_FILTER_VLR_SUBSCR,
141 _LOGGING_FILTER_COUNT
142};
143
Neels Hofmeyr0d6420b2017-02-23 17:34:35 +0100144/*! \brief Compatibility with older libosmocore versions */
145#define LOG_FILTER_ALL (1<<LOGGING_FILTER_ALL)
146/*! \brief Compatibility with older libosmocore versions */
147#define GPRS_CTX_NSVC LOGGING_CTX_GB_NSVC
148/*! \brief Compatibility with older libosmocore versions */
149#define GPRS_CTX_BVC LOGGING_CTX_GB_BVC
150
Harald Welte3ae27582010-03-26 21:24:24 +0800151struct log_target;
152
Harald Welte18fc4652011-08-17 14:14:17 +0200153/*! \brief Log filter function */
Harald Welte3ae27582010-03-26 21:24:24 +0800154typedef int log_filter(const struct log_context *ctx,
155 struct log_target *target);
156
Harald Weltefb84f322013-06-06 07:33:54 +0200157struct log_info;
158struct vty;
Harald Welteaa00f992016-12-02 15:30:02 +0100159struct gsmtap_inst;
Harald Weltefb84f322013-06-06 07:33:54 +0200160
161typedef void log_print_filters(struct vty *vty,
162 const struct log_info *info,
163 const struct log_target *tgt);
164
165typedef void log_save_filters(struct vty *vty,
166 const struct log_info *info,
167 const struct log_target *tgt);
168
Harald Welte18fc4652011-08-17 14:14:17 +0200169/*! \brief Logging configuration, passed to \ref log_init */
Harald Welte3ae27582010-03-26 21:24:24 +0800170struct log_info {
Harald Welte18fc4652011-08-17 14:14:17 +0200171 /* \brief filter callback function */
Harald Welte3ae27582010-03-26 21:24:24 +0800172 log_filter *filter_fn;
173
Harald Welte18fc4652011-08-17 14:14:17 +0200174 /*! \brief per-category information */
Holger Hans Peter Freyther06f64552012-09-11 10:31:29 +0200175 const struct log_info_cat *cat;
Harald Welte18fc4652011-08-17 14:14:17 +0200176 /*! \brief total number of categories */
Harald Welte3ae27582010-03-26 21:24:24 +0800177 unsigned int num_cat;
Harald Welte18fc4652011-08-17 14:14:17 +0200178 /*! \brief total number of user categories (not library) */
Harald Welteb43bc042011-06-27 10:29:17 +0200179 unsigned int num_cat_user;
Harald Weltefb84f322013-06-06 07:33:54 +0200180
Harald Welte2d2e2cc2016-04-25 12:11:20 +0200181 /*! \brief filter saving function */
Harald Weltefb84f322013-06-06 07:33:54 +0200182 log_save_filters *save_fn;
Harald Welte2d2e2cc2016-04-25 12:11:20 +0200183 /*! \brief filter saving function */
Harald Weltefb84f322013-06-06 07:33:54 +0200184 log_print_filters *print_fn;
Harald Welte3ae27582010-03-26 21:24:24 +0800185};
186
Harald Welte18fc4652011-08-17 14:14:17 +0200187/*! \brief Type of logging target */
Harald Welte28222962011-02-18 20:37:04 +0100188enum log_target_type {
Harald Welte18fc4652011-08-17 14:14:17 +0200189 LOG_TGT_TYPE_VTY, /*!< \brief VTY logging */
190 LOG_TGT_TYPE_SYSLOG, /*!< \brief syslog based logging */
191 LOG_TGT_TYPE_FILE, /*!< \brief text file logging */
192 LOG_TGT_TYPE_STDERR, /*!< \brief stderr logging */
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000193 LOG_TGT_TYPE_STRRB, /*!< \brief osmo_strrb-backed logging */
Harald Welteaa00f992016-12-02 15:30:02 +0100194 LOG_TGT_TYPE_GSMTAP, /*!< \brief GSMTAP network logging */
Harald Welte28222962011-02-18 20:37:04 +0100195};
196
Harald Welte18fc4652011-08-17 14:14:17 +0200197/*! \brief structure representing a logging target */
Harald Welte3ae27582010-03-26 21:24:24 +0800198struct log_target {
Harald Welte18fc4652011-08-17 14:14:17 +0200199 struct llist_head entry; /*!< \brief linked list */
Harald Welte3ae27582010-03-26 21:24:24 +0800200
Harald Welte18fc4652011-08-17 14:14:17 +0200201 /*! \brief Internal data for filtering */
Harald Welte3ae27582010-03-26 21:24:24 +0800202 int filter_map;
Harald Welte18fc4652011-08-17 14:14:17 +0200203 /*! \brief Internal data for filtering */
Harald Welte3ae27582010-03-26 21:24:24 +0800204 void *filter_data[LOG_MAX_FILTERS+1];
205
Harald Welte18fc4652011-08-17 14:14:17 +0200206 /*! \brief logging categories */
Harald Welteb43bc042011-06-27 10:29:17 +0200207 struct log_category *categories;
208
Harald Welte18fc4652011-08-17 14:14:17 +0200209 /*! \brief global log level */
Harald Welte3ae27582010-03-26 21:24:24 +0800210 uint8_t loglevel;
Harald Welte18fc4652011-08-17 14:14:17 +0200211 /*! \brief should color be used when printing log messages? */
Harald Welte87dbca12011-07-16 11:57:53 +0200212 unsigned int use_color:1;
Harald Welte18fc4652011-08-17 14:14:17 +0200213 /*! \brief should log messages be prefixed with a timestamp? */
Harald Welte87dbca12011-07-16 11:57:53 +0200214 unsigned int print_timestamp:1;
Holger Hans Peter Freytherdb153362012-09-11 11:24:51 +0200215 /*! \brief should log messages be prefixed with a filename? */
216 unsigned int print_filename:1;
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100217 /*! \brief should log messages be prefixed with a category name? */
218 unsigned int print_category:1;
219 /*! \brief should log messages be prefixed with an extended timestamp? */
220 unsigned int print_ext_timestamp:1;
Harald Welte3ae27582010-03-26 21:24:24 +0800221
Harald Welte18fc4652011-08-17 14:14:17 +0200222 /*! \brief the type of this log taget */
Harald Welte28222962011-02-18 20:37:04 +0100223 enum log_target_type type;
224
Harald Welte3ae27582010-03-26 21:24:24 +0800225 union {
226 struct {
227 FILE *out;
Harald Welte72d0c532010-08-25 19:24:00 +0200228 const char *fname;
Harald Welte0083cd32010-08-25 14:55:44 +0200229 } tgt_file;
Harald Welte3ae27582010-03-26 21:24:24 +0800230
231 struct {
232 int priority;
Harald Welte28222962011-02-18 20:37:04 +0100233 int facility;
Harald Welte3ae27582010-03-26 21:24:24 +0800234 } tgt_syslog;
235
236 struct {
237 void *vty;
238 } tgt_vty;
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000239
240 struct {
241 void *rb;
242 } tgt_rb;
Harald Welteaa00f992016-12-02 15:30:02 +0100243
244 struct {
245 struct gsmtap_inst *gsmtap_inst;
246 const char *ident;
247 const char *hostname;
248 } tgt_gsmtap;
Harald Welte3ae27582010-03-26 21:24:24 +0800249 };
250
Harald Welte18fc4652011-08-17 14:14:17 +0200251 /*! \brief call-back function to be called when the logging framework
Harald Welted7c0a372016-12-02 13:52:59 +0100252 * wants to log a fully formatted string
Katerina Barone-Adesic28c6a02013-02-15 13:27:59 +0100253 * \param[in] target logging target
Harald Welte18fc4652011-08-17 14:14:17 +0200254 * \param[in] level log level of currnet message
255 * \param[in] string the string that is to be written to the log
256 */
Harald Welte76e72ab2011-02-17 15:52:39 +0100257 void (*output) (struct log_target *target, unsigned int level,
258 const char *string);
Harald Welted7c0a372016-12-02 13:52:59 +0100259
260 /*! \brief alternative call-back function to which the logging
261 * framework passes the unfortmatted input arguments,
262 * i.e. bypassing the internal string formatter
263 * \param[in] target logging target
264 * \param[in] subsys logging sub-system
265 * \param[in] level logging level
266 * \param[in] file soure code file name
267 * \param[in] line source code file line number
268 * \param[in] cont continuation of previous statement?
269 * \param[in] format format string
270 * \param[in] ap vararg list of printf arguments
271 */
272 void (*raw_output)(struct log_target *target, int subsys,
273 unsigned int level, const char *file, int line,
274 int cont, const char *format, va_list ap);
Harald Welte3ae27582010-03-26 21:24:24 +0800275};
276
277/* use the above macros */
Andreas Eversberg2d6563b2012-07-10 13:10:15 +0200278void logp2(int subsys, unsigned int level, const char *file,
Harald Welte3ae27582010-03-26 21:24:24 +0800279 int line, int cont, const char *format, ...)
280 __attribute__ ((format (printf, 6, 7)));
Harald Welteb43bc042011-06-27 10:29:17 +0200281int log_init(const struct log_info *inf, void *talloc_ctx);
Harald Welte69e6c3c2016-04-20 10:41:27 +0200282void log_fini(void);
Jacob Erlbeckde6dd722015-11-17 11:52:24 +0100283int log_check_level(int subsys, unsigned int level);
Harald Welte3ae27582010-03-26 21:24:24 +0800284
285/* context management */
286void log_reset_context(void);
287int log_set_context(uint8_t ctx, void *value);
288
289/* filter on the targets */
290void log_set_all_filter(struct log_target *target, int);
291
292void log_set_use_color(struct log_target *target, int);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100293void log_set_print_extended_timestamp(struct log_target *target, int);
Harald Welte3ae27582010-03-26 21:24:24 +0800294void log_set_print_timestamp(struct log_target *target, int);
Holger Hans Peter Freytherdb153362012-09-11 11:24:51 +0200295void log_set_print_filename(struct log_target *target, int);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100296void log_set_print_category(struct log_target *target, int);
Harald Welte3ae27582010-03-26 21:24:24 +0800297void log_set_log_level(struct log_target *target, int log_level);
298void log_parse_category_mask(struct log_target *target, const char* mask);
Harald Welteaa00f992016-12-02 15:30:02 +0100299const char* log_category_name(int subsys);
Harald Welte3ae27582010-03-26 21:24:24 +0800300int log_parse_level(const char *lvl);
Harald Welte9ac22252010-05-11 11:19:40 +0200301const char *log_level_str(unsigned int lvl);
Harald Welte3ae27582010-03-26 21:24:24 +0800302int log_parse_category(const char *category);
303void log_set_category_filter(struct log_target *target, int category,
304 int enable, int level);
305
306/* management of the targets */
307struct log_target *log_target_create(void);
Harald Welte72d0c532010-08-25 19:24:00 +0200308void log_target_destroy(struct log_target *target);
Harald Welte3ae27582010-03-26 21:24:24 +0800309struct log_target *log_target_create_stderr(void);
Harald Welte72d0c532010-08-25 19:24:00 +0200310struct log_target *log_target_create_file(const char *fname);
Harald Welte46cfd772011-02-17 15:56:56 +0100311struct log_target *log_target_create_syslog(const char *ident, int option,
312 int facility);
Harald Welteaa00f992016-12-02 15:30:02 +0100313struct log_target *log_target_create_gsmtap(const char *host, uint16_t port,
314 const char *ident,
315 bool ofd_wq_mode,
316 bool add_sink);
Harald Welte72d0c532010-08-25 19:24:00 +0200317int log_target_file_reopen(struct log_target *tgt);
Harald Welte4de854d2013-03-18 19:01:40 +0100318int log_targets_reopen(void);
Harald Welte72d0c532010-08-25 19:24:00 +0200319
Harald Welte3ae27582010-03-26 21:24:24 +0800320void log_add_target(struct log_target *target);
321void log_del_target(struct log_target *target);
322
Pablo Neira Ayuso04139f12011-03-09 13:05:08 +0100323/* Generate command string for VTY use */
324const char *log_vty_command_string(const struct log_info *info);
325const char *log_vty_command_description(const struct log_info *info);
Harald Welte7638af92010-05-11 16:39:22 +0200326
Harald Welte28222962011-02-18 20:37:04 +0100327struct log_target *log_target_find(int type, const char *fname);
328extern struct llist_head osmo_log_target_list;
329
Sylvain Munautdca7d2c2012-04-18 21:53:23 +0200330/*! @} */