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