diff --git a/core/logging.c b/core/logging.c index 12441608..ec219aba 100644 --- a/core/logging.c +++ b/core/logging.c @@ -354,51 +354,51 @@ void uwsgi_setup_log() { static struct uwsgi_logger *setup_choosen_logger(struct uwsgi_string_list *usl) { char *id = NULL; - char *name = usl->value; + char *name = usl->value; - char *space = strchr(name, ' '); - if (space) { - int is_id = 1; - int i; - for (i = 0; i < (space - name); i++) { - if (!isalnum((int)name[i])) { - is_id = 0; - break; - } - } - if (is_id) { - id = uwsgi_concat2n(name, space - name, "", 0); - name = space + 1; - } - } + char *space = strchr(name, ' '); + if (space) { + int is_id = 1; + int i; + for (i = 0; i < (space - name); i++) { + if (!isalnum((int)name[i])) { + is_id = 0; + break; + } + } + if (is_id) { + id = uwsgi_concat2n(name, space - name, "", 0); + name = space + 1; + } + } - char *colon = strchr(name, ':'); - if (colon) { - *colon = 0; - } + char *colon = strchr(name, ':'); + if (colon) { + *colon = 0; + } - struct uwsgi_logger *choosen_logger = uwsgi_get_logger(name); - if (!choosen_logger) { - uwsgi_log("unable to find logger %s\n", name); - exit(1); - } + struct uwsgi_logger *choosen_logger = uwsgi_get_logger(name); + if (!choosen_logger) { + uwsgi_log("unable to find logger %s\n", name); + exit(1); + } - // make a copy of the logger - struct uwsgi_logger *copy_of_choosen_logger = uwsgi_malloc(sizeof(struct uwsgi_logger)); - memcpy(copy_of_choosen_logger, choosen_logger, sizeof(struct uwsgi_logger)); - choosen_logger = copy_of_choosen_logger; - choosen_logger->id = id; - choosen_logger->next = NULL; + // make a copy of the logger + struct uwsgi_logger *copy_of_choosen_logger = uwsgi_malloc(sizeof(struct uwsgi_logger)); + memcpy(copy_of_choosen_logger, choosen_logger, sizeof(struct uwsgi_logger)); + choosen_logger = copy_of_choosen_logger; + choosen_logger->id = id; + choosen_logger->next = NULL; - if (colon) { - choosen_logger->arg = colon + 1; - // check for empty string - if (*choosen_logger->arg == 0) { - choosen_logger->arg = NULL; - } - *colon = ':'; - } - return choosen_logger; + if (colon) { + choosen_logger->arg = colon + 1; + // check for empty string + if (*choosen_logger->arg == 0) { + choosen_logger->arg = NULL; + } + *colon = ':'; + } + return choosen_logger; } void uwsgi_setup_log_master(void) { @@ -519,40 +519,46 @@ void uwsgi_check_logrotate(void) { } } -void uwsgi_log_rotate() { - if (!uwsgi.logfile) return; - char *rot_name = uwsgi.log_backupname; - int need_free = 0; - if (rot_name == NULL) { - char *ts_str = uwsgi_num2str((int) uwsgi_now()); - rot_name = uwsgi_concat3(uwsgi.logfile, ".", ts_str); - free(ts_str); - need_free = 1; - } - // this will be rawly written to the logfile - uwsgi_logfile_write("logsize: %llu, triggering rotation to %s...\n", (unsigned long long) uwsgi.shared->logsize, rot_name); - if (rename(uwsgi.logfile, rot_name) == 0) { - // reopen logfile and dup'it, on dup2 error, exit(1) - int fd = open(uwsgi.logfile, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP); - if (fd < 0) { - // this will be written to the original file - uwsgi_error_open(uwsgi.logfile); +void uwsgi_log_do_rotate(char *logfile, char *rotatedfile, off_t logsize, int log_fd) { + int need_free = 0; + char *rot_name = rotatedfile; + + if (rot_name == NULL) { + char *ts_str = uwsgi_num2str((int) uwsgi_now()); + rot_name = uwsgi_concat3(logfile, ".", ts_str); + free(ts_str); + need_free = 1; + } + // this will be rawly written to the logfile + uwsgi_logfile_write("logsize: %llu, triggering rotation to %s...\n", (unsigned long long) logsize, rot_name); + if (rename(logfile, rot_name) == 0) { + // reopen logfile and dup'it, on dup2 error, exit(1) + int fd = open(logfile, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP); + if (fd < 0) { + // this will be written to the original file + uwsgi_error_open(logfile); + exit(1); + } + else { + if (dup2(fd, log_fd) < 0) { + // this could be lost :( + uwsgi_error("uwsgi_log_do_rotate()/dup2()"); exit(1); - } - else { - if (dup2(fd, uwsgi.original_log_fd) < 0) { - // this could be lost :( - uwsgi_error("uwsgi_log_rotate()/dup2()"); - exit(1); - } - close(fd); - } - } - else { - uwsgi_error("unable to rotate log: rename()"); - } - if (need_free) - free(rot_name); + } + close(fd); + } + } + else { + uwsgi_error("unable to rotate log: rename()"); + } + if (need_free) + free(rot_name); +} + +void uwsgi_log_rotate() { + if (!uwsgi.logfile) + return; + uwsgi_log_do_rotate(uwsgi.logfile, uwsgi.log_backupname, uwsgi.shared->logsize, uwsgi.original_log_fd); } void uwsgi_log_reopen() { diff --git a/plugins/logfile/logfile.c b/plugins/logfile/logfile.c index 2d027c34..a33e9858 100644 --- a/plugins/logfile/logfile.c +++ b/plugins/logfile/logfile.c @@ -1,10 +1,49 @@ #include +struct logfile_data { + char *logfile; + char *backupname; + uint64_t maxsize; +}; + static ssize_t uwsgi_file_logger(struct uwsgi_logger *ul, char *message, size_t len) { if (!ul->configured) { if (ul->arg) { - ul->fd = open(ul->arg, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP); + int is_keyval = 0; + char *backupname = NULL; + char *maxsize = NULL; + char *logfile = NULL; + + if (strchr(ul->arg, '=')) { + if (uwsgi_kvlist_parse(ul->arg, strlen(ul->arg), ',', '=', + "logfile", &logfile, "backupname", &backupname, "maxsize", &maxsize, NULL)) { + uwsgi_log("[uwsgi-logfile] invalid keyval syntax\n"); + exit(1); + } + is_keyval = 1; + } + if (is_keyval) { + if (!logfile) { + uwsgi_log("[uwsgi-logfile] missing logfile key\n"); + return 0; + } + + if (maxsize) { + struct logfile_data *data = uwsgi_malloc(sizeof(struct logfile_data)); + data->logfile = logfile; + data->backupname = backupname; + data->maxsize = (uint64_t)strtoull(maxsize, NULL, 10); + ul->data = data; + + free(maxsize); + maxsize = NULL; + } + } else { + logfile = ul->arg; + } + + ul->fd = open(logfile, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP); if (ul->fd >= 0) { ul->configured = 1; } @@ -12,10 +51,21 @@ static ssize_t uwsgi_file_logger(struct uwsgi_logger *ul, char *message, size_t } if (ul->fd >= 0) { - return write(ul->fd, message, len); - } - return 0; + ssize_t written = write(ul->fd, message, len); + if (ul->data) { + struct logfile_data *data = ul->data; + off_t logsize = lseek(ul->fd, 0, SEEK_CUR); + + if (data->maxsize > 0 && (uint64_t) logsize > data->maxsize) { + uwsgi_log_do_rotate(data->logfile, data->backupname, logsize, ul->fd); + } + } + + return written; + } + + return 0; } static ssize_t uwsgi_fd_logger(struct uwsgi_logger *ul, char *message, size_t len) { diff --git a/uwsgi.h b/uwsgi.h index 7d43db90..3c7f6f1f 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -4592,6 +4592,7 @@ void uwsgi_master_fifo_prepare(); int uwsgi_master_fifo(); int uwsgi_master_fifo_manage(int); +void uwsgi_log_do_rotate(char *, char *, off_t, int); void uwsgi_log_rotate(); void uwsgi_log_reopen(); void uwsgi_reload_workers();