1 /*
2  * Copyright (C) 2001-2003 FhG Fokus
3  *
4  * This file is part of Kamailio, a free SIP server.
5  *
6  * Kamailio 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  * Kamailio 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 Street, Fifth Floor, Boston, MA  02110-1301  USA
19  */
20 
21 /**
22  * @file
23  * @brief Kamailio 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 /** dicover the function name */
40 /* C >= 99 has __func__, older gcc versions have __FUNCTION__ */
41 #if __STDC_VERSION__ < 199901L
42 #	if __GNUC__ >= 2
43 #		define _FUNC_NAME_ __FUNCTION__
44 #		define _FUNC_SUFFIX_ "(): "
45 #	else
46 #		define _FUNC_NAME_ ""
47 #		define _FUNC_SUFFIX_ ""
48 #	endif
49 #else
50 #	define _FUNC_NAME_ __func__
51 #	define _FUNC_SUFFIX_ "(): "
52 #endif
53 
54 #ifdef NO_DEBUG
55 #	ifdef MOD_NAME
56 #		define LOC_INFO		MOD_NAME ": "
57 #		define LOG_MNAME	MOD_NAME
58 #	else
59 #		define LOC_INFO		"<core>: "
60 #		define LOG_MNAME	"core"
61 #	endif
62 #else
63 #	define XCT2STR(i) #i
64 #	define CT2STR(l)  XCT2STR(l)
65 #
66 #	ifdef MOD_NAME
67 #		define LOC_INFO		MOD_NAME " [" __FILE__ ":" CT2STR(__LINE__) "]: "
68 #		define LOG_MNAME	MOD_NAME
69 #	else
70 #		define LOC_INFO		"<core> [" __FILE__ ":" CT2STR(__LINE__) "]: "
71 #		define LOG_MNAME	"core"
72 #	endif
73 #
74 #	ifdef NO_LOG
75 #		undef NO_LOG
76 #	endif
77 #endif /* NO_DEBUG */
78 
79 #define LOG_MNAME_LEN		(sizeof(LOG_MNAME)-1)
80 
81 /*
82  * Log levels
83  */
84 #define L_NPRL		-6 /* (L_MIN-1) to skip printing level prefix */
85 #define L_MIN		-5
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 #define L_MAX    	3
96 #define L_OFFSET   42 /* needs to be added and then substracted
97                         because L_WARN may be confused with NULL pointer
98                         (e.g. fixup_dbg_sip_msg) */
99 
100 /** @brief This is the facility value used to indicate that the caller of the macro
101  * did not override the facility. Value 0 (the defaul) is LOG_KERN on Linux
102  */
103 #define DEFAULT_FACILITY 0
104 
105 #define LOG_LEVEL2NAME(level)	(log_level_info[(level) - (L_ALERT)].name)
106 #define LOG2SYSLOG_LEVEL(level) \
107 	(log_level_info[(level) - (L_ALERT)].syslog_level)
108 
109 /**
110  * data fileds used for structured logging
111  */
112 typedef struct ksr_logdata {
113 	/* next field are automatically set by log macro */
114 	int v_facility;
115 	int v_level;
116 	char *v_lname;
117 	const char *v_fname;
118 	int v_fline;
119 	const char *v_mname;
120 	const char *v_func;
121 	const char *v_locinfo;
122 	/* next field are __not__ automatically set by log macro */
123 	int v_pid;
124 	int v_pidx;
125 } ksr_logdata_t;
126 
127 typedef void (*ksr_slog_f)(ksr_logdata_t*, const char*, ...);
128 void ksr_slog_init(char *ename);
129 
130 extern ksr_slog_f _ksr_slog_func;
131 
132 /** @brief my_pid(), process_no are from pt.h but we cannot \#include it here
133    because of circular dependencies */
134 extern int process_no;
135 extern int my_pid(void);
136 
137 /** @brief non-zero if logging to stderr instead to the syslog */
138 extern int log_stderr;
139 
140 extern int log_color;
141 extern char *log_prefix_fmt;
142 extern str *log_prefix_val;
143 extern int log_prefix_mode;
144 extern char *_km_log_engine_type;
145 extern char *_km_log_engine_data;
146 
147 typedef void (*km_log_f)(int, const char *, ...);
148 extern km_log_f _km_log_func;
149 
150 void km_log_func_set(km_log_f f);
151 
152 /** @brief maps log levels to their string name and corresponding syslog level */
153 
154 struct log_level_info {
155  	char *name;
156 	int syslog_level;
157 };
158 
159 /** @brief per process debug level handling */
160 int get_debug_level(char *mname, int mnlen);
161 int get_cfg_debug_level(void);
162 int get_debug_facility(char *mname, int mnlen);
163 void set_local_debug_level(int level);
164 void set_local_debug_facility(int facility);
165 void reset_local_debug_level(void);
166 void reset_local_debug_facility(void);
167 typedef int (*get_module_debug_level_f)(char *mname, int mnlen, int *mlevel);
168 typedef int (*get_module_debug_facility_f)(char *mname, int mnlen, int *mfacility);
169 void set_module_debug_level_cb(get_module_debug_level_f f);
170 void set_module_debug_facility_cb(get_module_debug_facility_f f);
171 
172 #define is_printable(level) (get_debug_level(LOG_MNAME, LOG_MNAME_LEN)>=(level))
173 extern struct log_level_info log_level_info[];
174 extern char *log_name;
175 
176 #ifndef NO_SIG_DEBUG
177 /** @brief protection against "simultaneous" printing from signal handlers */
178 extern volatile int dprint_crit;
179 #endif
180 
181 int str2facility(char *s);
182 char* facility2str(int fl, int *len);
183 
184 int log_facility_fixup(void *handle, str *gname, str *name, void **val);
185 
186 void dprint_color(int level);
187 void dprint_color_reset(void);
188 void dprint_color_update(int level, char f, char b);
189 void dprint_init_colors(void);
190 void dprint_term_color(char f, char b, str *obuf);
191 
192 void log_prefix_init(void);
193 
194 #define LOGV_PREFIX_STR ((log_prefix_val)?log_prefix_val->s:"")
195 #define LOGV_PREFIX_LEN ((log_prefix_val)?log_prefix_val->len:0)
196 
197 #define LOGV_FUNCNAME_STR(vfuncname) (((void*)vfuncname!=NULL)?vfuncname:"")
198 #define LOGV_FUNCSUFFIX_STR(vfuncname) (((void*)vfuncname!=NULL)?_FUNC_SUFFIX_:"")
199 
200 /** @brief
201  * General logging macros
202  *
203  * LOG_FF(level, prefix, fmt, ...) prints "printf"-formatted log message to
204  * stderr (if `log_stderr' is non-zero) or to syslog.  Note that `fmt' must
205  * be constant. `prefix' is added to the beginning of the message.
206  *
207  * LOG(level, fmt, ...) is same as LOG_FP() with LOC_INFO prefix.
208  */
209 #ifdef NO_LOG
210 
211 #	ifdef __SUNPRO_C
212 #		define LOG_FX(facility, level, lname, prefix, funcname, ...)
213 #		define LOG_FL(facility, level, lname, prefix, ...)
214 #		define LOG_FP(facility, level, prefix, ...)
215 #		define LOG_FN(facility, level, prefix, ...)
216 #		define LOG_FC(facility, level, ...)
217 #		define LOG_LN(level, lname, ...)
218 #		define LOG(level, fmt, ...)
219 #	else
220 #		define LOG_FX(facility, level, lname, prefix, funcname, fmt, args...)
221 #		define LOG_FL(facility, level, lname, prefix, fmt, args...)
222 #		define LOG_FP(facility, level, prefix, fmt, args...)
223 #		define LOG_FN(facility, level, prefix, fmt, args...)
224 #		define LOG_FC(facility, level, fmt, args...)
225 #		define LOG_LN(level, lname, fmt, args...)
226 #		define LOG(level, fmt, args...)
227 #	endif
228 
229 #else
230 
231 #	ifdef NO_SIG_DEBUG
232 #		define DPRINT_NON_CRIT		(1)
233 #		define DPRINT_CRIT_ENTER
234 #		define DPRINT_CRIT_EXIT
235 #	else
236 #		define DPRINT_NON_CRIT		(dprint_crit==0)
237 #		define DPRINT_CRIT_ENTER	(dprint_crit++)
238 #		define DPRINT_CRIT_EXIT		(dprint_crit--)
239 #	endif
240 
241 #	ifdef __SUNPRO_C
242 #		define LOG_FX(facility, level, lname, prefix, funcname, fmt, ...) \
243 			do { \
244 				if (DPRINT_NON_CRIT \
245 						&& get_debug_level(LOG_MNAME, LOG_MNAME_LEN) >= (level)) { \
246 					int __llevel; \
247 					__llevel = ((level)<L_ALERT)?L_ALERT:(((level)>L_DBG)?L_DBG:level); \
248 					DPRINT_CRIT_ENTER; \
249 					if (unlikely(log_stderr)) { \
250 						if (unlikely(log_color)) dprint_color(__llevel); \
251 						fprintf(stderr, "%2d(%d) %s: %.*s%s%s%s" fmt, \
252 								process_no, my_pid(), \
253 								(lname)?(lname):LOG_LEVEL2NAME(__llevel), \
254 								LOGV_PREFIX_LEN, LOGV_PREFIX_STR, \
255 								(prefix), LOGV_FUNCNAME_STR(funcname), \
256 								LOGV_FUNCSUFFIX_STR(funcname), __VA_ARGS__); \
257 						if (unlikely(log_color)) dprint_color_reset(); \
258 					} else { \
259 						_km_log_func(LOG2SYSLOG_LEVEL(__llevel) | \
260 							    (((facility) != DEFAULT_FACILITY) ? \
261 								(facility) : \
262 								get_debug_facility(LOG_MNAME, LOG_MNAME_LEN)), \
263 								"%s: %.*s%s%s%s" fmt, \
264 								(lname)?(lname):LOG_LEVEL2NAME(__llevel), \
265 								LOGV_PREFIX_LEN, LOGV_PREFIX_STR, \
266 								(prefix), LOGV_FUNCNAME_STR(funcname), \
267 								LOGV_FUNCSUFFIX_STR(funcname), __VA_ARGS__); \
268 					} \
269 					DPRINT_CRIT_EXIT; \
270 				} \
271 			} while(0)
272 
273 #		define LOG_FL(facility, level, lname, prefix, ...) \
274 			LOG_FX(facility, level, lname, prefix, _FUNC_NAME_, __VA_ARGS__, NULL)
275 
276 #		define LOG_FN(facility, level, prefix, ...) \
277 			LOG_FX(facility, level, NULL, prefix, NULL, __VA_ARGS__, NULL)
278 
279 #		define LOG_FP(facility, level, prefix, ...) \
280 			LOG_FL(facility, level, NULL, prefix, __VA_ARGS__, NULL)
281 
282 #		define LOG_FC(facility, level, ...) \
283 			LOG_FP((facility), (level), LOC_INFO, __VA_ARGS__, NULL)
284 #		define LOG_LN(level, lname, ...) \
285 			LOG_FL(DEFAULT_FACILITY, (level), (lname), LOC_INFO, \
286 						__VA_ARGS__, NULL)
287 #		define LOG(level, ...) \
288 			LOG_FP(DEFAULT_FACILITY, (level), LOC_INFO, __VA_ARGS__, NULL)
289 
290 
291 #	else /* ! __SUNPRO_C */
292 #		define LOG_FX(facility, level, lname, prefix, funcname, fmt, args...) \
293 			do { \
294 				if (DPRINT_NON_CRIT \
295 						&& get_debug_level(LOG_MNAME, LOG_MNAME_LEN) >= (level) ) { \
296 					int __llevel; \
297 					__llevel = ((level)<L_ALERT)?L_ALERT:(((level)>L_DBG)?L_DBG:level); \
298 					DPRINT_CRIT_ENTER; \
299 					if (_ksr_slog_func) { /* structured logging */ \
300 						ksr_logdata_t __kld = {0}; \
301 						__kld.v_facility = LOG2SYSLOG_LEVEL(__llevel) | \
302 							   (((facility) != DEFAULT_FACILITY) ? \
303 								(facility) : \
304 								get_debug_facility(LOG_MNAME, LOG_MNAME_LEN)); \
305 						__kld.v_level = __llevel; \
306 						__kld.v_lname = (lname)?(lname):LOG_LEVEL2NAME(__llevel); \
307 						__kld.v_fname = __FILE__; \
308 						__kld.v_fline = __LINE__; \
309 						__kld.v_mname = LOG_MNAME; \
310 						__kld.v_func = LOGV_FUNCNAME_STR(funcname); \
311 						__kld.v_locinfo = prefix; \
312 						_ksr_slog_func(&__kld, fmt, ## args); \
313 					} else { /* classic logging */ \
314 						if (unlikely(log_stderr)) { \
315 							if (unlikely(log_color)) dprint_color(__llevel); \
316 							fprintf(stderr, "%2d(%d) %s: %.*s%s%s%s" fmt, \
317 								process_no, my_pid(), \
318 								(lname)?(lname):LOG_LEVEL2NAME(__llevel), \
319 								LOGV_PREFIX_LEN, LOGV_PREFIX_STR, \
320 								(prefix), LOGV_FUNCNAME_STR(funcname), \
321 								LOGV_FUNCSUFFIX_STR(funcname), ## args); \
322 							if (unlikely(log_color)) dprint_color_reset(); \
323 						} else { \
324 							_km_log_func(LOG2SYSLOG_LEVEL(__llevel) | \
325 							   (((facility) != DEFAULT_FACILITY) ? \
326 								(facility) : \
327 								get_debug_facility(LOG_MNAME, LOG_MNAME_LEN)), \
328 								"%s: %.*s%s%s%s" fmt, \
329 								(lname)?(lname):LOG_LEVEL2NAME(__llevel), \
330 								LOGV_PREFIX_LEN, LOGV_PREFIX_STR, \
331 								(prefix), LOGV_FUNCNAME_STR(funcname), \
332 								LOGV_FUNCSUFFIX_STR(funcname), ## args); \
333 						} \
334 					} \
335 					DPRINT_CRIT_EXIT; \
336 				} \
337 			} while(0)
338 
339 #		define LOG_FL(facility, level, lname, prefix, fmt, args...) \
340 			LOG_FX(facility, level, lname, prefix, _FUNC_NAME_, fmt, ## args)
341 
342 #		define LOG_FN(facility, level, prefix, fmt, args...) \
343 			LOG_FX(facility, level, NULL, prefix, NULL, fmt, ## args)
344 
345 #		define LOG_FP(facility, level, prefix, fmt, args...) \
346 			LOG_FL(facility, level, NULL, prefix, fmt, ## args)
347 
348 #		define LOG(level, fmt, args...) \
349 			LOG_FP(DEFAULT_FACILITY, (level), LOC_INFO, fmt, ## args)
350 #		define LOG_FC(facility, level, fmt, args...) \
351 			LOG_FP((facility), (level), LOC_INFO, fmt, ## args)
352 #		define LOG_LN(level, lname, fmt, args...) \
353 			LOG_FL(DEFAULT_FACILITY, (level), (lname), LOC_INFO, fmt, ## args)
354 
355 #	endif /* __SUNPRO_C */
356 #endif /* NO_LOG */
357 
358 
359 /** @name SimpleLog
360  * Simplier, prefered logging macros for constant log level
361  */
362 /*@ { */
363 #ifdef __SUNPRO_C
364 #	define NPRL(...)   LOG(L_NPRL,  __VA_ARGS__)
365 #	define ALERT(...)  LOG(L_ALERT,  __VA_ARGS__)
366 #	define BUG(...)    LOG(L_BUG,   __VA_ARGS__)
367 #	define ERR(...)    LOG(L_ERR,    __VA_ARGS__)
368 #	define WARN(...)   LOG(L_WARN,   __VA_ARGS__)
369 #	define NOTICE(...) LOG(L_NOTICE, __VA_ARGS__)
370 #	define INFO(...)   LOG(L_INFO,   __VA_ARGS__)
371 #	define CRIT(...)    LOG(L_CRIT2,   __VA_ARGS__)
372 
373 #	ifdef NO_DEBUG
374 #		define DBG(...)
375 #	else
376 #		define DBG(...)    LOG(L_DBG, __VA_ARGS__)
377 #	endif
378 /*@ } */
379 
380 /* obsolete, do not use */
381 #	define DEBUG(...) DBG(__VA_ARGS__)
382 
383 #else /* ! __SUNPRO_C */
384 #	define NPRL(fmt, args...)   LOG(L_NPRL,  fmt , ## args)
385 #	define ALERT(fmt, args...)  LOG(L_ALERT,  fmt , ## args)
386 #	define BUG(fmt, args...)    LOG(L_BUG,   fmt , ## args)
387 #	define ERR(fmt, args...)    LOG(L_ERR,    fmt , ## args)
388 #	define WARN(fmt, args...)   LOG(L_WARN,   fmt , ## args)
389 #	define NOTICE(fmt, args...) LOG(L_NOTICE, fmt , ## args)
390 #	define INFO(fmt, args...)   LOG(L_INFO,   fmt , ## args)
391 #	define CRIT(fmt, args...)   LOG(L_CRIT2,   fmt , ## args)
392 
393 #	ifdef NO_DEBUG
394 #		define DBG(fmt, args...)
395 #	else
396 #		define DBG(fmt, args...)    LOG(L_DBG, fmt , ## args)
397 #	endif
398 
399 /* obsolete, do not use */
400 #	define DEBUG(fmt, args...) DBG(fmt , ## args)
401 
402 #endif /* __SUNPRO_C */
403 
404 
405 /* kamailio/openser compatibility */
406 
407 #define LM_GEN1 LOG
408 #define LM_GEN2 LOG_FC
409 #define LM_NPRL NPRL
410 #define LM_ALERT ALERT
411 #define LM_CRIT  CRIT
412 #define LM_BUG  BUG
413 #define LM_ERR ERR
414 #define LM_WARN WARN
415 #define LM_NOTICE NOTICE
416 #define LM_INFO INFO
417 #define LM_DBG DEBUG
418 
419 #endif /* !dprint_h */
420