From e2cea376e85aa7d71a856dc7a5e992f9b0bfaccb Mon Sep 17 00:00:00 2001 From: "roberto@oneiric64" Date: Tue, 13 Dec 2011 20:33:17 +0100 Subject: [PATCH] added rsyslog plugin --- buildconf/default.ini | 2 +- plugins/graylog2/graylog2_plugin.c | 35 +++++++++---- plugins/rsyslog/rsyslog_plugin.c | 80 ++++++++++++++++++++++++++++++ plugins/rsyslog/uwsgiplugin.py | 6 +++ uwsgi.c | 27 +++++----- uwsgi.h | 1 + 6 files changed, 126 insertions(+), 25 deletions(-) create mode 100644 plugins/rsyslog/rsyslog_plugin.c create mode 100644 plugins/rsyslog/uwsgiplugin.py diff --git a/buildconf/default.ini b/buildconf/default.ini index a88db04d..80f63411 100644 --- a/buildconf/default.ini +++ b/buildconf/default.ini @@ -27,7 +27,7 @@ plugins = bin_name = uwsgi append_version = plugin_dir = . -embedded_plugins = python, ping, cache, nagios, rrdtool, carbon, rpc, fastrouter, http, ugreen, signal, syslog +embedded_plugins = python, ping, cache, nagios, rrdtool, carbon, rpc, fastrouter, http, ugreen, signal, syslog, rsyslog as_shared_library = false locking = auto diff --git a/plugins/graylog2/graylog2_plugin.c b/plugins/graylog2/graylog2_plugin.c index 7f59edde..bbe11303 100644 --- a/plugins/graylog2/graylog2_plugin.c +++ b/plugins/graylog2/graylog2_plugin.c @@ -6,7 +6,6 @@ extern struct uwsgi_server uwsgi; #define MAX_GELF 8192 struct graylog2_config { - struct sockaddr_in sin; char *host; char json_buf[MAX_GELF]; char escaped_buf[MAX_GELF]; @@ -25,6 +24,8 @@ ssize_t uwsgi_graylog2_logger(struct uwsgi_logger *ul, char *message, size_t len ul->fd = socket(AF_INET, SOCK_DGRAM, 0); if (ul->fd < 0) return -1 ; + uwsgi_socket_nb(ul->fd); + char *comma = strchr(uwsgi.choosen_logger_arg, ','); if (!comma) return -1; @@ -35,13 +36,13 @@ ssize_t uwsgi_graylog2_logger(struct uwsgi_logger *ul, char *message, size_t len char *colon = strchr(uwsgi.choosen_logger_arg, ':'); if (!colon) return -1; - memset(&g2c.sin, 0, sizeof(struct sockaddr_in)); - g2c.sin.sin_family = AF_INET; - g2c.sin.sin_port = htons(atoi(colon + 1)); + memset(&ul->sin, 0, sizeof(struct sockaddr_in)); + ul->sin.sin_family = AF_INET; + ul->sin.sin_port = htons(atoi(colon + 1)); *colon = 0; - g2c.sin.sin_addr.s_addr = inet_addr(uwsgi.choosen_logger_arg); + ul->sin.sin_addr.s_addr = inet_addr(uwsgi.choosen_logger_arg); *colon = ':'; *comma = ','; @@ -51,7 +52,9 @@ ssize_t uwsgi_graylog2_logger(struct uwsgi_logger *ul, char *message, size_t len g2c.escaped_len = 0; + int truncated = 0; char *ptr = g2c.escaped_buf; + uLongf destLen = MAX_GELF; for(i=0;i 128) { + truncated = 2; + } + } } + if (truncated) truncated = 128 - (truncated-1); + else (truncated = g2c.escaped_len); + int rlen = snprintf(g2c.json_buf, MAX_GELF, "{ \"version\": \"1.0\", \"host\": \"%s\", \"short_message\": \"%.*s\", \"full_message\": \"%.*s\", \"timestamp\": %d, \"facility\": \"uWSGI-%s\" }", - g2c.host, (int)g2c.escaped_len, g2c.escaped_buf, (int)g2c.escaped_len, g2c.escaped_buf, (int) time(NULL), UWSGI_VERSION); + g2c.host, truncated, g2c.escaped_buf, (int)g2c.escaped_len, g2c.escaped_buf, (int) time(NULL), UWSGI_VERSION); - uLongf destLen = MAX_GELF; if (rlen > 0) { - compress((Bytef *) g2c.buffer, &destLen, (Bytef *) g2c.json_buf, (uLong) rlen); - return sendto(ul->fd, g2c.buffer, destLen, 0, (const struct sockaddr *) &g2c.sin, sizeof(struct sockaddr_in)); + 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->sin, sizeof(struct sockaddr_in)); + } + } } return -1; diff --git a/plugins/rsyslog/rsyslog_plugin.c b/plugins/rsyslog/rsyslog_plugin.c new file mode 100644 index 00000000..7ced1851 --- /dev/null +++ b/plugins/rsyslog/rsyslog_plugin.c @@ -0,0 +1,80 @@ +#include "../../uwsgi.h" + +extern struct uwsgi_server uwsgi; + +#define MAX_SYSLOG_PKT 1024 + +ssize_t uwsgi_rsyslog_logger(struct uwsgi_logger *ul, char *message, size_t len) { + + char buf[MAX_SYSLOG_PKT]; + time_t current_time; + int portn = 514; + int rlen; + + if (!ul->configured) { + + if (!uwsgi.choosen_logger_arg) return -1; + + ul->fd = socket(AF_INET, SOCK_DGRAM, 0); + if (ul->fd < 0) return -1 ; + + uwsgi_socket_nb(ul->fd); + + char *comma = strchr(uwsgi.choosen_logger_arg, ','); + if (comma) { + ul->data = comma+1; + *comma = 0; + } + else { + ul->data = "uwsgi"; + } + + + char *port = strchr(uwsgi.choosen_logger_arg, ':'); + if (port) { + portn = atoi(port+1); + *port = 0; + } + + memset(&ul->sin, 0, sizeof(struct sockaddr_in)); + ul->sin.sin_family = AF_INET; + ul->sin.sin_port = htons(portn); + + ul->sin.sin_addr.s_addr = inet_addr(uwsgi.choosen_logger_arg); + + if (port) *port = ':'; + if (comma) *comma = ','; + + ul->configured = 1; + } + + + current_time = time(NULL); + + // drop newline + if (message[len-1] == '\n') len--; + + rlen = snprintf(buf, MAX_SYSLOG_PKT, "<29>%.*s %s %s: %.*s", 19, ctime(¤t_time), uwsgi.hostname, (char *) ul->data, (int) len, message); + if (rlen > 0) { + return sendto(ul->fd, buf, rlen, 0, (const struct sockaddr *) &ul->sin, sizeof(struct sockaddr_in)); + } + return -1; + +} + +void uwsgi_rsyslog_register() { + uwsgi_register_logger("rsyslog", uwsgi_rsyslog_logger); +} + +int uwsgi_rsyslog_init() { + return 0; +} + +struct uwsgi_plugin rsyslog_plugin = { + + .name = "rsyslog", + .on_load = uwsgi_rsyslog_register, + .init = uwsgi_rsyslog_init + +}; + diff --git a/plugins/rsyslog/uwsgiplugin.py b/plugins/rsyslog/uwsgiplugin.py new file mode 100644 index 00000000..3af77cb5 --- /dev/null +++ b/plugins/rsyslog/uwsgiplugin.py @@ -0,0 +1,6 @@ +NAME='rsyslog' + +CFLAGS = [] +LDFLAGS = [] +LIBS = [] +GCC_LIST = ['rsyslog_plugin'] diff --git a/uwsgi.c b/uwsgi.c index 2bba8dbf..5f2dcf99 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -1214,6 +1214,11 @@ int main(int argc, char *argv[], char *envp[]) { // ok we can now safely play with argv and environ fixup_argv_and_environ(argc, argv, environ); + if (gethostname(uwsgi.hostname, 255)) { + uwsgi_error("gethostname()"); + } + uwsgi.hostname_len = strlen(uwsgi.hostname); + #ifdef UWSGI_ZEROMQ uwsgi_register_logger("zeromq", uwsgi_zeromq_logger); uwsgi_register_logger("zmq", uwsgi_zeromq_logger); @@ -1249,11 +1254,6 @@ int main(int argc, char *argv[], char *envp[]) { build_options(); - if (gethostname(uwsgi.hostname, 255)) { - uwsgi_error("gethostname()"); - } - uwsgi.hostname_len = strlen(uwsgi.hostname); - uwsgi.magic_table['v'] = uwsgi.cwd; uwsgi.magic_table['h'] = uwsgi.hostname; @@ -2445,37 +2445,34 @@ skipzero: uwsgi.shared->hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping; //100 */ - uwsgi_log("*** Operational MODE: "); if (!uwsgi.numproc) { - uwsgi_rawlog("no-workers"); + uwsgi_log("*** Operational MODE: no-workers ***\n"); } else if (uwsgi.threads > 1) { if (uwsgi.numproc > 1) { - uwsgi_rawlog("preforking+threaded"); + uwsgi_log("*** Operational MODE: preforking+threaded ***\n"); } else { - uwsgi_rawlog("threaded"); + uwsgi_log("*** Operational MODE: threaded ***\n"); } } #ifdef UWSGI_ASYNC else if (uwsgi.async > 1) { if (uwsgi.numproc > 1) { - uwsgi_rawlog("preforking+async"); + uwsgi_log("*** Operational MODE: preforking+async ***\n"); } else { - uwsgi_rawlog("async"); + uwsgi_log("*** Operational MODE: async ***\n"); } } #endif else if (uwsgi.numproc > 1) { - uwsgi_rawlog("preforking"); + uwsgi_log("*** Operational MODE: preforking ***\n"); } else { - uwsgi_rawlog("single process"); + uwsgi_log("*** Operational MODE: single process ***\n"); } - uwsgi_rawlog(" ***\n"); - // even the master has cores.. uwsgi.core = uwsgi_malloc(sizeof(struct uwsgi_core *) * uwsgi.cores); for (j = 0; j < uwsgi.cores; j++) { diff --git a/uwsgi.h b/uwsgi.h index 7d9d35dd..9c940ec3 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -349,6 +349,7 @@ struct uwsgi_logger { int configured; int fd; void *data; + struct sockaddr_in sin; struct uwsgi_logger *next; };