libevent源码分析1---模块组成以及日志

勿在浮沙筑高台

libevent组件

evutil

用于抽象不同平台网络实现差异的通用功能

event和event_bask

libevent的核心,为各种平台特定的、基于事件的非阻塞IO后端提供抽象API,让程序可以知道套接字何时已经准备好,可以读或者可以写,并且处理基本的超时功能,检测OS信号

bufferevent

为livent基于事件的核心提供使用更方便的封装。除了通知程序套接字已经准备好读写之外,还
可以让程序可以请求缓冲的读写操作,可以知道何时IO已经真正发生(bufferevent接口有多个后端,可以采用系统能够提供的更快的非阻塞IO方式,如Windows中的IOCP。)

evbuffer

在bufferevent层之下实现了缓冲功能,并且提供了方便有效的访问函数

evhttp

一个简单的HTTP客户端/服务器实现

evdns

一个简单的DNS客户端/服务器实现

evrpc

一个简单的RPC实现

libevent库

libevent_core

所有核心的事件和缓冲功能,包含了所有的event_base、evbuffer、bufferevent和工具函数

libevent_extra

定义了程序可能需要,也可能不需要的协议特定功能,包括HTTP、DNS和RPC

日志模块分析

提供了四个等级的日志

#define EVENT_LOG_DEBUG 0
#define EVENT_LOG_MSG   1
#define EVENT_LOG_WARN  2
#define EVENT_LOG_ERR   3

用户需要定义一个回调用来接收libevnt的日志消息。

typedef void (*event_log_cb)(int severity, const char *msg);
void event_set_log_callback(event_log_cb cb);

从参数可知,用户可以指定获取哪个等级的日志消息,以及指定一个用来接收日志的缓冲区 msg。
同时调用 event_set_log_callback,将自定义的函数回调作为参数设置进去即可完成日志的获取。
进入 event_set_log_callback 函数,可以看到,libevent使用一个log_fn变量来接收用户自定义的日志回调函数。
当不想再继续接收日志信息的时候,重新调用event_set_log_callback函数,参数给 nullptr 即可;

static event_log_cb log_fn = NULL;
static void
event_log(int severity, const char *msg)
{
	if (log_fn)
		log_fn(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 = "err";
			break;
		default:
			severity_str = "???";
			break;
		}
		(void)fprintf(stderr, "[%s] %s\n", severity_str, msg);//打印日志信息
	}
}

实例:

#include <event2/event.h>
static void GetLog(int severity, const char *msg)
{
	const char *s;
	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);
	std::cout << s << "====" << msg << std::endl;
}
event_set_log_callback(GetLog);//注册回调

不能在定义的日志回调中调用libevent的API函数,否则可能会发生未定义行为
日志相关函数

#ifdef __GNUC__
#define EV_CHECK_FMT(a,b) __attribute__((format(printf, a, b)))
#define EV_NORETURN __attribute__((noreturn))
#else
#define EV_CHECK_FMT(a,b)
#define EV_NORETURN
#endif//当编译器是GNU的时候才会进行格式匹配检测
void event_err(int eval, const char *fmt, ...) EV_CHECK_FMT(2,3) EV_NORETURN;
void event_warn(const char *fmt, ...) EV_CHECK_FMT(1,2);
void event_sock_err(int eval, evutil_socket_t sock, const char *fmt, ...) EV_CHECK_FMT(3,4) EV_NORETURN;
void event_sock_warn(evutil_socket_t sock, const char *fmt, ...) EV_CHECK_FMT(2,3);
void event_errx(int eval, const char *fmt, ...) EV_CHECK_FMT(2,3) EV_NORETURN;
void event_warnx(const char *fmt, ...) EV_CHECK_FMT(1,2);
format (archetype, string-index, first-to-check)
  其中,“archetype”指定是哪种风格;“string-index”指定传入函数的第几个参数是格式化字符串;“first-to-check”指定从函数的第几个参数开始按上述规则进行检查。
void _event_debugx(const char *fmt, ...) EV_CHECK_FMT(1,2);
#define EV_CHECK_FMT(a,b) __attribute__((format(printf, a, b)))

上面就是日志的相关API函数。其中EV_CHECK_FMT
是一个宏,用来检测格式是否匹配
参考链接:https://blog.csdn.net/xiaozi0221/article/details/106893648

attribute format属性可以给被声明的函数加上类似printf或者scanf的特征,它可以使编译器检查函数声明和函数实际调用参数之间的格式化字符串是否匹配。format属性告诉编译器,按照printf, scanf等标准C函数参数格式规则对该函数的参数进行检查。这在我们自己封装调试信息的接口时非常的有用。

format (archetype, string-index, first-to-check)
  其中,“archetype”指定是哪种风格;“string-index”指定传
入函数的第几个参数是格式化字符串;“first-to-check”指定从函
数的第几个参数开始按上述规则进行检查。
void event_warnx(const char *fmt, ...) EV_CHECK_FMT(1,2);
以此为例,传入的第一个参数是格式化字符串,从函数的第二个参数开始进行检查

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一路初心向前

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值