,pfdebugCommand,-3,"w",0,NULL,0,0,0,0,0},
{"latency",latencyCommand,-2,"arslt",0,NULL,0,0,0,0,0}
};
接下来是服务器日志记录函数:
?
/* 低级别日志记录函数,用于存储大文本信息否则redisLog更合适*/
void redisLogRaw(int level, const char *msg) {
//定义日志级别
const int syslogLevelMap[] = { LOG_DEBUG, LOG_INFO, LOG_NOTICE, LOG_WARNING };
//char指针指向.数组元素
const char *c = ".-*#";
//文件指针
FILE *fp;
//缓存数组
char buf[64];
//原始模式
int rawmode = (level & REDIS_LOG_RAW);
//如果server的日志文件是null则表示日志记录到控制台
int log_to_stdout = server.logfile[0] == '\0';
//清除标志位
level &= 0xff; /* clear flags */
//如果日志级别小于配置的级别则直接返回
if (level < server.verbosity) return;
//如果是打印日志到控制台则fp就是控制台如果是打印日志到文件则打开server配置的日志文件
fp = log_to_stdout ? stdout : fopen(server.logfile,"a");
//如果fp不存在(空指针)则返回
if (!fp) return;
//如果是rawmode
if (rawmode) {
//往日志fp写入信息
fprintf(fp,"%s",msg);
} else {
//代表字符偏移量,也是Epoch时间转化成字符串后的长度
int off;
//记录Epoch时间的结构体
struct timeva l tv;
//表示角色
int role_char;
//获取当前进程号
pid_t pid = getpid();
//获取Epoch时间
gettimeofday(&tv,NULL);
//根据locale获取转化后字符串的长度
off = strftime(buf,sizeof(buf),"%d %b %H:%M:%S.",localtime(&tv.tv_sec));
//
snprintf(buf+off,sizeof(buf)-off,"%03d",(int)tv.tv_usec/1000);
//如果服务器配置成sentinel机制
if (server.sentinel_mode) {
//X角色,代表sentinel机制
role_char = 'X'; /* Sentinel. */
} else if (pid != server.pid) {
//如果获取当前的进程不是server的进程,则是RDB/AOF持久化时的写数据子进程
role_char = 'C'; /* RDB / AOF writing child. */
} else {
//如果server的masterhost为真则是从服务器否则是主服务器
role_char = (server.masterhost ? 'S':'M'); /* Slave or Master. */
}
//打印日志记录的信息
fprintf(fp,"%d:%c %s %c %s\n",
(int)getpid(),role_char, buf,c[level],msg);
}
//清空文件
fflush(fp);
//关闭文件
if (!log_to_stdout) fclose(fp);
//如果server的系统级日志记录开启则调用syslog记录日志
if (server.syslog_enabled) syslog(syslogLevelMap[level], "%s", msg);
}