From 15b12983e15df05bd4b22b7928fedc924c16f2a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?= Date: Fri, 25 Jan 2013 16:54:55 +0100 Subject: [PATCH] * add buf to uwsgi_logger struct and use it when logger needs buffering (rsyslog + graylog2) * allow to split big syslog messages into chunks * allow to set maximum syslog packet size (some syslog deamons support that) --- core/logging.c | 1 + plugins/graylog2/graylog2_plugin.c | 7 +++--- plugins/rsyslog/rsyslog_plugin.c | 40 +++++++++++++++++++++++++----- uwsgi.h | 1 + 4 files changed, 40 insertions(+), 9 deletions(-) diff --git a/core/logging.c b/core/logging.c index c83ce639..10bb8c71 100644 --- a/core/logging.c +++ b/core/logging.c @@ -761,6 +761,7 @@ void uwsgi_register_logger(char *name, ssize_t(*func) (struct uwsgi_logger *, ch ul->configured = 0; ul->fd = -1; ul->data = NULL; + ul->buf = NULL; #ifdef UWSGI_DEBUG diff --git a/plugins/graylog2/graylog2_plugin.c b/plugins/graylog2/graylog2_plugin.c index 8c67201c..fcd369c5 100644 --- a/plugins/graylog2/graylog2_plugin.c +++ b/plugins/graylog2/graylog2_plugin.c @@ -10,7 +10,6 @@ struct graylog2_config { char json_buf[MAX_GELF]; char escaped_buf[MAX_GELF]; size_t escaped_len; - char buffer[MAX_GELF]; } g2c; ssize_t uwsgi_graylog2_logger(struct uwsgi_logger *ul, char *message, size_t len) { @@ -52,6 +51,8 @@ ssize_t uwsgi_graylog2_logger(struct uwsgi_logger *ul, char *message, size_t len *comma = ','; + ul->buf = uwsgi_malloc(MAX_GELF); + ul->configured = 1; } @@ -91,8 +92,8 @@ ssize_t uwsgi_graylog2_logger(struct uwsgi_logger *ul, char *message, size_t len if (rlen > 0) { if (compressBound((uLong) rlen) <= MAX_GELF) { - if (compress((Bytef *) g2c.buffer, &destLen, (Bytef *) g2c.json_buf, (uLong) rlen) == Z_OK) { - return sendto(ul->fd, g2c.buffer, destLen, 0, (const struct sockaddr *) &ul->addr, ul->addr_len); + if (compress((Bytef *) ul->buf, &destLen, (Bytef *) g2c.json_buf, (uLong) rlen) == Z_OK) { + return sendto(ul->fd, ul->buf, destLen, 0, (const struct sockaddr *) &ul->addr, ul->addr_len); } } diff --git a/plugins/rsyslog/rsyslog_plugin.c b/plugins/rsyslog/rsyslog_plugin.c index 643135d2..8601af31 100644 --- a/plugins/rsyslog/rsyslog_plugin.c +++ b/plugins/rsyslog/rsyslog_plugin.c @@ -2,11 +2,23 @@ extern struct uwsgi_server uwsgi; -#define MAX_SYSLOG_PKT 1024 + +struct uwsgi_rsyslog { + int packet_size; + int msg_size; + int split_msg; +} u_rsyslog; + + +struct uwsgi_option rsyslog_options[] = { + {"rsyslog-packet-size", required_argument, 0, "set maximum packet size for syslog messages (default 1024) WARNING! using packets > 1024 breaks RFC 3164 (#4.1)", uwsgi_opt_set_int, &u_rsyslog.packet_size, 0}, + {"rsyslog-split-messages", no_argument, 0, "split big messages into multiple chunks if they are bigger than allowed packet size (default is false)", uwsgi_opt_true, &u_rsyslog.split_msg, 0}, + {0, 0, 0, 0, 0, 0, 0}, +}; + ssize_t uwsgi_rsyslog_logger(struct uwsgi_logger *ul, char *message, size_t len) { - char buf[MAX_SYSLOG_PKT]; char ctime_storage[26]; time_t current_time; int portn = 514; @@ -48,6 +60,11 @@ ssize_t uwsgi_rsyslog_logger(struct uwsgi_logger *ul, char *message, size_t len) if (port) *port = ':'; if (comma) *comma = ','; + if (!u_rsyslog.packet_size) u_rsyslog.packet_size = 1024; + if (!u_rsyslog.msg_size) u_rsyslog.msg_size = u_rsyslog.packet_size - 30; + + ul->buf = uwsgi_malloc(uwsgi.log_master_bufsize); + ul->configured = 1; } @@ -61,11 +78,21 @@ ssize_t uwsgi_rsyslog_logger(struct uwsgi_logger *ul, char *message, size_t len) #else ctime_r(¤t_time, ctime_storage); #endif - rlen = snprintf(buf, MAX_SYSLOG_PKT, "<29>%.*s %s: %.*s", 15, ctime_storage+4, (char *) ul->data, (int) len, message); - if (rlen > 0) { - return sendto(ul->fd, buf, rlen, 0, (const struct sockaddr *) &ul->addr, ul->addr_len); + + int pos, msg_len, ret; + for (pos=0 ; pos < (int) len ;) { + if (pos > 0 && !u_rsyslog.split_msg) return pos; + msg_len = ( ((int)len)-pos > u_rsyslog.msg_size ? u_rsyslog.msg_size : ((int)len)-pos); + rlen = snprintf(ul->buf, u_rsyslog.packet_size, "<29>%.*s %s: %.*s", 15, ctime_storage+4, (char *) ul->data, msg_len, &message[pos]); + if (rlen > 0 && rlen <= u_rsyslog.packet_size) { + ret = sendto(ul->fd, ul->buf, rlen, 0, (const struct sockaddr *) &ul->addr, ul->addr_len); + if (ret <= 0) return ret; + pos += msg_len; + } else { + return -1; + } } - return -1; + return pos; } @@ -77,6 +104,7 @@ struct uwsgi_plugin rsyslog_plugin = { .name = "rsyslog", .on_load = uwsgi_rsyslog_register, + .options = rsyslog_options, }; diff --git a/uwsgi.h b/uwsgi.h index a9c55c1b..5b801adc 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -511,6 +511,7 @@ struct uwsgi_logger { socklen_t addr_len; int count; struct msghdr msg; + char *buf; // used by choosen logger char *arg; struct uwsgi_logger *next;