First of all, the log is not comprehensive, only the error is implemented, the others can be implemented by referring to the source code:
#ifndef log_h_ #define log_h_ #include <stdarg.h> #include <string.h> #include <errno.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #define EVENT_LOG_DEBUG 0 #define EVENT_LOG_MSG 1 #define EVENT_LOG_WARN 2 #define EVENT_LOG_ERR 3 #define _EVENT_LOG_DEBUG EVENT_LOG_DEBUG #define _EVENT_LOG_MSG EVENT_LOG_MSG #define _EVENT_LOG_WARN EVENT_LOG_WARN #define _EVENT_LOG_ERR EVENT_LOG_ERR typedef void (*event_log)(int severity, const char *msg) //We mainly call him void event_error(const char* fmt,...); void event_warnx(const char *fmt, ...); void event_msgx(const char *fmt, ...); ///The following function is our internal, we can put it into a header file separately void _warn_helper(int severity,const char* errstr,char* fmt,va_list ap); void event_log(int severity, const char *msg); int evutil_snprintf(char* buf,int size ,char* fmt,...); int evutil_vsnprintf(char* buf,int size,char* fmt,va_list ap); #endif
Implementation of .c file
#include "build_libevent_log.h" //define global variable event_log func = NULL; //Set user-defined output format void event_set_log_callback(event_log cb) { func = cb; } void event_warnx(const char *fmt, ...) { va_list ap; va_start(ap, fmt); _warn_helper(EVENT_LOG_WARN, NULL, fmt, ap); va_end(ap); } void event_msgx(const char *fmt, ...) { va_list ap; va_start(ap, fmt); _warn_helper(EVENT_LOG_MSG, NULL, fmt, ap); va_end(ap); } void event_error(const char* fmt,...) { va_list ap; va_start(ap,fmt); //This is a proxy function, other priority functions can also call him _warn_helper(EVENT_LOG_ERR,strerror(errno),fmt,ap); va_end(ap); } void _warn_helper(int severity,const char* errstr,char* fmt,va_list ap) { char buf[1024]; if(fmt != NULL) { //Call the splicing function of the string. The format of the function is (char* buf, int size, char* fmt, va_list ap); evutil_vsnprintf(buf,sizeof(buf),fmt,ap); } if(errstr != NULL) { int len = strlen(buf); //The format of this function is (char* buf, int size, char* fmt,...); in fact, the above function is also the underlying implementation function of our function evutil_snprintf(buf + len,sizeof(buf) - len,": %s",errstr); } event_log(severity,buf); } int evutil_snprintf(char* buf,int size ,char* fmt,...) { int ret; va_list ap; va_start(ap,fmt); ret = evutil_vsnprintf(buf,size,fmt,ap); va_end(ap); return ret; } int evutil_vsnprintf(char* buf,int size,char* fmt,va_list ap) { int ret = vsnprintf(buf,size,fmt,ap); buf[size -1] = '\0'; return ret; } void event_log(int severity, const char *msg) { if(func) { func(severity,msg); } else{ const char *severity_str; switch (severity) { case _EVENT_LOG_DEBUG: severity_str = "debug"; break; case _EVENT_LOG_MSG: severity_str = "msg"; break; case _EVENT_LOG_WARN: severity_str = "warn"; break; case _EVENT_LOG_ERR: severity_str = "error"; break; default: break; } fprintf(stderr, "[%s] %s\n", severity_str, msg); } }