#include <mailutils/debug.h> typedef int mu_log_level_t; typedef int (*mu_debug_printer_fp)(void *,mu_log_level_t, const char*); int mu_debug_check_level(mu_debug_t debug, mu_log_level_t level); int mu_debug_create(mu_debug_t *debug,void *owner); int mu_debug_destroy(mu_debug_t *debug, void *owner); int mu_debug_get_function(mu_debug_t debug, const char **function); int mu_debug_get_level(mu_debug_t debug, mu_log_level_t *level); int mu_debug_get_locus(mu_debug_t debug, struct mu_debug_locus *locus); void* mu_debug_get_owner(mu_debug_t debug); int mu_debug_level_from_string(const char *string, mu_log_level_t *plev, mu_debug_t debug); int mu_debug_print(mu_debug_t debug,mu_log_level_t level, const char *fmt,...); int mu_debug_print(mu_debug_t debug,mu_log_level_t level, const char *fmt,...); int mu_debug_printv(mu_debug_t debug,mu_log_level_t level, const char *fmt,va_list ap); int mu_debug_set_data(mu_debug_t debug,void *data, void (*destroy)(void *), void *owner); int mu_debug_set_function(mu_debug_t debug,const char *function); int mu_debug_set_level(mu_debug_t debug, mu_log_level_t level); int mu_debug_set_locus(mu_debug_t debug,const char *file,int line); int mu_debug_set_print(mu_debug_t debug,mu_debug_printer_fp printer,void *owner); int mu_debug_vprintf(mu_debug_t debug,mu_log_level_t level, const char *fmt,va_list ap); int mu_global_debug_clear_level(const char *object_name); mu_log_level_t mu_global_debug_level(const char* object_name); int mu_global_debug_from_string(const char *string, const char *errpfx); int mu_global_debug_set_level(const char *object_name, mu_log_level_t level); char *mu_sockaddr_to_astr(const struct sockaddr *sa, int salen); void mu_sockaddr_to_str(const struct sockaddr *sa, int salen, char *bufptr, size_t buflen, size_t *plen); #include <mailutils/diag.h> void mu_diag_get_debug(mu_debug_t *debug); const char *mu_diag_level_to_string(mu_log_level_t level); int mu_diag_level_to_syslog(mu_log_level_t level); void mu_diag_output(mu_log_level_t level,const char *fmt,...); void mu_diag_printf(mu_log_level_t level,const char *fmt,...); void mu_diag_set_debug(mu_debug_t debug); void mu_diag_voutput(mu_log_level_t level,const char *fmt,va_list ap); void mu_diag_vprintf(mu_log_level_t level,const char *fmt,va_list ap); void mu_set_program_name(const char* program); #include <mailutils/error.h> int mu_error(const char *fmt,...); int mu_verror(const char *fmt,va_list ap);
There are 10 debug levels, MU_DEBUG_TRACE0-7, MU_DEBUG_ERROR and MU_DEBUG_PROT, which can be used to control the volume of debugging output produced.
To filter messages by level they should be generated using one of the following macros: MU_DEBUG(debug,level,x), MU_DEBUG1(debug,level,fmt,s1) to MU_DEBUG11(debug,level,fmt,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11) where debug is the debug object, level is the debug level,x is the message to output, fmt is a printf style format string and s1 to s11 are the parameters for this string. If the value of the mu_debug_line_info variable is 1 then the filename, line number and function name will be output as part of the message. The value of this variable can be set using the line-info option of the debug section in the configuration file.
If the “logging” capability is enabled and the configuration file has a logging section then output will be directed to syslogd otherwise it will be directed to stderr. It is possible to redirect the output to other destinations using the mu_debug_set_print function and changing the value of the mu_debug_default_printer global variable.
A global object for generating and displaying diagnostic messages based on a debug object is always available. Output is generated via calls to mu_error, mu_diag_output and the mu_diag_print routines. The log levels passed to these routines are one of MU_DIAG_EMERG, MU_DIAG_ALERT, MU_DIAG_CRIT, MU_DIAG_ERROR, MU_DIAG_WARNING, MU_DIAG_NOTICE, MU_DIAG_INFO, MU_DIAG_DEBUG which are mapped to the syslog levels. By default, output is directed to stderr. The destination can be changed by manipulating the underlying debug object, which can be obtained using the mu_diag_get_debug function. Output can be redirected to syslog by setting the print function on the debug object to mu_diag_syslog_printer.
typedef struct _mu_debug *mu_debug_t
This is an opaque data structure. None of the fields should be accessed by a user program.
struct mu_debug_locus
{
const char *file;
int line;
};
This structure is used to hold information about a location in a source file.
int mu_error(const char *fmt,...);
This routine outputs a formatted message using the global debug option and a level of MU_DIAG_ERROR. fmt holds the message as a “printf” style string with the following arguments being the parameters for the string.
int mu_debug_check_level(mu_debug_t debug, mu_log_level_t level);
This function returns TRUE if the level argument is one of the level's for which output is generated by the debug object.
int mu_debug_create(mu_debug_t *debug,void *owner);
Creates a new debug object. The function returns 0 is successful or an error code.
int mu_debug_destroy(mu_debug_t *debug, void *owner);
Releases resources associated with the debug object. The owner argument must equal the owner argument passed when the debug object was created.
int mu_debug_get_function(mu_debug_t debug, const char **function);
This function returns a pointer to the information stored by the most recent call to mu_debug_set_function. This function returns 0 if successful or an error code.
int mu_debug_get_level(mu_debug_t debug, mu_log_level_t *level);
This function returns, in level the bitmap of debug level(s) for which output is produced. This function returns 0 if successful or an error code.
int mu_debug_get_locus(mu_debug_t debug, struct mu_debug_locus *locus);
This function returns a pointer to the information stored by the most recent call to mu_debug_set_locus. This function returns 0 if successful or an error code.
void* mu_debug_get_owner(mu_debug_t debug);
Returns the owner argument passed to the mu_debug_create function.
int mu_debug_level_from_string(const char *string, mu_log_level_t *plev, mu_debug_t debug);
This function parses a level definition passed in string returning the bitmap in plev. The debug argument is a debug object which is used to output any errors.
int mu_debug_print(mu_debug_t debug,mu_log_level_t level, const char *fmt,...);
This routine outputs a formatted message, fmt holds a “printf” style string with the following arguments being the parameters for the string.
This routine should check that level passed in the level argument matches the levels set in the debug object but as of version 2.0 the test fails.
int mu_debug_printf(mu_debug_t debug,mu_log_level_t level, const char *fmt,...);
This routine outputs a formatted message, fmt holds a “printf” style string with the following arguments being the parameters for the string. This routine does not check whether or not the debug level passed in the level argument is one those for which the debug object generates output.
int mu_debug_printv(mu_debug_t debug,mu_log_level_t level, const char *fmt,va_list ap);
This routine outputs a formatted message, fmt holds a “printf” style string and ap holds the parameters for the string in va_list format.
This routine should check that level passed in the level argument matches the levels set in the debug object but as of version 2.0 the test fails.
int mu_debug_set_data(mu_debug_t debug,void *data, void (*destroy)(void *), void *owner);
This function sets the pointer, passed in data, which will be passed as the first argument to the print function set by a call to mu_debug_set_print. The destroy function is called when the debug object is destroyed to free data. The function returns 0 if successful or an error code.
int mu_debug_set_function(mu_debug_t debug,const char *function);
This function is called by the MU_DEBUGx macro's in order to store the name of the current function. The function could be called directly to store other information which may be useful for debugging. This function returns 0 if successful or an error code.
int mu_debug_set_level(mu_debug_t debug, mu_log_level_t level);
This function sets the debug level(s) for which output is produced. The level argument is a bitmap generated from the MU_DEBUG_x level identifiers using the MU_DEBUG_LEVEL_MASK(level) macro or the MU_DEBUG_LEVEL_UPTO(level) macro to enable all levels up to and including a particular level. This function returns 0 if successful or an error code.
int mu_debug_set_locus(mu_debug_t debug,const char *file,int line);
This function is called by the MU_DEBUGx macro's in order to store the location of the macro in the source file. The function could be called directly to store other information which may be useful for debugging. This function returns 0 if successful or an error code.
int mu_debug_set_print(mu_debug_t debug,mu_debug_printer_fp printer,void *owner);
This function is used to set the routine which is called to actually output the message. The owner argument must equal the owner argument passed when the debug object was created. This function returns 0 if successful or an error code.
The printer function takes 3 arguments. The first is a pointer which is set by a previous call to mu_debug_set_data, the second is the level of the error message and the third is the message to output. The function should return 0 if successful or an error code.
The library provides two standard functions, mu_debug_stderr_printer which outputs the message to stderr and mu_debug_syslog_printer which sends the message to syslogd.
int mu_debug_vprintf(mu_debug_t debug,mu_log_level_t level, const char *fmt,va_list ap);
This routine outputs a formatted message, fmt holds a “printf” style string and ap holds the parameters for the string in va_list format. This routine does not check whether or not the debug level passed in the level argument is one those for which the debug object generates output.
All the print routines eventually call this one in order to actually generate the output. To actually produce the output a terminating newline character is needed.
void mu_diag_get_debug(mu_debug_t *debug);
This function returns the global debug object.
const char *mu_diag_level_to_string(mu_log_level_t level);
This function is used to map the message levels passed to the mu_diag_print functions to a string.
int mu_diag_level_to_syslog(mu_log_level_t level);
This function is used to map the message levels passed to the mu_diag_print functions to the syslog levels.
void mu_diag_output(mu_log_level_t level,const char *fmt,...);
This routine outputs a formatted message, fmt holds a “printf” style string with the following arguments being the parameters for the string. Unlike the mu_diag_printf, this routine will automatically output a newline character so forcing the message to be displayed.
void mu_diag_printf(mu_log_level_t level,const char *fmt,...);
This routine outputs a formatted message, fmt holds a “printf” style string with the following arguments being the parameters for the string. As the message is generated via the debug object, it must be terminated with a newline character in order to be displayed.
void mu_diag_set_debug(mu_debug_t debug);
This function replaces the current debug object which drives the diagnostic system, with the one passed in debug.
void mu_diag_voutput(mu_log_level_t level,const char *fmt,va_list ap);
This routine outputs a formatted message, fmt holds a “printf” style string with ap holding the parameters for the string in va_list format. Unlike the mu_diag_vprintf, this routine will automatically output a newline character so forcing the message to be displayed.
void mu_diag_vprintf(mu_log_level_t level,const char *fmt,va_list ap);
This routine outputs a formatted message, fmt holds a “printf” style string with ap holding the parameters for the string in va_list format. As the message is generated via the debug object, it must be terminated with a newline character in order to be displayed.
int mu_global_debug_clear_level(const char *object_name);
If object_name is NULL then all debug settings extracted from the configuration file are removed. If object_name is not NULL then only the debug setting which is equal to object_name is removed. The function returns 0 if successful or an error code.
int mu_global_debug_from_string(const char *string, const char *errpfx);
This function parses the debug specification line passed in string storing the bitmaps in the global debug data. The string errpfx is used to generate the error message if the parsing fails. The function return 0 if successful or an error code.
mu_log_level_t mu_global_debug_level(const char* object_name);
This function returns the bitmap of trace flags which have been defined in the configuration file for the item passed in the object_name argument.
int mu_global_debug_set_level(const char *object_name, mu_log_level_t level);
This function sets the bitmap of trace flags associated with object_name to the value passed in level. The function returns 0 or MU_ERR_EXISTS if successful or an error code.
void mu_set_program_name(const char* program);
This sets the program name which is output as part of messages from the global diagnostic object.
char *mu_sockaddr_to_astr(const struct sockaddr *sa, int salen);
Returns a pointer to the information stored in the socket structure sa of size salen formatted as a string. The allocated string should be free'd when it is no longer needed.
void mu_sockaddr_to_str(const struct sockaddr *sa, int salen, char *bufptr, size_t buflen, size_t *plen);
Formats the information stored in the socket structure sa of size salen as a string and stores it in the character array bufptr of size buflen. The actual number of characters written is returned in plen.
int mu_verror(const char *fmt,va_list ap);
This routine outputs a formatted message using the global debug option and a level of MU_DIAG_ERROR. fmt holds the message as a “printf” style string with ap holding the parameters for the string in va_list format.
By default, messages passed to syslogd will be logged with the system default logging characteristics. These defaults can be overridden by calling openlog(3).
The following items are defined in mailutils/syslog.h:
If the “logging” capability is enabled for the program then the the mu_log_tag and mu_log_facility variables can be set via the configuration file.
e.g.
openlog(MU_LOG_TAG(),LOG_PID,mu_log_facility);