1.10. logger服务
涉及的结构体为:
struct logger {
FILE * handle; //用于存储log的输出,默认是控制台,否则为文档
char * filename; //如果是输出文件则保存文件名
int close; //标记是否需要关闭文档
};
logger服务主要用于log输出,在前面的1.3节中有介绍到,在函数skynet_start中会创建一个logger服务,在1.4节也介绍了服务的创建过程skynet_context_new,对于logger服务的创建过程为:首先根据配置文件中config->logservice(默认为“logger”)项指定的名称来获取服务动态库指针,然后调用logger_create函数创建一个服务实例,接着调用logger_init函数对实例进行初始化,如果配置文件config->logger这项有配置则用该配置名打开文件将log输入该文件,否则标准输出,注册该服务实例的回调函数,同时将该服务命名为“logger”。
//初始化给定的inst,如果parm不为NULL则创建一个文件用于存储,否则输出到标准输出
//将服务命名为logger
int logger_init(struct logger * inst, struct skynet_context *ctx, const char * parm) {
if (parm) { //如果参数不为NULL
inst->handle = fopen(parm,"w"); //打开parm指定的文件,返回文件句柄
if (inst->handle == NULL) {
return 1;
}
inst->filename = skynet_malloc(strlen(parm)+1);
strcpy(inst->filename, parm); //拷贝文件名
inst->close = 1; //标记问需要关闭文档
} else {
inst->handle = stdout; //否则为标准输出,即输出到控制台
}
if (inst->handle) {
skynet_callback(ctx, inst, logger_cb); //注册该服务实例的回调函数
skynet_command(ctx, "REG", ".logger"); //将服务命名为logger
return 0;
}
return 1;
}
logger服务的消息处理
关于服务的消息处理在1.6节有介绍,当从服务队列中取出消息进行处理时,如果该服务有注册回调函数则会调用相应的回调函数进行处理,而logger服务在logger_init函数中注册了回调函数logger_cb,所以对于该服务的每一条消息都会调用logger_cb函数进行处理,接下来看一下该函数的工作流程,该函数根据消息的类型对其进行处理,对于消息类型为PTYPE_SYSTEM的消息,该消息一般为输出终端关闭触发SIGHUP事件,定时器线程在处理过程中对该事件进行相应的处理signal_hup函数,即发送PTYPE_SYSTEM类型的消息,将log重定向到inst->filename指定的文件中。对于消息类型为PTYPE_TEXT的消息,即为正常的log输出。代码注释如下:
//处理该服务的消息回调函数
static int logger_cb(struct skynet_context * context, void *ud, int type, int session, uint32_t source, const void * msg, size_t sz) {
struct logger * inst = ud;
switch (type) {
case PTYPE_SYSTEM: //logger服务的系统消息,以追加的形式重定向log输出到inst->filename指定的文件
if (inst->filename) {
inst->handle = freopen(inst->filename, "a", inst->handle);
}
break;
case PTYPE_TEXT: //正常的log输出
fprintf(inst->handle, "[:%08x] ",source); //以“:”+8位十六进制的形式输出服务发送消息的服务handle
fwrite(msg, sz , 1, inst->handle); //输出消息内容
fprintf(inst->handle, "\n"); //回车
fflush(inst->handle); //刷新
break;
}
return 0;
}
skynet错误信息的输出skynet_error也是通过将错误信息以消息的形式压入logger服务的队列中,logger服务通过上述方式将错误信息输出。