1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
#include <uwsgi.h>
extern struct uwsgi_server uwsgi;
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) {
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;
}
}
}
if (ul->fd >= 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) {
if (!ul->configured) {
ul->fd = -1;
if (ul->arg) ul->fd = atoi(ul->arg);
ul->configured = 1;
}
if (ul->fd >= 0) {
return write(ul->fd, message, len);
}
return 0;
}
static ssize_t uwsgi_stdio_logger(struct uwsgi_logger *ul, char *message, size_t len) {
if (uwsgi.original_log_fd >= 0) {
return write(uwsgi.original_log_fd, message, len);
}
return 0;
}
void uwsgi_file_logger_register() {
uwsgi_register_logger("file", uwsgi_file_logger);
uwsgi_register_logger("fd", uwsgi_fd_logger);
uwsgi_register_logger("stdio", uwsgi_stdio_logger);
}
struct uwsgi_plugin logfile_plugin = {
.name = "logfile",
.on_load = uwsgi_file_logger_register,
};
|