add existing code (build system, libs, initial mizucp code)
[mizunara.git] / ucx / ucx / logging.h
1 /*
2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3  *
4  * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  *   1. Redistributions of source code must retain the above copyright
10  *      notice, this list of conditions and the following disclaimer.
11  *
12  *   2. Redistributions in binary form must reproduce the above copyright
13  *      notice, this list of conditions and the following disclaimer in the
14  *      documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 /**
29  * Logging API.
30  * 
31  * @file   logging.h
32  * @author Mike Becker, Olaf Wintermann
33  */
34 #ifndef UCX_LOGGING_H
35 #define UCX_LOGGING_H
36
37 #include "ucx.h"
38 #include "map.h"
39 #include "string.h"
40 #include <stdio.h>
41
42 #ifdef __cplusplus
43 extern "C" {
44 #endif
45
46 /* leave enough space for custom log levels */
47
48 /** Log level for error messages. */
49 #define UCX_LOGGER_ERROR        0x00
50     
51 /** Log level for warning messages. */
52 #define UCX_LOGGER_WARN         0x10
53
54 /** Log level for information messages. */
55 #define UCX_LOGGER_INFO         0x20
56
57 /** Log level for debug messages. */
58 #define UCX_LOGGER_DEBUG        0x30
59
60 /** Log level for trace messages. */
61 #define UCX_LOGGER_TRACE        0x40
62
63 /**
64  * Output flag for the log level. 
65  * If this flag is set, the log message will contain the log level.
66  * @see UcxLogger.mask
67  */
68 #define UCX_LOGGER_LEVEL        0x01
69
70 /**
71  * Output flag for the timestmap.
72  * If this flag is set, the log message will contain the timestmap.
73  * @see UcxLogger.mask
74  */
75 #define UCX_LOGGER_TIMESTAMP    0x02
76
77 /**
78  * Output flag for the source.
79  * If this flag is set, the log message will contain the source file and line
80  * number.
81  * @see UcxLogger.mask
82  */
83 #define UCX_LOGGER_SOURCE       0x04
84
85 /**
86  * The UCX Logger object.
87  */
88 typedef struct {
89     /** The stream this logger writes its messages to.*/
90     void *stream;
91
92     /**
93      * The write function that shall be used.
94      * For standard file or stdout loggers this might be standard fwrite
95      * (default).
96      */
97     write_func writer;
98
99     /**
100      * The date format for timestamp outputs including the delimiter
101      * (default: <code>"%F %T %z "</code>).
102      * @see UCX_LOGGER_TIMESTAMP
103      */
104     char *dateformat;
105
106     /**
107      * The level, this logger operates on.
108      * If a log command is issued, the message will only be logged, if the log
109      * level of the message is less or equal than the log level of the logger.
110      */
111     unsigned int level;
112
113     /**
114      * A configuration mask for automatic output. 
115      * For each flag that is set, the logger automatically outputs some extra
116      * information like the timestamp or the source file and line number.
117      * See the documentation for the flags for details.
118      */
119     unsigned int mask;
120
121     /**
122      * A map of valid log levels for this logger.
123      * 
124      * The keys represent all valid log levels and the values provide string
125      * representations, that are used, if the UCX_LOGGER_LEVEL flag is set.
126      * 
127      * The exact data types are <code>unsigned int</code> for the key and
128      * <code>const char*</code> for the value.
129      * 
130      * @see UCX_LOGGER_LEVEL
131      */
132     UcxMap* levels;
133 } UcxLogger;
134
135 /**
136  * Creates a new logger.
137  * @param stream the stream, which the logger shall write to
138  * @param level the level on which the logger shall operate
139  * @param mask configuration mask (cf. UcxLogger.mask)
140  * @return a new logger object
141  */
142 UcxLogger *ucx_logger_new(void *stream, unsigned int level, unsigned int mask);
143
144 /**
145  * Destroys the logger.
146  * 
147  * The map containing the valid log levels is also automatically destroyed.
148  * 
149  * @param logger the logger to destroy
150  */
151 void ucx_logger_free(UcxLogger* logger);
152
153 /**
154  * Internal log function - use macros instead.
155  * 
156  * This function uses the <code>format</code> and variadic arguments for a
157  * printf()-style output of the log message.
158  * 
159  * Dependent on the UcxLogger.mask some information is prepended. The complete
160  * format is:
161  * 
162  * <code>[LEVEL] [TIMESTAMP] [SOURCEFILE]:[LINENO] message</code>
163  *
164  * The source file name is reduced to the actual file name. This is necessary to
165  * get consistent behavior over different definitions of the __FILE__ macro.
166  *
167  * <b>Attention:</b> the message (including automatically generated information)
168  * is limited to 4096 characters. The level description is limited to
169  * 256 characters and the timestamp string is limited to 128 characters.
170  * 
171  * @param logger the logger to use
172  * @param level the level to log on
173  * @param file information about the source file
174  * @param line information about the source line number
175  * @param format format string
176  * @param ... arguments
177  * @see ucx_logger_log()
178  */
179 void ucx_logger_logf(UcxLogger *logger, unsigned int level, const char* file,
180         const unsigned int line, const char* format, ...);
181
182 /**
183  * Registers a custom log level.
184  * @param logger the logger
185  * @param level the log level as unsigned integer
186  * @param name a string literal describing the level
187  */
188 #define ucx_logger_register_level(logger, level, name) {\
189         unsigned int l; \
190             l = level; \
191             ucx_map_int_put(logger->levels, l, (void*) "[" name "]"); \
192         } while (0);
193
194 /**
195  * Logs a message at the specified level.
196  * @param logger the logger to use
197  * @param level the level to log the message on
198  * @param ... format string and arguments
199  * @see ucx_logger_logf()
200  */
201 #define ucx_logger_log(logger, level, ...) \
202     ucx_logger_logf(logger, level, __FILE__, __LINE__, __VA_ARGS__)
203
204 /**
205  * Shortcut for logging an error message.
206  * @param logger the logger to use
207  * @param ... format string and arguments
208  * @see ucx_logger_logf()
209  */
210 #define ucx_logger_error(logger, ...) \
211     ucx_logger_log(logger, UCX_LOGGER_ERROR, __VA_ARGS__)
212
213 /**
214  * Shortcut for logging an information message.
215  * @param logger the logger to use
216  * @param ... format string and arguments
217  * @see ucx_logger_logf()
218  */
219 #define ucx_logger_info(logger, ...) \
220     ucx_logger_log(logger, UCX_LOGGER_INFO, __VA_ARGS__)
221
222 /**
223  * Shortcut for logging a warning message.
224  * @param logger the logger to use
225  * @param ... format string and arguments
226  * @see ucx_logger_logf()
227  */
228 #define ucx_logger_warn(logger, ...) \
229     ucx_logger_log(logger, UCX_LOGGER_WARN, __VA_ARGS__)
230
231 /**
232  * Shortcut for logging a debug message.
233  * @param logger the logger to use
234  * @param ... format string and arguments
235  * @see ucx_logger_logf()
236  */
237 #define ucx_logger_debug(logger, ...) \
238     ucx_logger_log(logger, UCX_LOGGER_DEBUG, __VA_ARGS__)
239
240 /**
241  * Shortcut for logging a trace message.
242  * @param logger the logger to use
243  * @param ... format string and arguments
244  * @see ucx_logger_logf()
245  */
246 #define ucx_logger_trace(logger, ...) \
247     ucx_logger_log(logger, UCX_LOGGER_TRACE, __VA_ARGS__)
248
249 #ifdef __cplusplus
250 }
251 #endif
252
253 #endif /* UCX_LOGGING_H */