dprint.h
512dcd98
 /*
53c7e0f1
  * Copyright (C) 2001-2003 FhG Fokus
7dd0b342
  *
  * This file is part of ser, a free SIP server.
  *
  * ser is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version
  *
  * ser is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License 
  * along with this program; if not, write to the Free Software 
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
512dcd98
  */
 
1ff47a5c
 /**
  * @file
  * @brief SIP-router core :: debug printing
  * @ingroup core
  * Module: @ref core
  */
 
512dcd98
 #ifndef dprint_h
 #define dprint_h
 
bf79b581
 #include <assert.h>
efeaaf53
 #include <syslog.h>
bf79b581
 #include <stdio.h> /* stderr, fprintf() */
512dcd98
 
43181b6b
 #include "compiler_opt.h"
bf79b581
 #include "cfg_core.h"
512dcd98
 
26456ace
 
8af71cf2
 /** if defined the function name will also be logged. */
 #ifdef NO_LOG_FUNC_NAME
 #	undef LOG_FUNC_NAME
c3e19d24
 #else
 /* by default log the function name */
 #	define LOG_FUNC_NAME
8af71cf2
 #endif /* NO_LOG_FUNC_NAME */
 
a86d53b0
 /* C >= 99 has __func__, older gcc versions have __FUNCTION__ */
 #if __STDC_VERSION__ < 199901L
e081c288
 #	if __GNUC__ >= 2
bf79b581
 #		define _FUNC_NAME_ __FUNCTION__
 #	else
 #		define _FUNC_NAME_ ""
8af71cf2
 #		undef LOG_FUNC_NAME
bf79b581
 #	endif
a86d53b0
 #else
bf79b581
 #	define _FUNC_NAME_ __func__
a86d53b0
 #endif
 
bf79b581
 #ifdef NO_DEBUG
 #	ifdef MOD_NAME
 #		define LOC_INFO		MOD_NAME ": "
34378c35
 #		define LOG_MNAME	MOD_NAME
bf79b581
 #	else
 #		define LOC_INFO		"<core>: "
34378c35
 #		define LOG_MNAME	"core"
bf79b581
 #	endif
 #else
 #	define XCT2STR(i) #i
 #	define CT2STR(l)  XCT2STR(l)
 #
 #	ifdef MOD_NAME
 #		define LOC_INFO		MOD_NAME " [" __FILE__ ":" CT2STR(__LINE__) "]: "
34378c35
 #		define LOG_MNAME	MOD_NAME
bf79b581
 #	else
 #		define LOC_INFO		"<core> [" __FILE__ ":" CT2STR(__LINE__) "]: "
34378c35
 #		define LOG_MNAME	"core"
bf79b581
 #	endif
 #
 #	ifdef NO_LOG
 #		undef NO_LOG
 #	endif
 #endif /* NO_DEBUG */
a86d53b0
 
34378c35
 #define LOG_MNAME_LEN		(sizeof(LOG_MNAME)-1)
a86d53b0
 
bf79b581
 /*
  * Log levels
  */
6bda9c0b
 #define L_MIN		-5
271bfb0e
 #define L_ALERT		-5
 #define L_BUG		-4
 #define L_CRIT2		-3  /* like L_CRIT, but adds prefix */
 #define L_CRIT  	-2  /* no prefix added */
bf79b581
 #define L_ERR   	-1
 #define L_WARN   	0
 #define L_NOTICE 	1
 #define L_INFO   	2
 #define L_DBG    	3
6bda9c0b
 #define L_MAX    	3
512dcd98
 
1ff47a5c
 /** @brief This is the facility value used to indicate that the caller of the macro
f5618c1a
  * did not override the facility. Value 0 (the defaul) is LOG_KERN on Linux
  */
 #define DEFAULT_FACILITY 0
 
bf79b581
 #define LOG_LEVEL2NAME(level)	(log_level_info[(level) - (L_ALERT)].name)
7f3449bd
 #define LOG2SYSLOG_LEVEL(level) \
 	(log_level_info[(level) - (L_ALERT)].syslog_level)
26456ace
 
a86d53b0
 
7af69774
 /** @brief my_pid(), process_no are from pt.h but we cannot \#include it here
bf79b581
    because of circular dependencies */
 extern int process_no;
abb01fb4
 extern int my_pid(void);
a86d53b0
 
1ff47a5c
 /** @brief non-zero if logging to stderr instead to the syslog */
bf79b581
 extern int log_stderr;
a86d53b0
 
6bda9c0b
 extern int log_color;
 
1ff47a5c
 /** @brief maps log levels to their string name and corresponding syslog level */
a86d53b0
 
bf79b581
 struct log_level_info {
  	char *name;
 	int syslog_level;
 };
26456ace
 
0d2716bc
 /** @brief per process debug level handling */
34378c35
 int get_debug_level(char *mname, int mnlen);
0d2716bc
 void set_local_debug_level(int level);
 void reset_local_debug_level(void);
34378c35
 typedef int (*get_module_debug_level_f)(char *mname, int mnlen, int *mlevel);
 void set_module_debug_level_cb(get_module_debug_level_f f);
0d2716bc
 
34378c35
 #define is_printable(level) (get_debug_level(LOG_MNAME, LOG_MNAME_LEN)>=(level))
bf79b581
 extern struct log_level_info log_level_info[];
95bf8645
 extern char *log_name;
efeaaf53
 
bf79b581
 #ifndef NO_SIG_DEBUG
1ff47a5c
 /** @brief protection against "simultaneous" printing from signal handlers */
bf79b581
 extern volatile int dprint_crit; 
512dcd98
 #endif
 
bf79b581
 int str2facility(char *s);
33bfeb9d
 int log_facility_fixup(void *handle, str *gname, str *name, void **val);
512dcd98
 
6bda9c0b
 void dprint_color(int level);
 void dprint_color_reset(void);
1c1bdda1
 void dprint_color_update(int level, char f, char b);
6bda9c0b
 void dprint_init_colors(void);
b6642a1a
 void dprint_term_color(char f, char b, str *obuf);
512dcd98
 
1ff47a5c
 /** @brief
bf79b581
  * General logging macros
  *
7f3449bd
  * LOG_(level, prefix, fmt, ...) prints "printf"-formatted log message to
  * stderr (if `log_stderr' is non-zero) or to syslog.  Note that `fmt' must
  * be constant. `prefix' is added to the beginning of the message.
bf79b581
  *
  * LOG(level, fmt, ...) is same as LOG_() with LOC_INFO prefix.
  */
1fb7b1aa
 #ifdef NO_LOG
bf79b581
 
 #	ifdef __SUNPRO_C
f5618c1a
 #		define LOG_(facility, level, prefix, fmt, ...)
bf79b581
 #		define LOG(level, fmt, ...)
f5618c1a
 #		define LOG_FC(facility, level, fmt, ...)
bf79b581
 #	else
f5618c1a
 #		define LOG_(facility, level, prefix, fmt, args...)
bf79b581
 #		define LOG(level, fmt, args...)
f5618c1a
 #		define LOG_FC(facility, level, fmt, args...)
bf79b581
 #	endif
 
1fb7b1aa
 #else
bf79b581
 
 #	ifdef NO_SIG_DEBUG
 #		define DPRINT_NON_CRIT		(1)
 #		define DPRINT_CRIT_ENTER
 #		define DPRINT_CRIT_EXIT
 #	else
 #		define DPRINT_NON_CRIT		(dprint_crit==0)
 #		define DPRINT_CRIT_ENTER	(dprint_crit++)
 #		define DPRINT_CRIT_EXIT		(dprint_crit--)
 #	endif
 
 #	ifdef __SUNPRO_C
f5618c1a
 #		define LOG_(facility, level, prefix, fmt, ...) \
51eadd0c
 			do { \
34378c35
 				if (unlikely(get_debug_level(LOG_MNAME, LOG_MNAME_LEN) >= (level) && \
43181b6b
 						DPRINT_NON_CRIT)) { \
2d90691c
 					DPRINT_CRIT_ENTER; \
43181b6b
 					if (likely(((level) >= L_ALERT) && ((level) <= L_DBG))){ \
 						if (unlikely(log_stderr)) { \
6bda9c0b
 							if (unlikely(log_color)) dprint_color(level); \
43181b6b
 							fprintf(stderr, "%2d(%d) %s: %s" fmt, \
 									process_no, my_pid(), \
 									LOG_LEVEL2NAME(level), (prefix), \
 									__VA_ARGS__); \
6bda9c0b
 							if (unlikely(log_color)) dprint_color_reset(); \
43181b6b
 						} else { \
 							syslog(LOG2SYSLOG_LEVEL(level) | \
f5618c1a
 								   (((facility) != DEFAULT_FACILITY) ? \
 									(facility) : \
 									cfg_get(core, core_cfg, log_facility)), \
43181b6b
 									"%s: %s" fmt, LOG_LEVEL2NAME(level),\
 									(prefix), __VA_ARGS__); \
 						} \
bf79b581
 					} else { \
43181b6b
 						if (log_stderr) { \
6bda9c0b
 							if (unlikely(log_color)) dprint_color(level); \
43181b6b
 							fprintf(stderr, "%2d(%d) %s" fmt, \
 									process_no, my_pid(), \
 									(prefix),  __VA_ARGS__); \
6bda9c0b
 							if (unlikely(log_color)) dprint_color_reset(); \
43181b6b
 						} else { \
 							if ((level)<L_ALERT) \
 								syslog(LOG2SYSLOG_LEVEL(L_ALERT) | \
f5618c1a
 									   (((facility) != DEFAULT_FACILITY) ? \
 										(facility) : \
 										cfg_get(core, core_cfg, log_facility)),\
 									   "%s" fmt, (prefix), __VA_ARGS__); \
43181b6b
 							else \
 								syslog(LOG2SYSLOG_LEVEL(L_DBG) | \
f5618c1a
 									   (((facility) != DEFAULT_FACILITY) ? \
 										(facility) : \
 										cfg_get(core, core_cfg, log_facility)),\
 									   "%s" fmt, (prefix), __VA_ARGS__); \
43181b6b
 						} \
51eadd0c
 					} \
2d90691c
 					DPRINT_CRIT_EXIT; \
51eadd0c
 				} \
bf79b581
 			} while(0)
 			
8af71cf2
 #		ifdef LOG_FUNC_NAME
 #			define LOG(level, fmt, ...) \
 	LOG_(DEFAULT_FACILITY, (level), LOC_INFO, "%s(): " fmt,\
 				_FUNC_NAME_, __VA_ARGS__)
 
 #			define LOG_FC(facility, level, fmt, ...) \
 	LOG_((facility), (level), LOC_INFO, "%s(): " fmt,\
 				_FUNC_NAME_, __VA_ARGS__)
 #		else /* LOG_FUNC_NAME */
 
 #			define LOG(level, fmt, ...) \
f5618c1a
 	LOG_(DEFAULT_FACILITY, (level), LOC_INFO, fmt, __VA_ARGS__)
8af71cf2
 
 #			define LOG_FC(facility, level, fmt, ...) \
f5618c1a
 	LOG_((facility), (level), LOC_INFO, fmt, __VA_ARGS__)
bf79b581
 
8af71cf2
 #		endif /* LOG_FUNC_NAME */
 
43181b6b
 #	else /* ! __SUNPRO_C */
f5618c1a
 #		define LOG_(facility, level, prefix, fmt, args...) \
efeaaf53
 			do { \
34378c35
 				if (get_debug_level(LOG_MNAME, LOG_MNAME_LEN) >= (level) && \
7f3449bd
 						DPRINT_NON_CRIT) { \
2d90691c
 					DPRINT_CRIT_ENTER; \
43181b6b
 					if (likely(((level) >= L_ALERT) && ((level) <= L_DBG))){ \
 						if (unlikely(log_stderr)) { \
6bda9c0b
 							if (unlikely(log_color)) dprint_color(level); \
43181b6b
 							fprintf(stderr, "%2d(%d) %s: %s" fmt, \
 									process_no, my_pid(), \
20ce8764
 									LOG_LEVEL2NAME(level), \
 									(prefix) , ## args);\
6bda9c0b
 							if (unlikely(log_color)) dprint_color_reset(); \
43181b6b
 						} else { \
 							syslog(LOG2SYSLOG_LEVEL(level) |\
f5618c1a
 								   (((facility) != DEFAULT_FACILITY) ? \
 									(facility) : \
 									cfg_get(core, core_cfg, log_facility)), \
43181b6b
 									"%s: %s" fmt, LOG_LEVEL2NAME(level),\
20ce8764
 									(prefix) , ## args); \
43181b6b
 						} \
 					} else { \
 						if (log_stderr) { \
6bda9c0b
 							if (unlikely(log_color)) dprint_color(level); \
43181b6b
 							fprintf(stderr, "%2d(%d) %s" fmt, \
 										process_no, my_pid(), \
20ce8764
 										(prefix) , ## args); \
6bda9c0b
 							if (unlikely(log_color)) dprint_color_reset(); \
43181b6b
 						} else { \
 							if ((level)<L_ALERT) \
 								syslog(LOG2SYSLOG_LEVEL(L_ALERT) | \
f5618c1a
 									   (((facility) != DEFAULT_FACILITY) ? \
 										(facility) : \
 										cfg_get(core, core_cfg, log_facility)),\
20ce8764
 										"%s" fmt, (prefix) , ## args); \
43181b6b
 							else \
 								syslog(LOG2SYSLOG_LEVEL(L_DBG) | \
f5618c1a
 									   (((facility) != DEFAULT_FACILITY) ? \
 										(facility) : \
 										cfg_get(core, core_cfg, log_facility)),\
20ce8764
 										"%s" fmt, (prefix) , ## args); \
43181b6b
 						} \
efeaaf53
 					} \
2d90691c
 					DPRINT_CRIT_EXIT; \
efeaaf53
 				} \
bf79b581
 			} while(0)
 			
8af71cf2
 #		ifdef LOG_FUNC_NAME
 #			define LOG(level, fmt, args...) \
 	LOG_(DEFAULT_FACILITY, (level), LOC_INFO, "%s(): " fmt ,\
 			_FUNC_NAME_, ## args)
 
 #			define LOG_FC(facility, level, fmt, args...) \
 	LOG_((facility), (level), LOC_INFO, "%s(): " fmt , _FUNC_NAME_, ## args)
 
 #		else /* LOG_FUNC_NAME */
 #			define LOG(level, fmt, args...) \
20ce8764
 	LOG_(DEFAULT_FACILITY, (level), LOC_INFO, fmt , ## args)
8af71cf2
 #			define LOG_FC(facility, level, fmt, args...) \
20ce8764
 	LOG_((facility), (level), LOC_INFO, fmt , ## args)
8af71cf2
 
 #		endif /* LOG_FUNC_NAME */
bf79b581
 #	endif /* __SUNPRO_C */
 #endif /* NO_LOG */
efeaaf53
 
 
1ff47a5c
 /** @name SimpleLog
bf79b581
  * Simplier, prefered logging macros for constant log level
  */
1ff47a5c
 /*@ { */
a86d53b0
 #ifdef __SUNPRO_C
bf79b581
 #	define ALERT(...)  LOG(L_ALERT,  __VA_ARGS__)
54dc3302
 #	define BUG(...)    LOG(L_BUG,   __VA_ARGS__)
bf79b581
 #	define ERR(...)    LOG(L_ERR,    __VA_ARGS__)
 #	define WARN(...)   LOG(L_WARN,   __VA_ARGS__)
 #	define NOTICE(...) LOG(L_NOTICE, __VA_ARGS__)
 #	define INFO(...)   LOG(L_INFO,   __VA_ARGS__)
a07e7447
 #	define CRIT(...)    LOG(L_CRIT2,   __VA_ARGS__)
bf79b581
 
 #	ifdef NO_DEBUG
 #		define DBG(...)
 #	else
 #		define DBG(...)    LOG(L_DBG, __VA_ARGS__)
 #	endif		
1ff47a5c
 /*@ } */
bf79b581
 
 /* obsolete, do not use */
 #	define DEBUG(...) DBG(__VA_ARGS__)
a07e7447
 
 #else /* ! __SUNPRO_C */
20ce8764
 #	define ALERT(fmt, args...)  LOG(L_ALERT,  fmt , ## args)
 #	define BUG(fmt, args...)    LOG(L_BUG,   fmt , ## args)
 #	define ERR(fmt, args...)    LOG(L_ERR,    fmt , ## args)
 #	define WARN(fmt, args...)   LOG(L_WARN,   fmt , ## args)
 #	define NOTICE(fmt, args...) LOG(L_NOTICE, fmt , ## args)
 #	define INFO(fmt, args...)   LOG(L_INFO,   fmt , ## args)
 #	define CRIT(fmt, args...)   LOG(L_CRIT2,   fmt , ## args)
bf79b581
 
 #	ifdef NO_DEBUG
 #		define DBG(fmt, args...)
 #	else
20ce8764
 #		define DBG(fmt, args...)    LOG(L_DBG, fmt , ## args)
bf79b581
 #	endif		
 
 /* obsolete, do not use */
20ce8764
 #	define DEBUG(fmt, args...) DBG(fmt , ## args)
bf79b581
 		
 #endif /* __SUNPRO_C */
 
a86d53b0
 
4f69388d
 /* kamailio/openser compatibility */
 
 #define LM_GEN1 LOG
f5618c1a
 #define LM_GEN2 LOG_FC
4f69388d
 #define LM_ALERT ALERT
 #define LM_CRIT  CRIT
 #define LM_ERR ERR
 #define LM_WARN WARN
2d09ec6c
 #define LM_NOTICE NOTICE
4f69388d
 #define LM_INFO INFO
 #define LM_DBG DEBUG
 
bf79b581
 #endif /* !dprint_h */