alias_db(k): rephrase documentation a bit to make it hopefully better understandable
[sip-router] / dprint.h
1 /*
2  * $Id$
3  *
4  * Copyright (C) 2001-2003 FhG Fokus
5  *
6  * This file is part of ser, a free SIP server.
7  *
8  * ser is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * ser is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License 
19  * along with this program; if not, write to the Free Software 
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 /**
24  * @file
25  * @brief SIP-router core :: debug printing
26  * @ingroup core
27  * Module: @ref core
28  */
29
30 #ifndef dprint_h
31 #define dprint_h
32
33 #include <assert.h>
34 #include <syslog.h>
35 #include <stdio.h> /* stderr, fprintf() */
36
37 #include "compiler_opt.h"
38 #include "cfg_core.h"
39
40
41 /** if defined the function name will also be logged. */
42 #ifdef NO_LOG_FUNC_NAME
43 #       undef LOG_FUNC_NAME
44 #else
45 /* by default log the function name */
46 #       define LOG_FUNC_NAME
47 #endif /* NO_LOG_FUNC_NAME */
48
49 /* C >= 99 has __func__, older gcc versions have __FUNCTION__ */
50 #if __STDC_VERSION__ < 199901L
51 #       if __GNUC__ >= 2 && defined __FUNCTION__
52 #               define _FUNC_NAME_ __FUNCTION__
53 #       else
54 #               define _FUNC_NAME_ ""
55 #               undef LOG_FUNC_NAME
56 #       endif
57 #else
58 #       define _FUNC_NAME_ __func__
59 #endif
60
61 #ifdef NO_DEBUG
62 #       ifdef MOD_NAME
63 #               define LOC_INFO         MOD_NAME ": "
64 #       else
65 #               define LOC_INFO         "<core>: "
66 #       endif
67 #else
68 #       define XCT2STR(i) #i
69 #       define CT2STR(l)  XCT2STR(l)
70 #
71 #       ifdef MOD_NAME
72 #               define LOC_INFO         MOD_NAME " [" __FILE__ ":" CT2STR(__LINE__) "]: "
73 #       else
74 #               define LOC_INFO         "<core> [" __FILE__ ":" CT2STR(__LINE__) "]: "
75 #       endif
76 #
77 #       ifdef NO_LOG
78 #               undef NO_LOG
79 #       endif
80 #endif /* NO_DEBUG */
81
82
83 /*
84  * Log levels
85  */
86 #define L_ALERT         -5
87 #define L_BUG           -4
88 #define L_CRIT2         -3  /* like L_CRIT, but adds prefix */
89 #define L_CRIT          -2  /* no prefix added */
90 #define L_ERR           -1
91 #define L_WARN          0
92 #define L_NOTICE        1
93 #define L_INFO          2
94 #define L_DBG           3
95
96 /** @brief This is the facility value used to indicate that the caller of the macro
97  * did not override the facility. Value 0 (the defaul) is LOG_KERN on Linux
98  */
99 #define DEFAULT_FACILITY 0
100
101 #define LOG_LEVEL2NAME(level)   (log_level_info[(level) - (L_ALERT)].name)
102 #define LOG2SYSLOG_LEVEL(level) \
103         (log_level_info[(level) - (L_ALERT)].syslog_level)
104
105
106 /** @brief my_pid(), process_no are from pt.h but we cannot #include it here
107    because of circular dependencies */
108 extern int process_no;
109 extern int my_pid();
110
111 /** @brief non-zero if logging to stderr instead to the syslog */
112 extern int log_stderr;
113
114 /** @brief maps log levels to their string name and corresponding syslog level */
115
116 struct log_level_info {
117         char *name;
118         int syslog_level;
119 };
120
121 /** @brief per process debug level handling */
122 int get_debug_level(void);
123 void set_local_debug_level(int level);
124 void reset_local_debug_level(void);
125
126 #define is_printable(level) (get_debug_level()>=(level))
127 extern struct log_level_info log_level_info[];
128 extern char *log_name;
129
130 #ifndef NO_SIG_DEBUG
131 /** @brief protection against "simultaneous" printing from signal handlers */
132 extern volatile int dprint_crit; 
133 #endif
134
135 int str2facility(char *s);
136 int log_facility_fixup(void *handle, str *gname, str *name, void **val);
137
138
139 /** @brief
140  * General logging macros
141  *
142  * LOG_(level, prefix, fmt, ...) prints "printf"-formatted log message to
143  * stderr (if `log_stderr' is non-zero) or to syslog.  Note that `fmt' must
144  * be constant. `prefix' is added to the beginning of the message.
145  *
146  * LOG(level, fmt, ...) is same as LOG_() with LOC_INFO prefix.
147  */
148 #ifdef NO_LOG
149
150 #       ifdef __SUNPRO_C
151 #               define LOG_(facility, level, prefix, fmt, ...)
152 #               define LOG(level, fmt, ...)
153 #               define LOG_FC(facility, level, fmt, ...)
154 #       else
155 #               define LOG_(facility, level, prefix, fmt, args...)
156 #               define LOG(level, fmt, args...)
157 #               define LOG_FC(facility, level, fmt, args...)
158 #       endif
159
160 #else
161
162 #       ifdef NO_SIG_DEBUG
163 #               define DPRINT_NON_CRIT          (1)
164 #               define DPRINT_CRIT_ENTER
165 #               define DPRINT_CRIT_EXIT
166 #       else
167 #               define DPRINT_NON_CRIT          (dprint_crit==0)
168 #               define DPRINT_CRIT_ENTER        (dprint_crit++)
169 #               define DPRINT_CRIT_EXIT         (dprint_crit--)
170 #       endif
171
172 #       ifdef __SUNPRO_C
173 #               define LOG_(facility, level, prefix, fmt, ...) \
174                         do { \
175                                 if (unlikely(get_debuglevel() >= (level) && \
176                                                 DPRINT_NON_CRIT)) { \
177                                         DPRINT_CRIT_ENTER; \
178                                         if (likely(((level) >= L_ALERT) && ((level) <= L_DBG))){ \
179                                                 if (unlikely(log_stderr)) { \
180                                                         fprintf(stderr, "%2d(%d) %s: %s" fmt, \
181                                                                         process_no, my_pid(), \
182                                                                         LOG_LEVEL2NAME(level), (prefix), \
183                                                                         __VA_ARGS__); \
184                                                 } else { \
185                                                         syslog(LOG2SYSLOG_LEVEL(level) | \
186                                                                    (((facility) != DEFAULT_FACILITY) ? \
187                                                                         (facility) : \
188                                                                         cfg_get(core, core_cfg, log_facility)), \
189                                                                         "%s: %s" fmt, LOG_LEVEL2NAME(level),\
190                                                                         (prefix), __VA_ARGS__); \
191                                                 } \
192                                         } else { \
193                                                 if (log_stderr) { \
194                                                         fprintf(stderr, "%2d(%d) %s" fmt, \
195                                                                         process_no, my_pid(), \
196                                                                         (prefix),  __VA_ARGS__); \
197                                                 } else { \
198                                                         if ((level)<L_ALERT) \
199                                                                 syslog(LOG2SYSLOG_LEVEL(L_ALERT) | \
200                                                                            (((facility) != DEFAULT_FACILITY) ? \
201                                                                                 (facility) : \
202                                                                                 cfg_get(core, core_cfg, log_facility)),\
203                                                                            "%s" fmt, (prefix), __VA_ARGS__); \
204                                                         else \
205                                                                 syslog(LOG2SYSLOG_LEVEL(L_DBG) | \
206                                                                            (((facility) != DEFAULT_FACILITY) ? \
207                                                                                 (facility) : \
208                                                                                 cfg_get(core, core_cfg, log_facility)),\
209                                                                            "%s" fmt, (prefix), __VA_ARGS__); \
210                                                 } \
211                                         } \
212                                         DPRINT_CRIT_EXIT; \
213                                 } \
214                         } while(0)
215                         
216 #               ifdef LOG_FUNC_NAME
217 #                       define LOG(level, fmt, ...) \
218         LOG_(DEFAULT_FACILITY, (level), LOC_INFO, "%s(): " fmt,\
219                                 _FUNC_NAME_, __VA_ARGS__)
220
221 #                       define LOG_FC(facility, level, fmt, ...) \
222         LOG_((facility), (level), LOC_INFO, "%s(): " fmt,\
223                                 _FUNC_NAME_, __VA_ARGS__)
224 #               else /* LOG_FUNC_NAME */
225
226 #                       define LOG(level, fmt, ...) \
227         LOG_(DEFAULT_FACILITY, (level), LOC_INFO, fmt, __VA_ARGS__)
228
229 #                       define LOG_FC(facility, level, fmt, ...) \
230         LOG_((facility), (level), LOC_INFO, fmt, __VA_ARGS__)
231
232 #               endif /* LOG_FUNC_NAME */
233
234 #       else /* ! __SUNPRO_C */
235 #               define LOG_(facility, level, prefix, fmt, args...) \
236                         do { \
237                                 if (get_debug_level() >= (level) && \
238                                                 DPRINT_NON_CRIT) { \
239                                         DPRINT_CRIT_ENTER; \
240                                         if (likely(((level) >= L_ALERT) && ((level) <= L_DBG))){ \
241                                                 if (unlikely(log_stderr)) { \
242                                                         fprintf(stderr, "%2d(%d) %s: %s" fmt, \
243                                                                         process_no, my_pid(), \
244                                                                         LOG_LEVEL2NAME(level), \
245                                                                         (prefix) , ## args);\
246                                                 } else { \
247                                                         syslog(LOG2SYSLOG_LEVEL(level) |\
248                                                                    (((facility) != DEFAULT_FACILITY) ? \
249                                                                         (facility) : \
250                                                                         cfg_get(core, core_cfg, log_facility)), \
251                                                                         "%s: %s" fmt, LOG_LEVEL2NAME(level),\
252                                                                         (prefix) , ## args); \
253                                                 } \
254                                         } else { \
255                                                 if (log_stderr) { \
256                                                         fprintf(stderr, "%2d(%d) %s" fmt, \
257                                                                                 process_no, my_pid(), \
258                                                                                 (prefix) , ## args); \
259                                                 } else { \
260                                                         if ((level)<L_ALERT) \
261                                                                 syslog(LOG2SYSLOG_LEVEL(L_ALERT) | \
262                                                                            (((facility) != DEFAULT_FACILITY) ? \
263                                                                                 (facility) : \
264                                                                                 cfg_get(core, core_cfg, log_facility)),\
265                                                                                 "%s" fmt, (prefix) , ## args); \
266                                                         else \
267                                                                 syslog(LOG2SYSLOG_LEVEL(L_DBG) | \
268                                                                            (((facility) != DEFAULT_FACILITY) ? \
269                                                                                 (facility) : \
270                                                                                 cfg_get(core, core_cfg, log_facility)),\
271                                                                                 "%s" fmt, (prefix) , ## args); \
272                                                 } \
273                                         } \
274                                         DPRINT_CRIT_EXIT; \
275                                 } \
276                         } while(0)
277                         
278 #               ifdef LOG_FUNC_NAME
279 #                       define LOG(level, fmt, args...) \
280         LOG_(DEFAULT_FACILITY, (level), LOC_INFO, "%s(): " fmt ,\
281                         _FUNC_NAME_, ## args)
282
283 #                       define LOG_FC(facility, level, fmt, args...) \
284         LOG_((facility), (level), LOC_INFO, "%s(): " fmt , _FUNC_NAME_, ## args)
285
286 #               else /* LOG_FUNC_NAME */
287 #                       define LOG(level, fmt, args...) \
288         LOG_(DEFAULT_FACILITY, (level), LOC_INFO, fmt , ## args)
289 #                       define LOG_FC(facility, level, fmt, args...) \
290         LOG_((facility), (level), LOC_INFO, fmt , ## args)
291
292 #               endif /* LOG_FUNC_NAME */
293 #       endif /* __SUNPRO_C */
294 #endif /* NO_LOG */
295
296
297 /** @name SimpleLog
298  * Simplier, prefered logging macros for constant log level
299  */
300 /*@ { */
301 #ifdef __SUNPRO_C
302 #       define ALERT(...)  LOG(L_ALERT,  __VA_ARGS__)
303 #       define BUG(...)    LOG(L_BUG,   __VA_ARGS__)
304 #       define ERR(...)    LOG(L_ERR,    __VA_ARGS__)
305 #       define WARN(...)   LOG(L_WARN,   __VA_ARGS__)
306 #       define NOTICE(...) LOG(L_NOTICE, __VA_ARGS__)
307 #       define INFO(...)   LOG(L_INFO,   __VA_ARGS__)
308 #       define CRIT(...)    LOG(L_CRIT2,   __VA_ARGS__)
309
310 #       ifdef NO_DEBUG
311 #               define DBG(...)
312 #       else
313 #               define DBG(...)    LOG(L_DBG, __VA_ARGS__)
314 #       endif           
315 /*@ } */
316
317 /* obsolete, do not use */
318 #       define DEBUG(...) DBG(__VA_ARGS__)
319
320 #else /* ! __SUNPRO_C */
321 #       define ALERT(fmt, args...)  LOG(L_ALERT,  fmt , ## args)
322 #       define BUG(fmt, args...)    LOG(L_BUG,   fmt , ## args)
323 #       define ERR(fmt, args...)    LOG(L_ERR,    fmt , ## args)
324 #       define WARN(fmt, args...)   LOG(L_WARN,   fmt , ## args)
325 #       define NOTICE(fmt, args...) LOG(L_NOTICE, fmt , ## args)
326 #       define INFO(fmt, args...)   LOG(L_INFO,   fmt , ## args)
327 #       define CRIT(fmt, args...)   LOG(L_CRIT2,   fmt , ## args)
328
329 #       ifdef NO_DEBUG
330 #               define DBG(fmt, args...)
331 #       else
332 #               define DBG(fmt, args...)    LOG(L_DBG, fmt , ## args)
333 #       endif           
334
335 /* obsolete, do not use */
336 #       define DEBUG(fmt, args...) DBG(fmt , ## args)
337                 
338 #endif /* __SUNPRO_C */
339
340
341 /* kamailio/openser compatibility */
342
343 #define LM_GEN1 LOG
344 #define LM_GEN2 LOG_FC
345 #define LM_ALERT ALERT
346 #define LM_CRIT  CRIT
347 #define LM_ERR ERR
348 #define LM_WARN WARN
349 #define LM_NOTICE NOTICE
350 #define LM_INFO INFO
351 #define LM_DBG DEBUG
352
353 #endif /* !dprint_h */