add meson support
[protos/libecoli.git] / include / ecoli_log.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2016, Olivier MATZ <zer0@droids-corp.org>
3  */
4
5 /**
6  * Logging API
7  *
8  * This file provide logging helpers:
9  * - logging functions, supporting printf-like format
10  * - several debug level (similar to syslog)
11  * - named log types
12  * - redirection of log to a user functions (default logs nothing)
13  */
14
15 #ifndef ECOLI_LOG_
16 #define ECOLI_LOG_
17
18 #include <stdarg.h>
19
20 #include <ecoli_assert.h>
21
22 enum ec_log_level {
23         EC_LOG_EMERG   = 0,  /* system is unusable               */
24         EC_LOG_ALERT   = 1,  /* action must be taken immediately */
25         EC_LOG_CRIT    = 2,  /* critical conditions              */
26         EC_LOG_ERR     = 3,  /* error conditions                 */
27         EC_LOG_WARNING = 4,  /* warning conditions               */
28         EC_LOG_NOTICE  = 5,  /* normal but significant condition */
29         EC_LOG_INFO    = 6,  /* informational                    */
30         EC_LOG_DEBUG   = 7,  /* debug-level messages             */
31 };
32
33 /**
34  * Register a log type.
35  *
36  * This macro defines a function that will be called at startup (using
37  * the "constructor" attribute). This function registers the named type
38  * passed as argument, and sets a static global variable
39  * "ec_log_local_type". This variable is used as the default log type
40  * for this file when using EC_LOG() or EC_VLOG().
41  *
42  * This macro can be present several times in a file. In this case, the
43  * local log type is set to the last registered type.
44  *
45  * On error, the function aborts.
46  *
47  * @param name
48  *   The name of the log to be registered.
49  */
50 #define EC_LOG_TYPE_REGISTER(name)                                      \
51         static int name##_log_type;                                     \
52         static int ec_log_local_type;                                   \
53         __attribute__((constructor, used))                              \
54         static void ec_log_register_##name(void)                        \
55         {                                                               \
56                 ec_log_local_type = ec_log_type_register(#name);        \
57                 ec_assert_print(ec_log_local_type >= 0,                 \
58                                 "cannot register log type.\n");         \
59                 name##_log_type = ec_log_local_type;                    \
60         }
61
62 /**
63  * User log function type.
64  *
65  * It is advised that a user-defined log function drops all messages
66  * that are at least as critical as ec_log_level_get(), as done by the
67  * default handler.
68  *
69  * @param type
70  *   The log type identifier.
71  * @param level
72  *   The log level.
73  * @param opaque
74  *   The opaque pointer that was passed to ec_log_fct_register().
75  * @param str
76  *   The string to log.
77  * @return
78  *   0 on success, -1 on error (errno is set).
79  */
80 typedef int (*ec_log_t)(int type, enum ec_log_level level, void *opaque,
81                         const char *str);
82
83 /**
84  * Register a user log function.
85  *
86  * @param usr_log
87  *   Function pointer that will be invoked for each log call.
88  *   If the parameter is NULL, ec_log_default_cb() is used.
89  * @param opaque
90  *   Opaque pointer passed to the log function.
91  * @return
92  *   0 on success, -1 on error (errno is set).
93  */
94 int ec_log_fct_register(ec_log_t usr_log, void *opaque);
95
96 /**
97  * Register a named log type.
98  *
99  * Register a new log type, which is identified by its name. The
100  * function returns a log identifier associated to the log name. If the
101  * name is already registered, the function just returns its identifier.
102  *
103  * @param name
104  *   The name of the log type.
105  * @return
106  *   The log type identifier on success (positive or zero), -1 on
107  *   error (errno is set).
108  */
109 int ec_log_type_register(const char *name);
110
111 /**
112  * Return the log name associated to the log type identifier.
113  *
114  * @param type
115  *   The log type identifier.
116  * @return
117  *   The name associated to the log type, or "unknown". It always return
118  *   a valid string (never NULL).
119  */
120 const char *ec_log_name(int type);
121
122 /**
123  * Log a formatted string.
124  *
125  * @param type
126  *   The log type identifier.
127  * @param level
128  *   The log level.
129  * @param format
130  *   The format string, followed by optional arguments.
131  * @return
132  *   0 on success, -1 on error (errno is set).
133  */
134 int ec_log(int type, enum ec_log_level level, const char *format, ...)
135         __attribute__((format(__printf__, 3, 4)));
136
137 /**
138  * Log a formatted string.
139  *
140  * @param type
141  *   The log type identifier.
142  * @param level
143  *   The log level.
144  * @param format
145  *   The format string.
146  * @param ap
147  *   The list of arguments.
148  * @return
149  *   0 on success, -1 on error (errno is set).
150  */
151 int ec_vlog(int type, enum ec_log_level level, const char *format, va_list ap);
152
153 /**
154  * Log a formatted string using the local log type.
155  *
156  * This macro requires that a log type is previously register with
157  * EC_LOG_TYPE_REGISTER() since it uses the "ec_log_local_type"
158  * variable.
159  *
160  * @param level
161  *   The log level.
162  * @param format
163  *   The format string, followed by optional arguments.
164  * @return
165  *   0 on success, -1 on error (errno is set).
166  */
167 #define EC_LOG(level, args...) ec_log(ec_log_local_type, level, args)
168
169 /**
170  * Log a formatted string using the local log type.
171  *
172  * This macro requires that a log type is previously register with
173  * EC_LOG_TYPE_REGISTER() since it uses the "ec_log_local_type"
174  * variable.
175  *
176  * @param level
177  *   The log level.
178  * @param format
179  *   The format string.
180  * @param ap
181  *   The list of arguments.
182  * @return
183  *   0 on success, -1 on error (errno is set).
184  */
185 #define EC_VLOG(level, fmt, ap) ec_vlog(ec_log_local_type, level, fmt, ap)
186
187 /**
188  * Default log handler.
189  *
190  * This is the default log function that is used by the library. By
191  * default, it prints all logs whose level is WARNING or more critical.
192  * This level can be changed with ec_log_level_set().
193  *
194  * @param type
195  *   The log type identifier.
196  * @param level
197  *   The log level.
198  * @param opaque
199  *   Unused.
200  * @param str
201  *   The string to be logged.
202  * @return
203  *   0 on success, -1 on error (errno is set).
204  */
205 int ec_log_default_cb(int type, enum ec_log_level level, void *opaque,
206                 const char *str);
207
208 /**
209  * Set the global log level.
210  *
211  * This level is used by the default log handler, ec_log_default_cb().
212  * All messages that are at least as critical as the default level are
213  * displayed.
214  *
215  * It is advised
216  *
217  * @param level
218  *   The log level to be set.
219  * @return
220  *   0 on success, -1 on error.
221  */
222 int ec_log_level_set(enum ec_log_level level);
223
224 /**
225  * Get the global log level.
226  *
227  * This level is used by the default log handler, ec_log_default_cb().
228  * All messages that are at least as critical as the default level are
229  * displayed.
230  *
231  * @param level
232  *   The log level to be set.
233  * @return
234  *   0 on success, -1 on error.
235  */
236 enum ec_log_level ec_log_level_get(void);
237
238 #endif