/*============================ Utility functions ============================ */
-void redisLog(int level, const char *fmt, ...) {
+/* Low level logging. To use only for very big messages, otherwise
+ * redisLog() is to prefer. */
+void redisLogRaw(int level, const char *msg) {
const int syslogLevelMap[] = { LOG_DEBUG, LOG_INFO, LOG_NOTICE, LOG_WARNING };
const char *c = ".-*#";
time_t now = time(NULL);
- va_list ap;
FILE *fp;
char buf[64];
- char msg[REDIS_MAX_LOGMSG_LEN];
if (level < server.verbosity) return;
fp = (server.logfile == NULL) ? stdout : fopen(server.logfile,"a");
if (!fp) return;
- va_start(ap, fmt);
- vsnprintf(msg, sizeof(msg), fmt, ap);
- va_end(ap);
-
strftime(buf,sizeof(buf),"%d %b %H:%M:%S",localtime(&now));
fprintf(fp,"[%d] %s %c %s\n",(int)getpid(),buf,c[level],msg);
fflush(fp);
if (server.syslog_enabled) syslog(syslogLevelMap[level], "%s", msg);
}
+/* Like redisLogRaw() but with printf-alike support. This is the funciton 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];
+
+ if (level < server.verbosity) return;
+
+ va_start(ap, fmt);
+ vsnprintf(msg, sizeof(msg), fmt, ap);
+ va_end(ap);
+
+ redisLogRaw(level,msg);
+}
+
/* Redis generally does not try to recover from out of memory conditions
* when allocating objects or strings, it is not clear if it will be possible
* to report this condition to the client since the networking layer itself
createSharedObjects();
server.el = aeCreateEventLoop();
server.db = zmalloc(sizeof(redisDb)*server.dbnum);
- server.ipfd = anetTcpServer(server.neterr,server.port,server.bindaddr);
- if (server.ipfd == ANET_ERR) {
- redisLog(REDIS_WARNING, "Opening port: %s", server.neterr);
- exit(1);
+
+ if (server.port != 0) {
+ server.ipfd = anetTcpServer(server.neterr,server.port,server.bindaddr);
+ if (server.ipfd == ANET_ERR) {
+ redisLog(REDIS_WARNING, "Opening port: %s", server.neterr);
+ exit(1);
+ }
}
if (server.unixsocket != NULL) {
unlink(server.unixsocket); /* don't care if this fails */
}
if (server.ds_enabled) dsInit();
+ srand(time(NULL)^getpid());
}
/* Populates the Redis Command Table starting from the hard coded list
info = sdscatprintf(info,
"cache_max_memory:%llu\r\n"
"cache_blocked_clients:%lu\r\n"
+ "cache_io_queue_len:%lu\r\n"
+ "cache_io_jobs_new:%lu\r\n"
+ "cache_io_jobs_processing:%lu\r\n"
+ "cache_io_jobs_processed:%lu\r\n"
+ "cache_io_ready_clients:%lu\r\n"
,(unsigned long long) server.cache_max_memory,
- (unsigned long) server.cache_blocked_clients
+ (unsigned long) server.cache_blocked_clients,
+ (unsigned long) listLength(server.cache_io_queue),
+ (unsigned long) listLength(server.io_newjobs),
+ (unsigned long) listLength(server.io_processing),
+ (unsigned long) listLength(server.io_processed),
+ (unsigned long) listLength(server.io_ready_clients)
);
unlockThreadedIO();
}
/* Finally remove the selected key. */
if (bestkey) {
robj *keyobj = createStringObject(bestkey,sdslen(bestkey));
+ propagateExpire(db,keyobj);
dbDelete(db,keyobj);
server.stat_evictedkeys++;
decrRefCount(keyobj);
redisLog(REDIS_WARNING,
"======= Ooops! Redis %s got signal: -%d- =======", REDIS_VERSION, sig);
infostring = genRedisInfoString("all");
- redisLog(REDIS_WARNING, "%s",infostring);
+ redisLogRaw(REDIS_WARNING, infostring);
/* It's not safe to sdsfree() the returned string under memory
* corruption conditions. Let it leak as we are going to abort */