diff --git a/src/ckpool.c b/src/ckpool.c index 01a9639e..02a63059 100644 --- a/src/ckpool.c +++ b/src/ckpool.c @@ -7,6 +7,8 @@ * any later version. See COPYING for more details. */ +#include "config.h" + #include #include #include @@ -216,6 +218,7 @@ static void clean_up(ckpool_t *ckp) for (i = 0; i < children; i++) dealloc(ckp->children[i]); dealloc(ckp->children); + fclose(ckp->logfp); } static void __shutdown_children(ckpool_t *ckp, int sig) @@ -436,7 +439,7 @@ int main(int argc, char **argv) { struct sigaction handler; int len, c, ret, i; - char buf[16] = {}; + char buf[512] = {}; ckpool_t ckp; global_ckp = &ckp; @@ -479,6 +482,8 @@ int main(int argc, char **argv) } snprintf(buf, 15, "%s", ckp.name); prctl(PR_SET_NAME, buf, 0, 0, 0); + memset(buf, 0, 15); + if (!ckp.config) { ckp.config = strdup(ckp.name); realloc_strcat(&ckp.config, ".conf"); @@ -532,6 +537,7 @@ int main(int argc, char **argv) if (ckp.proxy && !ckp.proxies) quit(0, "No proxy entries found in config file %s", ckp.config); + /* Create the log directory */ len = strlen(ckp.logdir); if (memcmp(&ckp.logdir[len], "/", 1)) realloc_strcat(&ckp.logdir, "/"); @@ -539,6 +545,13 @@ int main(int argc, char **argv) if (ret && errno != EEXIST) quit(1, "Failed to make log directory %s", ckp.logdir); + /* Create the logfile */ + sprintf(buf, "%s%s.log", ckp.logdir, ckp.name); + ckp.logfp = fopen(buf, "a"); + if (!ckp.logfp) + quit(1, "Failed to make open log file %s", buf); + ckp.logfd = fileno(ckp.logfp); + ckp.main.ckp = &ckp; ckp.main.processname = strdup("main"); ckp.main.sockname = strdup("listener"); diff --git a/src/ckpool.h b/src/ckpool.h index f59004dd..130b9090 100644 --- a/src/ckpool.h +++ b/src/ckpool.h @@ -12,6 +12,8 @@ #include "config.h" +#include + #include "libckpool.h" #include "uthash.h" @@ -56,6 +58,9 @@ struct ckpool_instance { char *socket_dir; /* Directory where logs are written */ char *logdir; + /* Logfile */ + FILE *logfp; + int logfd; /* Process instance data of parent/child processes */ proc_instance_t main; @@ -105,26 +110,41 @@ ckpool_t *global_ckp; int process_exit(ckpool_t *ckp, proc_instance_t *pi, int ret); -/* Placeholders for when we have more comprehensive logging facilities */ - +/* Log everything to the logfile, but display warnings on the console as well */ #define LOGMSG(_loglevel, fmt, ...) do { \ if (global_ckp->loglevel >= _loglevel && fmt) { \ struct tm *tm; \ + char *buf = NULL; \ + asprintf(&buf, fmt, ##__VA_ARGS__); \ time_t now_t; \ now_t = time(NULL); \ tm = localtime(&now_t); \ - fprintf(stderr, "[%d-%02d-%02d %02d:%02d:%02d] ", \ + flock(global_ckp->logfd, LOCK_EX); \ + fprintf(global_ckp->logfp, "[%d-%02d-%02d %02d:%02d:%02d] %s", \ tm->tm_year + 1900, \ tm->tm_mon + 1, \ tm->tm_mday, \ tm->tm_hour, \ tm->tm_min, \ - tm->tm_sec); \ - fprintf(stderr, fmt, ##__VA_ARGS__); \ + tm->tm_sec, \ + buf); \ if (_loglevel <= LOG_ERR) \ - fprintf(stderr, " with errno %d: %s", errno, strerror(errno)); \ - fprintf(stderr, "\n"); \ - fflush(stderr); \ + fprintf(global_ckp->logfp, " with errno %d: %s", errno, strerror(errno)); \ + fprintf(global_ckp->logfp, "\n"); \ + if (_loglevel <= LOG_WARNING) \ + fprintf(stderr, "%s\n", buf); \ + fflush(NULL); \ + flock(global_ckp->logfd, LOCK_UN); \ + free(buf); \ + } \ +} while (0) + +#define LOGBOTH(_loglevel, fmt, ...) do { \ + if (global_ckp->loglevel >= _loglevel && fmt) { \ + char *buf = NULL; \ + asprintf(&buf, fmt, ##__VA_ARGS__); \ + printf("%s\n", buf); \ + free(buf); \ } \ } while (0)