Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes / improvements related to logger #2676

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 59 additions & 41 deletions core/logging.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,13 @@ void create_logpipe(void) {

}

mode_t uwsgi_get_logfile_chmod_value() {
if (uwsgi.chmod_logfile_value)
return uwsgi.chmod_logfile_value;
else
return S_IRUSR | S_IWUSR | S_IRGRP;
}

// log to the specified file or udp address
void logto(char *logfile) {

Expand Down Expand Up @@ -279,22 +286,16 @@ void logto(char *logfile) {
}
else {
if (uwsgi.log_truncate) {
fd = open(logfile, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP);
fd = open(logfile, O_RDWR | O_CREAT | O_TRUNC, uwsgi_get_logfile_chmod_value());
}
else {
fd = open(logfile, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP);
fd = open(logfile, O_RDWR | O_CREAT | O_APPEND, uwsgi_get_logfile_chmod_value());
}
if (fd < 0) {
uwsgi_error_open(logfile);
exit(1);
}
uwsgi.logfile = logfile;

if (uwsgi.chmod_logfile_value) {
if (fchmod(fd, uwsgi.chmod_logfile_value)) {
uwsgi_error("fchmod()");
}
}
}


Expand Down Expand Up @@ -530,20 +531,30 @@ void uwsgi_check_logrotate(void) {
}

void uwsgi_log_do_rotate(char *logfile, char *rotatedfile, off_t logsize, int log_fd) {
int need_free = 0;
char *rot_name = rotatedfile;
time_t rawtime = uwsgi_now();
struct tm *current = localtime(&rawtime);

if (rot_name == NULL) {
char *ts_str = uwsgi_num2str((int) uwsgi_now());
rot_name = uwsgi_concat3(logfile, ".", ts_str);
free(ts_str);
int need_free = 0;
char *rot_base_name = rotatedfile;
if (rot_base_name == NULL) {
rot_base_name = uwsgi_concat2(logfile, ".%Y-%m-%dT%X");
need_free = 1;
}

size_t rot_name_len = strlen(rot_base_name) + 64;
char *rot_name = uwsgi_malloc(rot_name_len);

if (strftime(rot_name, rot_name_len, rot_base_name, current) == 0) {
uwsgi_error("uwsgi_log_do_rotate()/strftime() (maybe too long)");
}
if (need_free)
free(rot_base_name);

// 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);
int fd = open(logfile, O_RDWR | O_CREAT | O_TRUNC, uwsgi_get_logfile_chmod_value());
if (fd < 0) {
// this will be written to the original file
uwsgi_error_open(logfile);
Expand All @@ -561,8 +572,8 @@ void uwsgi_log_do_rotate(char *logfile, char *rotatedfile, off_t logsize, int lo
else {
uwsgi_error("unable to rotate log: rename()");
}
if (need_free)
free(rot_name);

free(rot_name);
}

void uwsgi_log_rotate() {
Expand All @@ -571,33 +582,40 @@ void uwsgi_log_rotate() {
uwsgi_log_do_rotate(uwsgi.logfile, uwsgi.log_backupname, uwsgi.shared->logsize, uwsgi.original_log_fd);
}

void uwsgi_opt_add_cron_logrotate(char *opt, char *value, void *foobar) {
struct uwsgi_cron *uc = uwsgi_cron_add(value);
uc->func = uwsgi_log_rotate;
}

void uwsgi_log_reopen() {
char message[1024];
if (!uwsgi.logfile) return;
if (!uwsgi.logfile)
return;
int ret = snprintf(message, 1024, "[%d] logsize: %llu, triggering log-reopen...\n", (int) uwsgi_now(), (unsigned long long) uwsgi.shared->logsize);
if (ret > 0 && ret < 1024) {
if (write(uwsgi.original_log_fd, message, ret) != ret) {
// very probably this will never be printed
uwsgi_error("write()");
}
}

// reopen logfile;
close(uwsgi.original_log_fd);
uwsgi.original_log_fd = open(uwsgi.logfile, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP);
if (uwsgi.original_log_fd < 0) {
uwsgi_error_open(uwsgi.logfile);
grace_them_all(0);
return;
}
ret = snprintf(message, 1024, "[%d] %s reopened.\n", (int) uwsgi_now(), uwsgi.logfile);
if (ret > 0 && ret < 1024) {
if (write(uwsgi.original_log_fd, message, ret) != ret) {
// very probably this will never be printed
uwsgi_error("write()");
}
}
uwsgi.shared->logsize = lseek(uwsgi.original_log_fd, 0, SEEK_CUR);
if (ret > 0 && ret < 1024) {
if (write(uwsgi.original_log_fd, message, ret) != ret) {
// very probably this will never be printed
uwsgi_error("write()");
}
}

// reopen logfile;
close(uwsgi.original_log_fd);
uwsgi.original_log_fd = open(uwsgi.logfile, O_RDWR | O_CREAT | O_APPEND, uwsgi_get_logfile_chmod_value());
if (uwsgi.original_log_fd < 0) {
uwsgi_error_open(uwsgi.logfile);
grace_them_all(0);
return;
}

ret = snprintf(message, 1024, "[%d] %s reopened.\n", (int) uwsgi_now(), uwsgi.logfile);
if (ret > 0 && ret < 1024) {
if (write(uwsgi.original_log_fd, message, ret) != ret) {
// very probably this will never be printed
uwsgi_error("write()");
}
}
uwsgi.shared->logsize = lseek(uwsgi.original_log_fd, 0, SEEK_CUR);
}


Expand Down
1 change: 1 addition & 0 deletions core/uwsgi.c
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"touch-mules-reload", required_argument, 0, "reload mules if the specified file is modified/touched", uwsgi_opt_add_string_list, &uwsgi.touch_mules_reload, UWSGI_OPT_MASTER},
{"touch-spoolers-reload", required_argument, 0, "reload spoolers if the specified file is modified/touched", uwsgi_opt_add_string_list, &uwsgi.touch_spoolers_reload, UWSGI_OPT_MASTER},
{"touch-chain-reload", required_argument, 0, "trigger chain reload if the specified file is modified/touched", uwsgi_opt_add_string_list, &uwsgi.touch_chain_reload, UWSGI_OPT_MASTER},
{"cron-logrotate", required_argument, 0, "add a cron task to trigger log rotation", uwsgi_opt_add_cron_logrotate, NULL, UWSGI_OPT_MASTER | UWSGI_OPT_LOG_MASTER},
{"touch-logrotate", required_argument, 0, "trigger logrotation if the specified file is modified/touched", uwsgi_opt_add_string_list, &uwsgi.touch_logrotate, UWSGI_OPT_MASTER | UWSGI_OPT_LOG_MASTER},
{"touch-logreopen", required_argument, 0, "trigger log reopen if the specified file is modified/touched", uwsgi_opt_add_string_list, &uwsgi.touch_logreopen, UWSGI_OPT_MASTER | UWSGI_OPT_LOG_MASTER},
{"touch-exec", required_argument, 0, "run command when the specified file is modified/touched (syntax: file command)", uwsgi_opt_add_string_list, &uwsgi.touch_exec, UWSGI_OPT_MASTER},
Expand Down
31 changes: 23 additions & 8 deletions plugins/logfile/logfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ struct logfile_data {
uint64_t maxsize;
};

static void uwsgi_cron_trigger_rotate_func(struct uwsgi_cron *uc, time_t now){
struct uwsgi_logger *ul = uc->data;
struct logfile_data *data = ul->data;
off_t logsize = lseek(ul->fd, 0, SEEK_CUR);

uwsgi_log_do_rotate(data->logfile, data->backupname, logsize, ul->fd);
}

static ssize_t uwsgi_file_logger(struct uwsgi_logger *ul, char *message, size_t len) {

if (!ul->configured) {
Expand All @@ -15,10 +23,11 @@ static ssize_t uwsgi_file_logger(struct uwsgi_logger *ul, char *message, size_t
char *backupname = NULL;
char *maxsize = NULL;
char *logfile = NULL;
char *cron = NULL;

if (strchr(ul->arg, '=')) {
if (uwsgi_kvlist_parse(ul->arg, strlen(ul->arg), ',', '=',
"logfile", &logfile, "backupname", &backupname, "maxsize", &maxsize, NULL)) {
"logfile", &logfile, "backupname", &backupname, "maxsize", &maxsize, "cron", &cron, NULL)) {
uwsgi_log("[uwsgi-logfile] invalid keyval syntax\n");
exit(1);
}
Expand All @@ -29,22 +38,28 @@ static ssize_t uwsgi_file_logger(struct uwsgi_logger *ul, char *message, size_t
uwsgi_log("[uwsgi-logfile] missing logfile key\n");
return 0;
}


struct logfile_data *data = uwsgi_malloc(sizeof(struct logfile_data));
data->logfile = logfile;
data->backupname = backupname;
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 {
data->maxsize = (uint64_t) 0;
}
if (cron) {
struct uwsgi_cron *uc = uwsgi_cron_add(cron);
uc->data = ul;
uc->func = uwsgi_cron_trigger_rotate_func;
}
ul->data = data;
} else {
logfile = ul->arg;
}

ul->fd = open(logfile, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP);
ul->fd = open(logfile, O_RDWR | O_CREAT | O_APPEND, uwsgi_get_logfile_chmod_value());
if (ul->fd >= 0) {
ul->configured = 1;
}
Expand Down
5 changes: 5 additions & 0 deletions uwsgi.h
Original file line number Diff line number Diff line change
Expand Up @@ -3005,6 +3005,9 @@ struct uwsgi_cron {
char *command;
void (*func)(struct uwsgi_cron *, time_t);

// data to be used with func
void *data;

time_t started_at;

// next harakiri timestamp
Expand Down Expand Up @@ -4899,8 +4902,10 @@ void uwsgi_master_fifo_prepare();
int uwsgi_master_fifo();
int uwsgi_master_fifo_manage(int);

mode_t uwsgi_get_logfile_chmod_value();
void uwsgi_log_do_rotate(char *, char *, off_t, int);
void uwsgi_log_rotate();
void uwsgi_opt_add_cron_logrotate(char *opt, char *value, void *foobar);
void uwsgi_log_reopen();
void uwsgi_reload_workers();
void uwsgi_reload_mules();
Expand Down