blob: fa3365adf20d782c99910f6ad459fa5af5500aa8 [file] [log] [blame]
Harald Welte3ae27582010-03-26 21:24:24 +08001#ifndef _OSMOCORE_LOGGING_H
2#define _OSMOCORE_LOGGING_H
3
Harald Welte18fc4652011-08-17 14:14:17 +02004/*! \defgroup logging Osmocom logging framework
5 * @{
Harald Weltebd598e32011-08-16 23:26:52 +02006 */
7
Harald Welte18fc4652011-08-17 14:14:17 +02008/*! \file logging.h */
9
Harald Welte3ae27582010-03-26 21:24:24 +080010#include <stdio.h>
11#include <stdint.h>
Christoph Fritzab7c9c72011-09-01 16:22:17 +020012#include <stdarg.h>
Pablo Neira Ayuso83419342011-03-22 16:36:13 +010013#include <osmocom/core/linuxlist.h>
Harald Welte3ae27582010-03-26 21:24:24 +080014
Harald Weltebd598e32011-08-16 23:26:52 +020015/*! \brief Maximum number of logging contexts */
Harald Welte3ae27582010-03-26 21:24:24 +080016#define LOG_MAX_CTX 8
Harald Weltebd598e32011-08-16 23:26:52 +020017/*! \brief Maximum number of logging filters */
Harald Welte3ae27582010-03-26 21:24:24 +080018#define LOG_MAX_FILTERS 8
19
20#define DEBUG
21
22#ifdef DEBUG
23#define DEBUGP(ss, fmt, args...) logp(ss, __FILE__, __LINE__, 0, fmt, ## args)
24#define DEBUGPC(ss, fmt, args...) logp(ss, __FILE__, __LINE__, 1, fmt, ## args)
25#else
26#define DEBUGP(xss, fmt, args...)
27#define DEBUGPC(ss, fmt, args...)
28#endif
29
Harald Welte3ae27582010-03-26 21:24:24 +080030
Holger Hans Peter Freytherfb4bfc22012-07-12 09:26:25 +020031void osmo_vlogp(int subsys, int level, const char *file, int line,
Harald Welte36c5a3e2011-08-27 14:33:19 +020032 int cont, const char *format, va_list ap);
33
Andreas Eversberg2d6563b2012-07-10 13:10:15 +020034void 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 +080035
Harald Weltebd598e32011-08-16 23:26:52 +020036/*! \brief Log a new message through the Osmocom logging framework
37 * \param[in] ss logging subsystem (e.g. \ref DLGLOBAL)
38 * \param[in] level logging level (e.g. \ref LOGL_NOTICE)
39 * \param[in] fmt format string
40 * \param[in] args variable argument list
41 */
Harald Welte3ae27582010-03-26 21:24:24 +080042#define LOGP(ss, level, fmt, args...) \
43 logp2(ss, level, __FILE__, __LINE__, 0, fmt, ##args)
Harald Weltebd598e32011-08-16 23:26:52 +020044
45/*! \brief Continue a log 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 LOGPC(ss, level, fmt, args...) \
52 logp2(ss, level, __FILE__, __LINE__, 1, fmt, ##args)
53
Harald Welte18fc4652011-08-17 14:14:17 +020054/*! \brief different log levels */
55#define LOGL_DEBUG 1 /*!< \brief debugging information */
Harald Welte3ae27582010-03-26 21:24:24 +080056#define LOGL_INFO 3
Harald Welte18fc4652011-08-17 14:14:17 +020057#define LOGL_NOTICE 5 /*!< \brief abnormal/unexpected condition */
58#define LOGL_ERROR 7 /*!< \brief error condition, requires user action */
59#define LOGL_FATAL 8 /*!< \brief fatal, program aborted */
Harald Welte3ae27582010-03-26 21:24:24 +080060
61#define LOG_FILTER_ALL 0x0001
62
Harald Welteb43bc042011-06-27 10:29:17 +020063/* logging levels defined by the library itself */
64#define DLGLOBAL -1
root8a996b42011-09-26 11:22:21 +020065#define DLLAPD -2
Harald Welte892e6212011-07-19 14:31:44 +020066#define DLINP -3
67#define DLMUX -4
68#define DLMI -5
69#define DLMIB -6
Andreas Eversbergc626da92011-10-28 03:53:50 +020070#define DLSMS -7
71#define OSMO_NUM_DLIB 7
Harald Welteb43bc042011-06-27 10:29:17 +020072
Harald Welte3ae27582010-03-26 21:24:24 +080073struct log_category {
74 uint8_t loglevel;
75 uint8_t enabled;
76};
77
Harald Welte18fc4652011-08-17 14:14:17 +020078/*! \brief Information regarding one logging category */
Harald Welte3ae27582010-03-26 21:24:24 +080079struct log_info_cat {
Harald Welte18fc4652011-08-17 14:14:17 +020080 const char *name; /*!< name of category */
81 const char *color; /*!< color string for cateyory */
82 const char *description; /*!< description text */
83 uint8_t loglevel; /*!< currently selected log-level */
84 uint8_t enabled; /*!< is this category enabled or not */
Harald Welte3ae27582010-03-26 21:24:24 +080085};
86
Harald Welte18fc4652011-08-17 14:14:17 +020087/*! \brief Log context information, passed to filter */
Harald Welte3ae27582010-03-26 21:24:24 +080088struct log_context {
89 void *ctx[LOG_MAX_CTX+1];
90};
91
92struct log_target;
93
Harald Welte18fc4652011-08-17 14:14:17 +020094/*! \brief Log filter function */
Harald Welte3ae27582010-03-26 21:24:24 +080095typedef int log_filter(const struct log_context *ctx,
96 struct log_target *target);
97
Harald Welte18fc4652011-08-17 14:14:17 +020098/*! \brief Logging configuration, passed to \ref log_init */
Harald Welte3ae27582010-03-26 21:24:24 +080099struct log_info {
Harald Welte18fc4652011-08-17 14:14:17 +0200100 /* \brief filter callback function */
Harald Welte3ae27582010-03-26 21:24:24 +0800101 log_filter *filter_fn;
102
Harald Welte18fc4652011-08-17 14:14:17 +0200103 /*! \brief per-category information */
Holger Hans Peter Freyther06f64552012-09-11 10:31:29 +0200104 const struct log_info_cat *cat;
Harald Welte18fc4652011-08-17 14:14:17 +0200105 /*! \brief total number of categories */
Harald Welte3ae27582010-03-26 21:24:24 +0800106 unsigned int num_cat;
Harald Welte18fc4652011-08-17 14:14:17 +0200107 /*! \brief total number of user categories (not library) */
Harald Welteb43bc042011-06-27 10:29:17 +0200108 unsigned int num_cat_user;
Harald Welte3ae27582010-03-26 21:24:24 +0800109};
110
Harald Welte18fc4652011-08-17 14:14:17 +0200111/*! \brief Type of logging target */
Harald Welte28222962011-02-18 20:37:04 +0100112enum log_target_type {
Harald Welte18fc4652011-08-17 14:14:17 +0200113 LOG_TGT_TYPE_VTY, /*!< \brief VTY logging */
114 LOG_TGT_TYPE_SYSLOG, /*!< \brief syslog based logging */
115 LOG_TGT_TYPE_FILE, /*!< \brief text file logging */
116 LOG_TGT_TYPE_STDERR, /*!< \brief stderr logging */
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000117 LOG_TGT_TYPE_STRRB, /*!< \brief osmo_strrb-backed logging */
Harald Welte28222962011-02-18 20:37:04 +0100118};
119
Harald Welte18fc4652011-08-17 14:14:17 +0200120/*! \brief structure representing a logging target */
Harald Welte3ae27582010-03-26 21:24:24 +0800121struct log_target {
Harald Welte18fc4652011-08-17 14:14:17 +0200122 struct llist_head entry; /*!< \brief linked list */
Harald Welte3ae27582010-03-26 21:24:24 +0800123
Harald Welte18fc4652011-08-17 14:14:17 +0200124 /*! \brief Internal data for filtering */
Harald Welte3ae27582010-03-26 21:24:24 +0800125 int filter_map;
Harald Welte18fc4652011-08-17 14:14:17 +0200126 /*! \brief Internal data for filtering */
Harald Welte3ae27582010-03-26 21:24:24 +0800127 void *filter_data[LOG_MAX_FILTERS+1];
128
Harald Welte18fc4652011-08-17 14:14:17 +0200129 /*! \brief logging categories */
Harald Welteb43bc042011-06-27 10:29:17 +0200130 struct log_category *categories;
131
Harald Welte18fc4652011-08-17 14:14:17 +0200132 /*! \brief global log level */
Harald Welte3ae27582010-03-26 21:24:24 +0800133 uint8_t loglevel;
Harald Welte18fc4652011-08-17 14:14:17 +0200134 /*! \brief should color be used when printing log messages? */
Harald Welte87dbca12011-07-16 11:57:53 +0200135 unsigned int use_color:1;
Harald Welte18fc4652011-08-17 14:14:17 +0200136 /*! \brief should log messages be prefixed with a timestamp? */
Harald Welte87dbca12011-07-16 11:57:53 +0200137 unsigned int print_timestamp:1;
Holger Hans Peter Freytherdb153362012-09-11 11:24:51 +0200138 /*! \brief should log messages be prefixed with a filename? */
139 unsigned int print_filename:1;
Harald Welte3ae27582010-03-26 21:24:24 +0800140
Harald Welte18fc4652011-08-17 14:14:17 +0200141 /*! \brief the type of this log taget */
Harald Welte28222962011-02-18 20:37:04 +0100142 enum log_target_type type;
143
Harald Welte3ae27582010-03-26 21:24:24 +0800144 union {
145 struct {
146 FILE *out;
Harald Welte72d0c532010-08-25 19:24:00 +0200147 const char *fname;
Harald Welte0083cd32010-08-25 14:55:44 +0200148 } tgt_file;
Harald Welte3ae27582010-03-26 21:24:24 +0800149
150 struct {
151 int priority;
Harald Welte28222962011-02-18 20:37:04 +0100152 int facility;
Harald Welte3ae27582010-03-26 21:24:24 +0800153 } tgt_syslog;
154
155 struct {
156 void *vty;
157 } tgt_vty;
Katerina Barone-Adesi3309a432013-02-21 05:16:29 +0000158
159 struct {
160 void *rb;
161 } tgt_rb;
Harald Welte3ae27582010-03-26 21:24:24 +0800162 };
163
Harald Welte18fc4652011-08-17 14:14:17 +0200164 /*! \brief call-back function to be called when the logging framework
165 * wants to log somethnig.
Katerina Barone-Adesic28c6a02013-02-15 13:27:59 +0100166 * \param[in] target logging target
Harald Welte18fc4652011-08-17 14:14:17 +0200167 * \param[in] level log level of currnet message
168 * \param[in] string the string that is to be written to the log
169 */
Harald Welte76e72ab2011-02-17 15:52:39 +0100170 void (*output) (struct log_target *target, unsigned int level,
171 const char *string);
Harald Welte3ae27582010-03-26 21:24:24 +0800172};
173
174/* use the above macros */
Andreas Eversberg2d6563b2012-07-10 13:10:15 +0200175void logp2(int subsys, unsigned int level, const char *file,
Harald Welte3ae27582010-03-26 21:24:24 +0800176 int line, int cont, const char *format, ...)
177 __attribute__ ((format (printf, 6, 7)));
Harald Welteb43bc042011-06-27 10:29:17 +0200178int log_init(const struct log_info *inf, void *talloc_ctx);
Harald Welte3ae27582010-03-26 21:24:24 +0800179
180/* context management */
181void log_reset_context(void);
182int log_set_context(uint8_t ctx, void *value);
183
184/* filter on the targets */
185void log_set_all_filter(struct log_target *target, int);
186
187void log_set_use_color(struct log_target *target, int);
188void log_set_print_timestamp(struct log_target *target, int);
Holger Hans Peter Freytherdb153362012-09-11 11:24:51 +0200189void log_set_print_filename(struct log_target *target, int);
Harald Welte3ae27582010-03-26 21:24:24 +0800190void log_set_log_level(struct log_target *target, int log_level);
191void log_parse_category_mask(struct log_target *target, const char* mask);
192int log_parse_level(const char *lvl);
Harald Welte9ac22252010-05-11 11:19:40 +0200193const char *log_level_str(unsigned int lvl);
Harald Welte3ae27582010-03-26 21:24:24 +0800194int log_parse_category(const char *category);
195void log_set_category_filter(struct log_target *target, int category,
196 int enable, int level);
197
198/* management of the targets */
199struct log_target *log_target_create(void);
Harald Welte72d0c532010-08-25 19:24:00 +0200200void log_target_destroy(struct log_target *target);
Harald Welte3ae27582010-03-26 21:24:24 +0800201struct log_target *log_target_create_stderr(void);
Harald Welte72d0c532010-08-25 19:24:00 +0200202struct log_target *log_target_create_file(const char *fname);
Harald Welte46cfd772011-02-17 15:56:56 +0100203struct log_target *log_target_create_syslog(const char *ident, int option,
204 int facility);
Harald Welte72d0c532010-08-25 19:24:00 +0200205int log_target_file_reopen(struct log_target *tgt);
206
Harald Welte3ae27582010-03-26 21:24:24 +0800207void log_add_target(struct log_target *target);
208void log_del_target(struct log_target *target);
209
Pablo Neira Ayuso04139f12011-03-09 13:05:08 +0100210/* Generate command string for VTY use */
211const char *log_vty_command_string(const struct log_info *info);
212const char *log_vty_command_description(const struct log_info *info);
Harald Welte7638af92010-05-11 16:39:22 +0200213
Harald Welte28222962011-02-18 20:37:04 +0100214struct log_target *log_target_find(int type, const char *fname);
215extern struct llist_head osmo_log_target_list;
216
Sylvain Munautdca7d2c2012-04-18 21:53:23 +0200217/*! @} */
Harald Welte18fc4652011-08-17 14:14:17 +0200218
Harald Welte3ae27582010-03-26 21:24:24 +0800219#endif /* _OSMOCORE_LOGGING_H */