上一章介绍了libevent 的一些特性,本章重点介绍libevent库中的一些配置项。
libevent 有些在进程整个生命周期中都起作用的全局配置项。这些配置项也决定了libevent的某些行为。必须在调用libevent中的任何函数之前配置libevent。否则,libevent 可能处于不一致状态。
libevent中的日志
libevent 提供记录内部错误和警告消息的日志功能。如果在编译时设置了debug选项,也会记录debug 日志。默认情况下,这些消息都输出到标准错误(stderr)。可以通过提供自定义的日志函数覆盖默认行为。
Interface
#define EVENT_LOG_DEBUG 0 #define EVENT_LOG_MSG 1 #define EVENT_LOG_WARN 2 #define EVENT_LOG_ERR 3 /* Deprecated; see note at the end of this section */ #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_cb)(int severity, const char *msg); void event_set_log_callback(event_log_cb cb);
为了修改libevent 的默认日志记录方式,需提供自定义的符合event_log_cb 原型的函数。并且将其作为event_set_log_callback的参数调用event_set_log_callback。当libevent记录日志时,便会调用你提供的记日志函数。若想重新使用libevent的默认日志记录方式,以NULL为参数调用event_set_log_callback即可。
#include <event2/event.h> #include <stdio.h> static void discard_cb(int severity, const char *msg) { /* This callback does nothing. */ } static FILE *logfile = NULL; static void write_to_file_cb(int severity, const char *msg) { const char *s; if (!logfile) return; switch (severity) { case _EVENT_LOG_DEBUG: s = "debug"; break; case _EVENT_LOG_MSG: s = "msg"; break; case _EVENT_LOG_WARN: s = "warn"; break; case _EVENT_LOG_ERR: s = "error"; break; default: s = "?"; break; /* never reached */ } fprintf(logfile, "[%s] %s\n", s, msg); } /* Turn off all logging from Libevent. */ void suppress_logging(void) { event_set_log_callback(discard_cb); } /* Redirect all Libevent log messages to the C stdio file 'f'. */ void set_logfile(FILE *f) { logfile = f; event_set_log_callback(write_to_file_cb); }
在自定义的event_log_cb_callback 函数中调用libevent中的函数容易出现问题。比如,你想提供一个使用了bufferevents来输出警告消息到网络socket的日志回调函数,可能会陷入难于调试的BUG的困境当中。这个限制在将来的libevent版本中可能会被移除。通常情况下,debug日志是未开启的,也不会发送到日志回调函数。不过,可以手动开启debug 日志功能,如果构建的libevent支持此选项的话。
未完待续......