int luaLogCommand(lua_State *lua) { int j, argc = lua_gettop(lua); int level; sds log; if (argc < 2) { luaPushError(lua, "redis.log() requires two arguments or more."); return 1; } else if (!lua_isnumber(lua,-argc)) { luaPushError(lua, "First argument must be a number (log level)."); return 1; } level = lua_tonumber(lua,-argc); if (level < REDIS_DEBUG || level > REDIS_WARNING) { luaPushError(lua, "Invalid debug level."); return 1; } /* Glue together all the arguments */ log = sdsempty(); for (j = 1; j < argc; j++) { size_t len; char *s; s = (char*)lua_tolstring(lua,(-argc)+j,&len); if (s) { if (j != 1) log = sdscatlen(log," ",1); log = sdscatlen(log,s,len); } } redisLogRaw(level,log); sdsfree(log); return 0; }
// redis log(组织日志内容) void redisLog(int level, const char *fmt, ...) { va_list ap; char msg[REDIS_MAX_LOGMSG_LEN]; // & 0xff(补码), level永为正 if ((level & 0xff) < server.verbosity) return; va_start(ap, fmt); vsnprintf(msg, sizeof(msg), fmt, ap); va_end(ap); // 根据设定的日志等级来写日志 redisLogRaw(level, msg); }
/* Like redisLogRaw() but with printf-alike support. This is the function that * is used across the code. The raw version is only used in order to dump * the INFO output on crash. */ void redisLog(int level, const char *fmt, ...) { va_list ap; char msg[REDIS_MAX_LOGMSG_LEN]; int vlen; if ((level&0xff) < verbosity) return; va_start(ap, fmt); vlen = vsnprintf(msg, sizeof(msg), fmt, ap); va_end(ap); /* The MS CRT implementation of vsnprintf/snprintf returns -1 if the formatted output doesn't fit the buffer, * in addition to when an encoding error occurs. Proceeding with a zero-terminated ellipsis at the end of the * buffer seems a better option than not logging this message at all. */ if (vlen < 0 || vlen >= sizeof(msg)) { strncpy(msg + sizeof(msg) - sizeof(ellipsis), ellipsis, sizeof(ellipsis)); } redisLogRaw(level,msg); }