REDIS_NOTUSED(info);
REDIS_NOTUSED(sig);
sds st, log;
- time_t now = time(NULL);
- char date[128];
- FILE *fp;
- fp = (server.logfile == NULL) ? stdout : fopen(server.logfile,"a");
- if (fp == NULL) return;
-
- strftime(date,sizeof(date),"%d %b %H:%M:%S",localtime(&now));
- log = sdscatprintf(sdsempty(),
- "\n--- WATCHDOG TIMER EXPIRED (%s) ---\n",date);
+ log = sdsnew("\n--- WATCHDOG TIMER EXPIRED ---\n");
#ifdef HAVE_BACKTRACE
st = getStackTrace(uc);
#else
st = sdsnew("Sorry: no support for backtrace().\n");
#endif
log = sdscatsds(log,st);
- log = sdscat(log,"------\n\n");
- fprintf(fp,"%s",log);
- if (server.logfile) fclose(fp);
+ log = sdscat(log,"------\n");
+ redisLogFromHandler(REDIS_WARNING,log);
sdsfree(st);
sdsfree(log);
}
redisLogRaw(level,msg);
}
+/* Log a fixed message without printf-alike capabilities, in a way that is
+ * safe to call from a signal handler.
+ *
+ * We actually use this only for signals that are not fatal from the point
+ * of view of Redis. Signals that are going to kill the server anyway and
+ * where we need printf-alike features are served by redisLog(). */
+void redisLogFromHandler(int level, const char *msg) {
+ int fd;
+ char buf[64];
+
+ if ((level&0xff) < server.verbosity ||
+ (server.logfile == NULL && server.daemonize)) return;
+ fd = server.logfile ?
+ open(server.logfile, O_APPEND|O_CREAT|O_WRONLY, 0644) :
+ STDIN_FILENO;
+ if (fd == -1) return;
+ ll2string(buf,sizeof(buf),getpid());
+ write(fd,"[",1);
+ write(fd,buf,strlen(buf));
+ write(fd," | signal handler] (",20);
+ ll2string(buf,sizeof(buf),time(NULL));
+ write(fd,buf,strlen(buf));
+ write(fd,") ",2);
+ write(fd,msg,strlen(msg));
+ write(fd,"\n",1);
+ close(fd);
+}
+
/* 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
static void sigtermHandler(int sig) {
REDIS_NOTUSED(sig);
- redisLog(REDIS_WARNING,"Received SIGTERM, scheduling shutdown...");
+ redisLogFromHandler(REDIS_WARNING,"Received SIGTERM, scheduling shutdown...");
server.shutdown_asap = 1;
}
int prepareForShutdown();
void redisLog(int level, const char *fmt, ...);
void redisLogRaw(int level, const char *msg);
+void redisLogFromHandler(int level, const char *msg);
void usage();
void updateDictResizePolicy(void);
int htNeedsResize(dict *dict);