From d3053523abb6d6c7ad25d28bde9e0e3633dfc979 Mon Sep 17 00:00:00 2001 From: "roberto@oneiric64" Date: Wed, 14 Dec 2011 10:50:25 +0100 Subject: [PATCH] completed logging pluginization --- buildconf/default.ini | 2 +- master.c | 3 -- plugins/graylog2/graylog2_plugin.c | 31 ++++++----- plugins/logsocket/logsocket_plugin.c | 78 ++++++++++++++++++++++++++++ plugins/logsocket/uwsgiplugin.py | 6 +++ plugins/rsyslog/rsyslog_plugin.c | 22 ++++---- socket.c | 13 +++-- utils.c | 28 ++-------- uwsgi.c | 3 +- uwsgi.h | 16 +++--- 10 files changed, 136 insertions(+), 66 deletions(-) create mode 100644 plugins/logsocket/logsocket_plugin.c create mode 100644 plugins/logsocket/uwsgiplugin.py diff --git a/buildconf/default.ini b/buildconf/default.ini index 80f63411..9f883564 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, rsyslog +embedded_plugins = python, ping, cache, nagios, rrdtool, carbon, rpc, fastrouter, http, ugreen, signal, syslog, rsyslog, logsocket as_shared_library = false locking = auto diff --git a/master.c b/master.c index e1bc3693..48bfd7e7 100644 --- a/master.c +++ b/master.c @@ -77,9 +77,6 @@ void master_log(void) { if (uwsgi.choosen_logger) { uwsgi.choosen_logger->func(uwsgi.choosen_logger, log_buf, rlen); } - else if (uwsgi.log_socket) { - sendto(uwsgi.log_socket_fd, log_buf, rlen, 0, &uwsgi.log_socket_addr->sa, uwsgi.log_socket_size); - } else { rlen = write(uwsgi.original_log_fd, log_buf, rlen); } diff --git a/plugins/graylog2/graylog2_plugin.c b/plugins/graylog2/graylog2_plugin.c index 379f0efb..b22a72bd 100644 --- a/plugins/graylog2/graylog2_plugin.c +++ b/plugins/graylog2/graylog2_plugin.c @@ -19,32 +19,37 @@ ssize_t uwsgi_graylog2_logger(struct uwsgi_logger *ul, char *message, size_t len if (!ul->configured) { - if (!uwsgi.choosen_logger_arg) return -1; + if (!uwsgi.choosen_logger_arg) { + uwsgi_log_safe("invalid graylog2 syntax\n"); + exit(1); + } ul->fd = socket(AF_INET, SOCK_DGRAM, 0); - if (ul->fd < 0) return -1 ; + if (ul->fd < 0) { + uwsgi_error_safe("socket()"); + exit(1); + } uwsgi_socket_nb(ul->fd); char *comma = strchr(uwsgi.choosen_logger_arg, ','); - if (!comma) return -1; + if (!comma) { + uwsgi_log_safe("invalid graylog2 syntax\n"); + exit(1); + } g2c.host = comma + 1; *comma = 0; char *colon = strchr(uwsgi.choosen_logger_arg, ':'); - if (!colon) return -1; + if (!colon) { + uwsgi_log_safe("invalid graylog2 syntax\n"); + exit(1); + } - memset(&ul->sin, 0, sizeof(struct sockaddr_in)); - ul->sin.sin_family = AF_INET; - ul->sin.sin_port = htons(atoi(colon + 1)); + ul->addr_len = socket_to_in_addr(uwsgi.choosen_logger_arg, colon, 0, &ul->addr.sa_in); - *colon = 0; - - ul->sin.sin_addr.s_addr = inet_addr(uwsgi.choosen_logger_arg); - - *colon = ':'; *comma = ','; ul->configured = 1; @@ -87,7 +92,7 @@ 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->sin, sizeof(struct sockaddr_in)); + return sendto(ul->fd, g2c.buffer, destLen, 0, (const struct sockaddr *) &ul->addr, ul->addr_len); } } diff --git a/plugins/logsocket/logsocket_plugin.c b/plugins/logsocket/logsocket_plugin.c new file mode 100644 index 00000000..0a82d2a5 --- /dev/null +++ b/plugins/logsocket/logsocket_plugin.c @@ -0,0 +1,78 @@ +#include "../../uwsgi.h" + +extern struct uwsgi_server uwsgi; + +ssize_t uwsgi_socket_logger(struct uwsgi_logger *ul, char *message, size_t len) { + + int family = AF_UNIX; + + if (!ul->configured) { + + char *comma = strchr(uwsgi.choosen_logger_arg, ','); + if (comma) { + ul->data = comma+1; + *comma = 0; + } + + char *colon = strchr(uwsgi.choosen_logger_arg, ':'); + if (colon) { + family = AF_INET; + ul->addr_len = socket_to_in_addr(uwsgi.choosen_logger_arg, colon, 0, &ul->addr.sa_in); + } + else { + ul->addr_len = socket_to_un_addr(uwsgi.choosen_logger_arg, &ul->addr.sa_un); + } + + ul->fd = socket(family, SOCK_DGRAM, 0); + if (ul->fd < 0) { + uwsgi_error_safe("socket()"); + exit(1); + } + + memset(&ul->msg, 0, sizeof(struct msghdr)); + + ul->msg.msg_name = &ul->addr; + ul->msg.msg_namelen = ul->addr_len; + if (ul->data) { + ul->msg.msg_iov = uwsgi_malloc(sizeof(struct iovec) * 2); + ul->msg.msg_iov[0].iov_base = ul->data; + ul->msg.msg_iov[0].iov_len = strlen(ul->data); + ul->msg.msg_iovlen = 2; + ul->count = 1; + } + else { + ul->msg.msg_iov = uwsgi_malloc(sizeof(struct iovec)); + ul->msg.msg_iovlen = 1; + } + + if (comma) { + *comma = ',' ; + } + + ul->configured = 1; + } + + + ul->msg.msg_iov[ul->count].iov_base = message; + ul->msg.msg_iov[ul->count].iov_len = len; + + return sendmsg(ul->fd, &ul->msg, 0); + +} + +void uwsgi_logsocket_register() { + uwsgi_register_logger("socket", uwsgi_socket_logger); +} + +int uwsgi_logsocket_init() { + return 0; +} + +struct uwsgi_plugin logsocket_plugin = { + + .name = "logsocket", + .on_load = uwsgi_logsocket_register, + .init = uwsgi_logsocket_init + +}; + diff --git a/plugins/logsocket/uwsgiplugin.py b/plugins/logsocket/uwsgiplugin.py new file mode 100644 index 00000000..d2e3337d --- /dev/null +++ b/plugins/logsocket/uwsgiplugin.py @@ -0,0 +1,6 @@ +NAME='logsocket' + +CFLAGS = [] +LDFLAGS = [] +LIBS = [] +GCC_LIST = ['logsocket_plugin'] diff --git a/plugins/rsyslog/rsyslog_plugin.c b/plugins/rsyslog/rsyslog_plugin.c index 7ced1851..86bfd0b4 100644 --- a/plugins/rsyslog/rsyslog_plugin.c +++ b/plugins/rsyslog/rsyslog_plugin.c @@ -13,10 +13,16 @@ ssize_t uwsgi_rsyslog_logger(struct uwsgi_logger *ul, char *message, size_t len) if (!ul->configured) { - if (!uwsgi.choosen_logger_arg) return -1; + if (!uwsgi.choosen_logger_arg) { + uwsgi_log_safe("invalid rsyslog syntax\n"); + exit(1); + } ul->fd = socket(AF_INET, SOCK_DGRAM, 0); - if (ul->fd < 0) return -1 ; + if (ul->fd < 0) { + uwsgi_error_safe("socket()"); + exit(1); + } uwsgi_socket_nb(ul->fd); @@ -26,7 +32,7 @@ ssize_t uwsgi_rsyslog_logger(struct uwsgi_logger *ul, char *message, size_t len) *comma = 0; } else { - ul->data = "uwsgi"; + ul->data = uwsgi_concat2(uwsgi.hostname," uwsgi"); } @@ -36,11 +42,7 @@ ssize_t uwsgi_rsyslog_logger(struct uwsgi_logger *ul, char *message, size_t len) *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); + ul->addr_len = socket_to_in_addr(uwsgi.choosen_logger_arg, NULL, portn, &ul->addr.sa_in); if (port) *port = ':'; if (comma) *comma = ','; @@ -54,9 +56,9 @@ ssize_t uwsgi_rsyslog_logger(struct uwsgi_logger *ul, char *message, size_t len) // 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); + rlen = snprintf(buf, MAX_SYSLOG_PKT, "<29>%.*s %s: %.*s", 15, ctime(¤t_time)+4, (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 sendto(ul->fd, buf, rlen, 0, (const struct sockaddr *) &ul->addr, ul->addr_len); } return -1; diff --git a/socket.c b/socket.c index 05c79645..7a722094 100644 --- a/socket.c +++ b/socket.c @@ -460,15 +460,18 @@ socklen_t socket_to_un_addr(char *socket_name, struct sockaddr_un *sun_addr) { return sizeof(sun_addr->sun_family)+len; } -socklen_t socket_to_in_addr(char *socket_name, char *port, struct sockaddr_in *sin_addr) { +socklen_t socket_to_in_addr(char *socket_name, char *port, int portn, struct sockaddr_in *sin_addr) { memset(sin_addr, 0, sizeof(struct sockaddr_in)); sin_addr->sin_family = AF_INET; if (port) { - port[0] = 0; + *port = 0; sin_addr->sin_port = htons(atoi(port + 1)); } + else { + sin_addr->sin_port = htons(portn); + } if (socket_name[0] == 0) { sin_addr->sin_addr.s_addr = INADDR_ANY; @@ -483,6 +486,10 @@ socklen_t socket_to_in_addr(char *socket_name, char *port, struct sockaddr_in *s } } + if (port) { + *port = ':'; + } + return sizeof(struct sockaddr_in); } @@ -493,7 +500,7 @@ int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) { struct sockaddr_in uws_addr; int reuse = 1; - socket_to_in_addr(socket_name, tcp_port, &uws_addr); + socket_to_in_addr(socket_name, tcp_port, 0, &uws_addr); serverfd = socket(AF_INET, SOCK_STREAM, 0); if (serverfd < 0) { diff --git a/utils.c b/utils.c index 1d2e9232..f3aaaff0 100644 --- a/utils.c +++ b/utils.c @@ -279,7 +279,10 @@ ssize_t uwsgi_zeromq_logger(struct uwsgi_logger *ul, char *message, size_t len) if (!ul->configured) { - if (!uwsgi.choosen_logger_arg) return -1; + if (!uwsgi.choosen_logger_arg) { + uwsgi_log_safe("invalid zeromq syntax\n"); + exit(1); + } void *ctx = zmq_init(1); if (ctx == NULL) { @@ -312,29 +315,6 @@ ssize_t uwsgi_zeromq_logger(struct uwsgi_logger *ul, char *message, size_t len) } #endif -void log_socket(char *socket_name) { - - int family = AF_UNIX; - - uwsgi.log_socket_addr = uwsgi_malloc(sizeof(union uwsgi_sockaddr)); - - char *colon = strchr(socket_name, ':'); - if (colon) { - family = AF_INET; - uwsgi.log_socket_size = socket_to_in_addr(socket_name, colon, &uwsgi.log_socket_addr->sa_in); - } - else { - uwsgi.log_socket_size = socket_to_un_addr(socket_name, &uwsgi.log_socket_addr->sa_un); - } - - uwsgi.log_socket_fd = socket(family, SOCK_DGRAM, 0); - if (uwsgi.log_socket_fd < 0) { - uwsgi_error("socket()"); - uwsgi_nuclear_blast(); - } - -} - void create_logpipe(void) { #if defined(SOCK_SEQPACKET) && defined(__linux__) diff --git a/uwsgi.c b/uwsgi.c index 2f84f0d6..28c15bfc 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -3200,10 +3200,9 @@ static int manage_base_opt(int i, char *optarg) { uwsgi.log_master = 1; return 1; case LONG_ARGS_LOG_SOCKET: - uwsgi.log_socket = 1; uwsgi.log_master = 1; uwsgi.master_process = 1; - log_socket(optarg); + uwsgi.requested_logger = uwsgi_concat2("socket:", optarg); return 1; case LONG_ARGS_LOGGER: uwsgi.log_master = 1; diff --git a/uwsgi.h b/uwsgi.h index 0c0be13a..0a74047b 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -11,6 +11,7 @@ extern "C" { #define UMAX64_STR "18446744073709551616" #define uwsgi_error(x) uwsgi_log("%s: %s [%s line %d]\n", x, strerror(errno), __FILE__, __LINE__); +#define uwsgi_log_safe(x) if (uwsgi.original_log_fd != 2) dup2(uwsgi.original_log_fd, 2) ; uwsgi_log(x); #define uwsgi_error_safe(x) if (uwsgi.original_log_fd != 2) dup2(uwsgi.original_log_fd, 2) ; uwsgi_log("%s: %s [%s line %d]\n", x, strerror(errno), __FILE__, __LINE__); #define uwsgi_log_initial if (!uwsgi.no_initial_output) uwsgi_log #define uwsgi_fatal_error(x) uwsgi_error(x); exit(1); @@ -349,7 +350,10 @@ struct uwsgi_logger { int configured; int fd; void *data; - struct sockaddr_in sin; + union uwsgi_sockaddr addr; + socklen_t addr_len; + int count; + struct msghdr msg; struct uwsgi_logger *next; }; @@ -1201,12 +1205,6 @@ struct uwsgi_server { int original_log_fd; - int log_socket; - int log_socket_fd; - union uwsgi_sockaddr *log_socket_addr; - socklen_t log_socket_size; - - // static file serving int file_serve_mode; int build_mime_dict; @@ -2404,9 +2402,7 @@ void uwsgi_ignition(void); void master_check_cluster_nodes(void); int uwsgi_respawn_worker(int); -void log_socket(char *); - -socklen_t socket_to_in_addr(char *, char *, struct sockaddr_in *); +socklen_t socket_to_in_addr(char *, char *, int, struct sockaddr_in *); socklen_t socket_to_un_addr(char *, struct sockaddr_un *); int uwsgi_get_shared_socket_fd_by_num(int);