blob: 31934111320aba4a062e3cd74df38ce2ec159353 [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>
Pablo Neira Ayuso83419342011-03-22 16:36:13 +010012#include <osmocom/core/linuxlist.h>
Harald Welte3ae27582010-03-26 21:24:24 +080013
Harald Weltebd598e32011-08-16 23:26:52 +020014/*! \brief Maximum number of logging contexts */
Harald Welte3ae27582010-03-26 21:24:24 +080015#define LOG_MAX_CTX 8
Harald Weltebd598e32011-08-16 23:26:52 +020016/*! \brief Maximum number of logging filters */
Harald Welte3ae27582010-03-26 21:24:24 +080017#define LOG_MAX_FILTERS 8
18
19#define DEBUG
20
21#ifdef DEBUG
Jacob Erlbecka89d22c2015-11-17 11:52:25 +010022#define DEBUGP(ss, fmt, args...) \
23 do { \
24 if (log_check_level(ss, LOGL_DEBUG)) \
25 logp(ss, __FILE__, __LINE__, 0, fmt, ## args); \
26 } while(0)
27
28#define DEBUGPC(ss, fmt, args...) \
29 do { \
30 if (log_check_level(ss, LOGL_DEBUG)) \
31 logp(ss, __FILE__, __LINE__, 1, fmt, ## args); \
32 } while(0)
33
Harald Welte3ae27582010-03-26 21:24:24 +080034#else
35#define DEBUGP(xss, fmt, args...)
36#define DEBUGPC(ss, fmt, args...)
37#endif
38
Harald Welte3ae27582010-03-26 21:24:24 +080039
Holger Hans Peter Freytherfb4bfc22012-07-12 09:26:25 +020040void osmo_vlogp(int subsys, int level, const char *file, int line,
Harald Welte36c5a3e2011-08-27 14:33:19 +020041 int cont, const char *format, va_list ap);
42
Andreas Eversberg2d6563b2012-07-10 13:10:15 +020043void logp(int subsys, const char *file, int line, int cont, const char *format, ...) __attribute__ ((format (printf, 5, 6)));
Harald Welte3ae27582010-03-26 21:24:24 +080044
Harald Weltebd598e32011-08-16 23:26:52 +020045/*! \brief Log a new message through the Osmocom logging framework
46 * \param[in] ss logging subsystem (e.g. \ref DLGLOBAL)
47 * \param[in] level logging level (e.g. \ref LOGL_NOTICE)
48 * \param[in] fmt format string
49 * \param[in] args variable argument list
50 */
Harald Welte3ae27582010-03-26 21:24:24 +080051#define LOGP(ss, level, fmt, args...) \
Jacob Erlbecka89d22c2015-11-17 11:52:25 +010052 do { \
53 if (log_check_level(ss, level)) \
54 logp2(ss, level, __FILE__, __LINE__, 0, fmt, ##args); \
55 } while(0)
Harald Weltebd598e32011-08-16 23:26:52 +020056
57/*! \brief Continue a log message through the Osmocom logging framework
58 * \param[in] ss logging subsystem (e.g. \ref DLGLOBAL)
59 * \param[in] level logging level (e.g. \ref LOGL_NOTICE)
60 * \param[in] fmt format string
61 * \param[in] args variable argument list
62 */
Harald Welte3ae27582010-03-26 21:24:24 +080063#define LOGPC(ss, level, fmt, args...) \
Jacob Erlbecka89d22c2015-11-17 11:52:25 +010064 do { \
65 if (log_check_level(ss, level)) \
66 logp2(ss, level, __FILE__, __LINE__, 1, fmt, ##args); \
67 } while(0)
Harald Welte3ae27582010-03-26 21:24:24 +080068
Harald Welte18fc4652011-08-17 14:14:17 +020069/*! \brief different log levels */
70#define LOGL_DEBUG 1 /*!< \brief debugging information */
Harald Welte3ae27582010-03-26 21:24:24 +080071#define LOGL_INFO 3
Harald Welte18fc4652011-08-17 14:14:17 +020072#define LOGL_NOTICE 5 /*!< \brief abnormal/unexpected condition */
73#define LOGL_ERROR 7 /*!< \brief error condition, requires user action */
74#define LOGL_FATAL 8 /*!< \brief fatal, program aborted */
Harald Welte3ae27582010-03-26 21:24:24 +080075
76#define LOG_FILTER_ALL 0x0001
77
Harald Welteb43bc042011-06-27 10:29:17 +020078/* logging levels defined by the library itself */
79#define DLGLOBAL -1
root8a996b42011-09-26 11:22:21 +020080#define DLLAPD -2
Harald Welte892e6212011-07-19 14:31:44 +020081#define DLINP -3
82#define DLMUX -4
83#define DLMI -5
84#define DLMIB -6
Andreas Eversbergc626da92011-10-28 03:53:50 +020085#define DLSMS -7
Harald Welte7fd0c832014-08-20 19:58:13 +020086#define DLCTRL -8
Holger Hans Peter Freythera5dc19d2014-12-04 14:35:21 +010087#define DLGTP -9
Jacob Erlbeck79125ec2015-11-02 15:17:50 +010088#define DLSTATS -10
89#define OSMO_NUM_DLIB 10
Harald Welteb43bc042011-06-27 10:29:17 +020090
Harald Welte3ae27582010-03-26 21:24:24 +080091struct log_category {
92 uint8_t loglevel;
93 uint8_t enabled;
94};
95
Harald Welte18fc4652011-08-17 14:14:17 +020096/*! \brief Information regarding one logging category */
Harald Welte3ae27582010-03-26 21:24:24 +080097struct log_info_cat {
Harald Welte18fc4652011-08-17 14:14:17 +020098 const char *name; /*!< name of category */
99 const char *color; /*!< color string for cateyory */
100 const char *description; /*!< description text */
101 uint8_t loglevel; /*!< currently selected log-level */
102 uint8_t enabled; /*!< is this category enabled or not */
Harald Welte3ae27582010-03-26 21:24:24 +0800103};
104
Harald Welte18fc4652011-08-17 14:14:17 +0200105/*! \brief Log context information, passed to filter */
Harald Welte3ae27582010-03-26 21:24:24 +0800106struct log_context {
107 void *ctx[LOG_MAX_CTX+1];
108};
109
110struct log_target;
111
Harald Welte18fc4652011-08-17 14:14:17 +0200112/*! \brief Log filter function */
Harald Welte3ae27582010-03-26 21:24:24 +0800113typedef int log_filter(const struct log_context *ctx,
114 struct log_target *target);
115
Harald Weltefb84f322013-06-06 07:33:54 +0200116struct log_info;
117struct vty;
118
119typedef void log_print_filters(struct vty *vty,
120 const struct log_info *info,
121 const struct log_target *tgt);
122
123typedef void log_save_filters(struct vty *vty,
124 const struct log_info *info,
125 const struct log_target *tgt);
126
Harald Welte18fc4652011-08-17 14:14:17 +0200127/*! \brief Logging configuration, passed to \ref log_init */
Harald Welte3ae27582010-03-26 21:24:24 +0800128struct log_info {
Harald Welte18fc4652011-08-17 14:14:17 +0200129 /* \brief filter callback function */
Harald Welte3ae27582010-03-26 21:24:24 +0800130 log_filter *filter_fn;
131
Harald Welte18fc4652011-08-17 14:14:17 +0200132 /*! \brief per-category information */
Holger Hans Peter Freyther06f64552012-09-11 10:31:29 +0200133 const struct log_info_cat *cat;
Harald Welte18fc4652011-08-17 14:14:17 +0200134 /*! \brief total number of categories */
Harald Welte3ae27582010-03-26 21:24:24 +0800135 unsigned int num_cat;
Harald Welte18fc4652011-08-17 14:14:17 +0200136 /*! \brief total number of user categories (not library) */
Harald Welteb43bc042011-06-27 10:29:17 +0200137 unsigned int num_cat_user;
Harald Weltefb84f322013-06-06 07:33:54 +0200138
139 /* \brief filter saving function */
140 log_save_filters *save_fn;
141 /* \brief filter saving function */
142 log_print_filters *print_fn;
Harald Welte3ae27582010-03-26 21:24:24 +0800143};
144
Harald Welte18fc4652011-08-17 14:14:17 +0200145/*! \brief Type of logging target */
Harald Welte28222962011-02-18 20:37:04 +0100146enum log_target_type {
Harald Welte18fc4652011-08-17 14:14:17 +0200147 LOG_TGT_TYPE_VTY, /*!< \brief VTY logging */
148 LOG_TGT_TYPE_SYSLOG, /*!< \brief syslog based logging */
149 LOG_TGT_TYPE_FILE, /*!< \brief text file logging */
150 LOG_TGT_TYPE_STDERR, /*!< \brief stderr logging */
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000151 LOG_TGT_TYPE_STRRB, /*!< \brief osmo_strrb-backed logging */
Harald Welte28222962011-02-18 20:37:04 +0100152};
153
Harald Welte18fc4652011-08-17 14:14:17 +0200154/*! \brief structure representing a logging target */
Harald Welte3ae27582010-03-26 21:24:24 +0800155struct log_target {
Harald Welte18fc4652011-08-17 14:14:17 +0200156 struct llist_head entry; /*!< \brief linked list */
Harald Welte3ae27582010-03-26 21:24:24 +0800157
Harald Welte18fc4652011-08-17 14:14:17 +0200158 /*! \brief Internal data for filtering */
Harald Welte3ae27582010-03-26 21:24:24 +0800159 int filter_map;
Harald Welte18fc4652011-08-17 14:14:17 +0200160 /*! \brief Internal data for filtering */
Harald Welte3ae27582010-03-26 21:24:24 +0800161 void *filter_data[LOG_MAX_FILTERS+1];
162
Harald Welte18fc4652011-08-17 14:14:17 +0200163 /*! \brief logging categories */
Harald Welteb43bc042011-06-27 10:29:17 +0200164 struct log_category *categories;
165
Harald Welte18fc4652011-08-17 14:14:17 +0200166 /*! \brief global log level */
Harald Welte3ae27582010-03-26 21:24:24 +0800167 uint8_t loglevel;
Harald Welte18fc4652011-08-17 14:14:17 +0200168 /*! \brief should color be used when printing log messages? */
Harald Welte87dbca12011-07-16 11:57:53 +0200169 unsigned int use_color:1;
Harald Welte18fc4652011-08-17 14:14:17 +0200170 /*! \brief should log messages be prefixed with a timestamp? */
Harald Welte87dbca12011-07-16 11:57:53 +0200171 unsigned int print_timestamp:1;
Holger Hans Peter Freytherdb153362012-09-11 11:24:51 +0200172 /*! \brief should log messages be prefixed with a filename? */
173 unsigned int print_filename:1;
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100174 /*! \brief should log messages be prefixed with a category name? */
175 unsigned int print_category:1;
176 /*! \brief should log messages be prefixed with an extended timestamp? */
177 unsigned int print_ext_timestamp:1;
Harald Welte3ae27582010-03-26 21:24:24 +0800178
Harald Welte18fc4652011-08-17 14:14:17 +0200179 /*! \brief the type of this log taget */
Harald Welte28222962011-02-18 20:37:04 +0100180 enum log_target_type type;
181
Harald Welte3ae27582010-03-26 21:24:24 +0800182 union {
183 struct {
184 FILE *out;
Harald Welte72d0c532010-08-25 19:24:00 +0200185 const char *fname;
Harald Welte0083cd32010-08-25 14:55:44 +0200186 } tgt_file;
Harald Welte3ae27582010-03-26 21:24:24 +0800187
188 struct {
189 int priority;
Harald Welte28222962011-02-18 20:37:04 +0100190 int facility;
Harald Welte3ae27582010-03-26 21:24:24 +0800191 } tgt_syslog;
192
193 struct {
194 void *vty;
195 } tgt_vty;
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000196
197 struct {
198 void *rb;
199 } tgt_rb;
Harald Welte3ae27582010-03-26 21:24:24 +0800200 };
201
Harald Welte18fc4652011-08-17 14:14:17 +0200202 /*! \brief call-back function to be called when the logging framework
203 * wants to log somethnig.
Katerina Barone-Adesic28c6a02013-02-15 13:27:59 +0100204 * \param[in] target logging target
Harald Welte18fc4652011-08-17 14:14:17 +0200205 * \param[in] level log level of currnet message
206 * \param[in] string the string that is to be written to the log
207 */
Harald Welte76e72ab2011-02-17 15:52:39 +0100208 void (*output) (struct log_target *target, unsigned int level,
209 const char *string);
Harald Welte3ae27582010-03-26 21:24:24 +0800210};
211
212/* use the above macros */
Andreas Eversberg2d6563b2012-07-10 13:10:15 +0200213void logp2(int subsys, unsigned int level, const char *file,
Harald Welte3ae27582010-03-26 21:24:24 +0800214 int line, int cont, const char *format, ...)
215 __attribute__ ((format (printf, 6, 7)));
Harald Welteb43bc042011-06-27 10:29:17 +0200216int log_init(const struct log_info *inf, void *talloc_ctx);
Harald Welte69e6c3c2016-04-20 10:41:27 +0200217void log_fini(void);
Jacob Erlbeckde6dd722015-11-17 11:52:24 +0100218int log_check_level(int subsys, unsigned int level);
Harald Welte3ae27582010-03-26 21:24:24 +0800219
220/* context management */
221void log_reset_context(void);
222int log_set_context(uint8_t ctx, void *value);
223
224/* filter on the targets */
225void log_set_all_filter(struct log_target *target, int);
226
227void log_set_use_color(struct log_target *target, int);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100228void log_set_print_extended_timestamp(struct log_target *target, int);
Harald Welte3ae27582010-03-26 21:24:24 +0800229void log_set_print_timestamp(struct log_target *target, int);
Holger Hans Peter Freytherdb153362012-09-11 11:24:51 +0200230void log_set_print_filename(struct log_target *target, int);
Holger Hans Peter Freyther2d6ad132014-12-05 09:35:30 +0100231void log_set_print_category(struct log_target *target, int);
Harald Welte3ae27582010-03-26 21:24:24 +0800232void log_set_log_level(struct log_target *target, int log_level);
233void log_parse_category_mask(struct log_target *target, const char* mask);
234int log_parse_level(const char *lvl);
Harald Welte9ac22252010-05-11 11:19:40 +0200235const char *log_level_str(unsigned int lvl);
Harald Welte3ae27582010-03-26 21:24:24 +0800236int log_parse_category(const char *category);
237void log_set_category_filter(struct log_target *target, int category,
238 int enable, int level);
239
240/* management of the targets */
241struct log_target *log_target_create(void);
Harald Welte72d0c532010-08-25 19:24:00 +0200242void log_target_destroy(struct log_target *target);
Harald Welte3ae27582010-03-26 21:24:24 +0800243struct log_target *log_target_create_stderr(void);
Harald Welte72d0c532010-08-25 19:24:00 +0200244struct log_target *log_target_create_file(const char *fname);
Harald Welte46cfd772011-02-17 15:56:56 +0100245struct log_target *log_target_create_syslog(const char *ident, int option,
246 int facility);
Harald Welte72d0c532010-08-25 19:24:00 +0200247int log_target_file_reopen(struct log_target *tgt);
Harald Welte4de854d2013-03-18 19:01:40 +0100248int log_targets_reopen(void);
Harald Welte72d0c532010-08-25 19:24:00 +0200249
Harald Welte3ae27582010-03-26 21:24:24 +0800250void log_add_target(struct log_target *target);
251void log_del_target(struct log_target *target);
252
Pablo Neira Ayuso04139f12011-03-09 13:05:08 +0100253/* Generate command string for VTY use */
254const char *log_vty_command_string(const struct log_info *info);
255const char *log_vty_command_description(const struct log_info *info);
Harald Welte7638af92010-05-11 16:39:22 +0200256
Harald Welte28222962011-02-18 20:37:04 +0100257struct log_target *log_target_find(int type, const char *fname);
258extern struct llist_head osmo_log_target_list;
259
Sylvain Munautdca7d2c2012-04-18 21:53:23 +0200260/*! @} */