Permalink
Browse files

syslog support

  • Loading branch information...
jonahharris committed Dec 9, 2010
1 parent d51ebef commit e1a586ee69a15dd15afbba8e25f8eb62bbb22da9
Showing with 74 additions and 8 deletions.
  1. +10 −0 redis.conf
  2. +40 −0 src/config.c
  3. +19 −8 src/redis.c
  4. +5 −0 src/redis.h
View
@@ -50,6 +50,16 @@ loglevel verbose
# output for logging but daemonize, logs will be sent to /dev/null
logfile stdout
+# To enable logging to the system logger, just set 'syslog-enabled' to yes,
+# and optionally update the other syslog parameters to suit your needs.
+# syslog-enabled no
+
+# Specify the syslog identity.
+# syslog-ident redis
+
+# Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7.
+# syslog-facility local0
+
# Set the number of databases. The default database is DB 0, you can select
# a different one on a per-connection basis using SELECT <dbid> where
# dbid is a number between 0 and 'databases'-1
View
@@ -114,6 +114,46 @@ void loadServerConfig(char *filename) {
}
fclose(logfp);
}
+ } else if (!strcasecmp(argv[0],"syslog-enabled") && argc == 2) {
+ if ((server.syslog_enabled = yesnotoi(argv[1])) == -1) {
+ err = "argument must be 'yes' or 'no'"; goto loaderr;
+ }
+ } else if (!strcasecmp(argv[0],"syslog-ident") && argc == 2) {
+ if (server.syslog_ident) zfree(server.syslog_ident);
+ server.syslog_ident = zstrdup(argv[1]);
+ } else if (!strcasecmp(argv[0],"syslog-facility") && argc == 2) {
+ struct {
+ const char *name;
+ const int value;
+ } validSyslogFacilities[] = {
+ {"user", LOG_USER},
+ {"local0", LOG_LOCAL0},
+ {"local1", LOG_LOCAL1},
+ {"local2", LOG_LOCAL2},
+ {"local3", LOG_LOCAL3},
+ {"local4", LOG_LOCAL4},
+ {"local5", LOG_LOCAL5},
+ {"local6", LOG_LOCAL6},
+ {"local7", LOG_LOCAL7},
+ {NULL, 0}
+ };
+ int i;
+
+ for (i = 0; validSyslogFacilities[i].name; i++) {
+ if (!strcasecmp(validSyslogFacilities[i].name, argv[1])) {
+ server.syslog_facility = validSyslogFacilities[i].value;
+ break;
+ }
+ }
+
+ if (!validSyslogFacilities[i].name) {
+ err = "Invalid log facility. Must be one of USER or between LOCAL0-LOCAL7";
+ goto loaderr;
+ }
+ } else if (!strcasecmp(argv[0],"syslog-ident") && argc == 2) {
+
+
+ server.syslog_ident = zstrdup(argv[1]);
} else if (!strcasecmp(argv[0],"databases") && argc == 2) {
server.dbnum = atoi(argv[1]);
if (server.dbnum < 1) {
View
@@ -188,27 +188,30 @@ struct redisCommand readonlyCommandTable[] = {
/*============================ Utility functions ============================ */
void redisLog(int level, const char *fmt, ...) {
+ 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 *c = ".-*#";
char buf[64];
- time_t now;
+ 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);
- now = time(NULL);
- strftime(buf,64,"%d %b %H:%M:%S",localtime(&now));
- fprintf(fp,"[%d] %s %c ",(int)getpid(),buf,c[level]);
- vfprintf(fp, fmt, ap);
- fprintf(fp,"\n");
- fflush(fp);
+ 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.logfile) fclose(fp);
+
+ if (server.syslog_enabled) syslog(syslogLevelMap[level], "%s", msg);
}
/* Redis generally does not try to recover from out of memory conditions
@@ -743,6 +746,9 @@ void initServerConfig() {
server.saveparams = NULL;
server.loading = 0;
server.logfile = NULL; /* NULL = log on standard output */
+ server.syslog_enabled = 0;
+ server.syslog_ident = zstrdup("redis");
+ server.syslog_facility = LOG_LOCAL0;
server.glueoutputbuf = 1;
server.daemonize = 0;
server.appendonly = 0;
@@ -813,6 +819,11 @@ void initServer() {
signal(SIGPIPE, SIG_IGN);
setupSigSegvAction();
+ if (server.syslog_enabled) {
+ openlog(server.syslog_ident, LOG_PID | LOG_NDELAY | LOG_NOWAIT,
+ server.syslog_facility);
+ }
+
server.mainthread = pthread_self();
server.clients = listCreate();
server.slaves = listCreate();
View
@@ -17,6 +17,7 @@
#include <errno.h>
#include <inttypes.h>
#include <pthread.h>
+#include <syslog.h>
#include "ae.h" /* Event driven programming library */
#include "sds.h" /* Dynamic safe strings */
@@ -47,6 +48,7 @@
#define REDIS_REQUEST_MAX_SIZE (1024*1024*256) /* max bytes in inline command */
#define REDIS_SHARED_INTEGERS 10000
#define REDIS_REPLY_CHUNK_BYTES (5*1500) /* 5 TCP packets with default MTU */
+#define REDIS_MAX_LOGMSG_LEN 1024 /* Default maximum length of syslog messages */
/* If more then REDIS_WRITEV_THRESHOLD write packets are pending use writev */
#define REDIS_WRITEV_THRESHOLD 3
@@ -402,6 +404,9 @@ struct redisServer {
struct saveparam *saveparams;
int saveparamslen;
char *logfile;
+ int syslog_enabled;
+ char *syslog_ident;
+ int syslog_facility;
char *dbfilename;
char *appendfilename;
char *requirepass;

0 comments on commit e1a586e

Please sign in to comment.