Implement syslog.
[bertos.git] / bertos / cfg / log.h
1 /**
2  * \file
3  * <!--
4  * This file is part of BeRTOS.
5  *
6  * Bertos is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  * As a special exception, you may use this file as part of a free software
21  * library without restriction.  Specifically, if other files instantiate
22  * templates or use macros or inline functions from this file, or you compile
23  * this file and link it with other files to produce an executable, this
24  * file does not by itself cause the resulting executable to be covered by
25  * the GNU General Public License.  This exception does not however
26  * invalidate any other reasons why the executable file might be covered by
27  * the GNU General Public License.
28  *
29  * Copyright 2008 Develer S.r.l. (http://www.develer.com/)
30  *
31  * -->
32  *
33  * \defgroup logging Logging facilities
34  * \ingroup core
35  * \{
36  * \brief Logging system module.
37  *
38  * This module implement a simple interface to use the multi level logging system.
39  * The log message have the priority order, like this:
40  *
41  *  - error message (highest)
42  *  - warning message
43  *  - info message (lowest)
44  *
45  * With this priority system we log only the messages that have priority higher
46  * or equal to the log level that has been configurated; messages below the
47  * selected log level are not included at compile time, so no time and space
48  * is wasted on unused functions.
49  *
50  * Furthermore you can define different log levels for each module. To do this
51  * you just need to define LOG_LEVEL in the configuration file for the
52  * selected module.
53  *
54  * This module provides two types of macros:
55  *
56  *  - LOG_* macros: these macros allow formatted output, using the same format
57  *                  as kprintf
58  *  - LOG_*B macros: these macros allow to optionally compile a block of code
59  *                   depending on the logging level chosen
60  *
61  * To use the logging system you should include this module in your driver
62  * and use one of the LOG_ERR, LOG_WARN and LOG_INFO macros to output error
63  * messages.
64  * Then you should define a LOG_LEVEL and LOG_VERBOSE costant in your
65  * \c cfg/cfg_\<your_cfg_module_name\>.h using the follow policy:
66  *
67  * - in your file \c cfg/cfg_\<cfg_module_name\>.h, define the logging
68  *   level and verbosity mode for your specific module:
69  *
70  * \code
71  *      /// Module logging level.
72  *      #define <cfg_module_name>_LOG_LEVEL    LOG_LVL_INFO
73  *
74  *      /// Module logging format.
75  *      #define <cfg_module_name>_LOG_FORMAT   LOG_FMT_VERBOSE
76  * \endcode
77  *
78  * - then, in the module where you use the logging macros you should define
79  *   the macros LOG_LEVEL and LOG_FORMAT and you should include cfg/log.h
80  *   module, as demonstrated in the following example:
81  *
82  * \code
83  *      // Define log settings for cfg/log.h.
84  *      #define LOG_LEVEL   <cfg_module_name>_LOG_LEVEL
85  *      #define LOG_FORMAT  <cfg_module_name>_LOG_FORMAT
86  *      #include <cfg/log.h>
87  * \endcode
88  *
89  * if you include a log.h module without defining the LOG_LEVEL and LOG_VERBOSE
90  * macros, the module uses the default settings.
91  *
92  * WARNING: when using the log.h module make sure to include this module after
93  * a \c cfg_<cfg_module_name>.h, because the LOG_LEVEL and LOG_VERBOSE macros
94  * must be defined before including the log module. Otherwise the log module
95  * will use the default settings.
96  *
97  * \author Daniele Basile <asterix@develer.com>
98  *
99  * $WIZ$
100  */
101
102 #ifndef CFG_LOG_H
103 #define CFG_LOG_H
104
105 #include <cfg/debug.h>
106
107 // Use a default setting if nobody defined a log level
108 #ifndef LOG_LEVEL
109 #define LOG_LEVEL       LOG_LVL_ERR
110 #endif
111
112 // Use a default setting if nobody defined a log format
113 #ifndef LOG_FORMAT
114 #define LOG_FORMAT      LOG_FMT_TERSE
115 #endif
116
117 /**
118  * \name Logging level definition
119  *
120  * When you choose a log level messages you choose
121  * also which print function are linked.
122  * When using a log level, you link all log functions that have a priority
123  * higher or equal than the level you chose.
124  * The priority level go from error (highest) to info (lowest).
125  *
126  * $WIZ$ log_level = "LOG_LVL_NONE", "LOG_LVL_ERR", "LOG_LVL_WARN", "LOG_LVL_INFO"
127  * \{
128  */
129 #define LOG_LVL_NONE      0
130 #define LOG_LVL_ERR       1
131 #define LOG_LVL_WARN      2
132 #define LOG_LVL_INFO      3
133 /** \} */
134
135 /**
136  * \name Logging format
137  *
138  * There are two logging format: terse and verbose.  The latter prepends
139  * function names and line number information to each log entry.
140  *
141  * $WIZ$ log_format = "LOG_FMT_VERBOSE", "LOG_FMT_TERSE"
142  * \{
143  */
144 #define LOG_FMT_VERBOSE   1
145 #define LOG_FMT_TERSE     0
146 /** \} */
147
148 #include "cfg/cfg_syslog.h"
149
150 /* For backward compatibility */
151 #ifndef CONFIG_SYSLOG_NET
152         #define CONFIG_SYSLOG_NET 0
153 #endif
154
155 #if CONFIG_SYSLOG_NET
156         #include <net/syslog.h>
157
158         #if LOG_FORMAT == LOG_FMT_VERBOSE
159                 #define LOG_PRINT(str_level, str,...)    syslog_printf("<182>%d-%s():%d:%s: " str, syslog_count(), __func__, __LINE__, str_level, ## __VA_ARGS__)
160         #elif LOG_FORMAT == LOG_FMT_TERSE
161                 #define LOG_PRINT(str_level, str,...)    syslog_printf("<182>%d-%s: " str, syslog_count(), str_level, ## __VA_ARGS__)
162         #else
163                 #error No LOG_FORMAT defined
164         #endif
165
166 #else
167         #if LOG_FORMAT == LOG_FMT_VERBOSE
168                 #define LOG_PRINT(str_level, str,...)    kprintf("%s():%d:%s: " str, __func__, __LINE__, str_level, ## __VA_ARGS__)
169         #elif LOG_FORMAT == LOG_FMT_TERSE
170                 #define LOG_PRINT(str_level, str,...)    kprintf("%s: " str, str_level, ## __VA_ARGS__)
171         #else
172                 #error No LOG_FORMAT defined
173         #endif
174
175 #endif
176
177 #if LOG_LEVEL >= LOG_LVL_ERR
178         /**
179          * Output an error message
180          */
181         #define LOG_ERR(str,...)       LOG_PRINT("ERR", str, ## __VA_ARGS__)
182         /**
183          * Define a code block that will be compiled only when LOG_LEVEL >= LOG_LVL_ERR
184          */
185         #define LOG_ERRB(x)            x
186 #else
187         INLINE void LOG_ERR(UNUSED_ARG(const char *, fmt), ...) { /* nop */ }
188         #define LOG_ERRB(x)            /* Nothing */
189 #endif
190
191 #if LOG_LEVEL >= LOG_LVL_WARN
192         /**
193          * Output a warning message
194          */
195         #define LOG_WARN(str,...)       LOG_PRINT("WARN", str, ## __VA_ARGS__)
196         /**
197          * Define a code block that will be compiled only when LOG_LEVEL >= LOG_LVL_WARN
198          */
199         #define LOG_WARNB(x)            x
200 #else
201         INLINE void LOG_WARN(UNUSED_ARG(const char *, fmt), ...) { /* nop */ }
202         #define LOG_WARNB(x)            /* Nothing */
203 #endif
204
205 #if LOG_LEVEL >= LOG_LVL_INFO
206         /**
207          * Output an informative message
208          */
209         #define LOG_INFO(str,...)       LOG_PRINT("INFO", str, ## __VA_ARGS__)
210         /**
211          * Define a code block that will be compiled only when LOG_LEVEL >= LOG_LVL_INFO
212          */
213         #define LOG_INFOB(x)            x
214 #else
215         INLINE void LOG_INFO(UNUSED_ARG(const char *, fmt), ...) { /* nop */ }
216         #define LOG_INFOB(x)            /* Nothing */
217 #endif
218 /** \} */
219
220
221 #endif /* CFG_LOG_H */