static void stats_pusher_dogstatsd(struct uwsgi_stats_pusher_instance *uspi, time_t now, char *json, size_t json_len) { if (!uspi->configured) { struct dogstatsd_node *sn = uwsgi_calloc(sizeof(struct dogstatsd_node)); char *comma = strchr(uspi->arg, ','); if (comma) { sn->prefix = comma+1; sn->prefix_len = strlen(sn->prefix); *comma = 0; } else { sn->prefix = "uwsgi"; sn->prefix_len = 5; } char *colon = strchr(uspi->arg, ':'); if (!colon) { uwsgi_log("invalid dd address %s\n", uspi->arg); if (comma) *comma = ','; free(sn); return; } sn->addr_len = socket_to_in_addr(uspi->arg, colon, 0, &sn->addr.sa_in); sn->fd = socket(AF_INET, SOCK_DGRAM, 0); if (sn->fd < 0) { uwsgi_error("stats_pusher_dogstatsd()/socket()"); if (comma) *comma = ','; free(sn); return; } uwsgi_socket_nb(sn->fd); if (comma) *comma = ','; uspi->data = sn; uspi->configured = 1; } // we use the same buffer for all of the packets struct uwsgi_buffer *ub = uwsgi_buffer_new(uwsgi.page_size); struct uwsgi_metric *um = uwsgi.metrics; while(um) { uwsgi_rlock(uwsgi.metrics_lock); // ignore return value if (um->type == UWSGI_METRIC_GAUGE) { dogstatsd_send_metric(ub, uspi, um->name, um->name_len, *um->value, "|g"); } else { dogstatsd_send_metric(ub, uspi, um->name, um->name_len, *um->value, "|c"); } uwsgi_rwunlock(uwsgi.metrics_lock); if (um->reset_after_push){ uwsgi_wlock(uwsgi.metrics_lock); *um->value = um->initial_value; uwsgi_rwunlock(uwsgi.metrics_lock); } um = um->next; } uwsgi_buffer_destroy(ub); }
ssize_t uwsgi_graylog2_logger(struct uwsgi_logger *ul, char *message, size_t len) { size_t i; if (!ul->configured) { 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) { uwsgi_error_safe("socket()"); exit(1); } uwsgi_socket_nb(ul->fd); char *comma = strchr(uwsgi.choosen_logger_arg, ','); 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) { uwsgi_log_safe("invalid graylog2 syntax\n"); exit(1); } ul->addr_len = socket_to_in_addr(uwsgi.choosen_logger_arg, colon, 0, &ul->addr.sa_in); *comma = ','; ul->configured = 1; } g2c.escaped_len = 0; int truncated = 0; char *ptr = g2c.escaped_buf; uLongf destLen = MAX_GELF; for(i=0;i<len;i++) { if (message[i] == '\\') { *ptr ++= '\\'; g2c.escaped_len++; } else if (message[i] == '"') { *ptr ++= '\\'; g2c.escaped_len++; } *ptr ++= message[i]; g2c.escaped_len++; if (!truncated) { if (g2c.escaped_len == 128) { truncated = 1; } else if (g2c.escaped_len > 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, \"level\": 5, \"facility\": \"uWSGI-%s\" }", g2c.host, truncated, g2c.escaped_buf, (int)g2c.escaped_len, g2c.escaped_buf, (int) time(NULL), UWSGI_VERSION); 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); } } } return -1; }
static ssize_t uwsgi_crypto_logger(struct uwsgi_logger *ul, char *message, size_t len) { struct uwsgi_crypto_logger_conf *uclc = (struct uwsgi_crypto_logger_conf *) ul->data; if (!ul->configured) { uclc = uwsgi_calloc(sizeof(struct uwsgi_crypto_logger_conf)); if (uwsgi_kvlist_parse(ul->arg, strlen(ul->arg), ',', '=', "addr", &uclc->addr, "algo", &uclc->algo, "secret", &uclc->secret, "iv", &uclc->iv, "prefix", &uclc->prefix, NULL)) { uwsgi_log_safe("[uwsgi-logcrypto] unable to parse options\n"); exit(1); } if (!uclc->addr || !uclc->algo || !uclc->secret) { uwsgi_log_safe("[uwsgi-logcrypto] you have to specify at least addr,algo and secret options\n"); exit(1); } if (uclc->prefix) { uclc->prefix_len = strlen(uclc->prefix); } char *colon = strchr(uclc->addr, ':'); if (!colon) { uwsgi_log_safe("[uwsgi-logcrypto] invalid UDP address\n"); exit(1); } ul->addr_len = socket_to_in_addr(uclc->addr, colon, 0, &ul->addr.sa_in); ul->fd = socket(AF_INET, SOCK_DGRAM, 0); if (ul->fd < 0) { uwsgi_error_safe("uwsgi_crypto_logger()/socket()"); exit(1); } uwsgi_crypto_logger_setup_encryption(uclc); ul->data = uclc; ul->configured = 1; } struct uwsgi_buffer *ub = uwsgi_buffer_new(uwsgi.page_size); if (uwsgi_buffer_num64(ub, uwsgi_micros())) goto error; if (uwsgi_buffer_append(ub, " ", 1)) goto error; if (uclc->prefix) { if (uwsgi_buffer_append(ub, uclc->prefix, uclc->prefix_len)) goto error; if (uwsgi_buffer_append(ub, " ", 1)) goto error; } if (uwsgi_buffer_append(ub, message, len)) goto error; // let's encrypt the message unsigned char *encrypted = uwsgi_malloc(ub->pos + EVP_MAX_BLOCK_LENGTH); if (EVP_EncryptInit_ex(uclc->encrypt_ctx, NULL, NULL, NULL, NULL) <= 0) { uwsgi_error_safe("[uwsgi-logcrypto] EVP_EncryptInit_ex()"); free(encrypted); goto error; } int e_len = 0; if (EVP_EncryptUpdate(uclc->encrypt_ctx, encrypted, &e_len, (unsigned char *) ub->buf, ub->pos) <= 0) { uwsgi_error("[uwsgi-logcrypto] EVP_EncryptUpdate()"); free(encrypted); goto error; } int tmplen = 0; if (EVP_EncryptFinal_ex(uclc->encrypt_ctx, encrypted + e_len, &tmplen) <= 0) { uwsgi_error("[uwsgi-logcrypto] EVP_EncryptFinal_ex()"); free(encrypted); goto error; } uwsgi_buffer_destroy(ub); ssize_t rlen = sendto(ul->fd, encrypted, e_len + tmplen, 0, (struct sockaddr *) &ul->addr.sa_in, ul->addr_len); free(encrypted); return rlen; error: uwsgi_buffer_destroy(ub); return -1; }
int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) { int serverfd; struct sockaddr_in uws_addr; int reuse = 1; socket_to_in_addr(socket_name, tcp_port, 0, &uws_addr); serverfd = socket(AF_INET, SOCK_STREAM, 0); if (serverfd < 0) { uwsgi_error("socket()"); uwsgi_nuclear_blast(); } if (setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, (const void *) &reuse, sizeof(int)) < 0) { uwsgi_error("SO_REUSEADDR setsockopt()"); uwsgi_nuclear_blast(); } #ifdef __linux__ #ifndef IP_FREEBIND #define IP_FREEBIND 15 #endif if (uwsgi.freebind) { if (setsockopt(serverfd, SOL_IP, IP_FREEBIND, (const void *) &uwsgi.freebind, sizeof(int)) < 0) { uwsgi_error("IP_FREEBIND setsockopt()"); uwsgi_nuclear_blast(); } } #endif if (uwsgi.reuse_port) { #ifdef SO_REUSEPORT if (setsockopt(serverfd, SOL_SOCKET, SO_REUSEPORT, (const void *) &uwsgi.reuse_port, sizeof(int)) < 0) { uwsgi_error("SO_REUSEPORT setsockopt()"); uwsgi_nuclear_blast(); } #else uwsgi_log("!!! your system does not support SO_REUSEPORT !!!\n"); #endif } if (uwsgi.so_send_timeout) { struct timeval tv; tv.tv_sec = uwsgi.so_send_timeout; tv.tv_usec = 0; if (setsockopt(serverfd, SOL_SOCKET, SO_SNDTIMEO, (const void *) &tv, sizeof(struct timeval)) < 0) { uwsgi_error("SO_SNDTIMEO setsockopt()"); uwsgi_nuclear_blast(); } } if (!uwsgi.no_defer_accept) { #ifdef __linux__ if (setsockopt(serverfd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], sizeof(int))) { uwsgi_error("TCP_DEFER_ACCEPT setsockopt()"); } // OSX has no SO_ACCEPTFILTER !!! #elif defined(__freebsd__) struct accept_filter_arg afa; strcpy(afa.af_name, "dataready"); afa.af_arg[0] = 0; if (setsockopt(serverfd, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(struct accept_filter_arg))) { uwsgi_error("SO_ACCEPTFILTER setsockopt()"); } #endif } if (uwsgi.so_keepalive) { if (setsockopt(serverfd, SOL_SOCKET, SO_KEEPALIVE, &uwsgi.so_keepalive, sizeof(int))) { uwsgi_error("SO_KEEPALIVE setsockopt()"); } } if (bind(serverfd, (struct sockaddr *) &uws_addr, sizeof(uws_addr)) != 0) { if (errno == EADDRINUSE) { uwsgi_log("probably another instance of uWSGI is running on the same address (%s).\n", socket_name); } uwsgi_error("bind()"); uwsgi_nuclear_blast(); } #ifdef __linux__ long somaxconn = uwsgi_num_from_file("/proc/sys/net/core/somaxconn", 1); if (somaxconn > 0 && uwsgi.listen_queue > somaxconn) { uwsgi_log("Listen queue size is greater than the system max net.core.somaxconn (%i).\n", somaxconn); uwsgi_nuclear_blast(); } #endif if (listen(serverfd, listen_queue) != 0) { uwsgi_error("listen()"); uwsgi_nuclear_blast(); } if (tcp_port) tcp_port[0] = ':'; return serverfd; }
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; int rlen; if (!ul->configured) { if (!ul->arg) { uwsgi_log_safe("invalid rsyslog syntax\n"); exit(1); } ul->fd = socket(AF_INET, SOCK_DGRAM, 0); if (ul->fd < 0) { uwsgi_error_safe("socket()"); exit(1); } uwsgi_socket_nb(ul->fd); char *comma = strchr(ul->arg, ','); if (comma) { ul->data = comma+1; *comma = 0; } else { ul->data = uwsgi_concat2(uwsgi.hostname," uwsgi"); } char *port = strchr(ul->arg, ':'); if (port) { portn = atoi(port+1); *port = 0; } ul->addr_len = socket_to_in_addr(ul->arg, NULL, portn, &ul->addr.sa_in); if (port) *port = ':'; if (comma) *comma = ','; ul->configured = 1; } current_time = uwsgi_now(); // drop newline if (message[len-1] == '\n') len--; #ifdef __sun__ ctime_r(¤t_time, ctime_storage, 26); #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); } return -1; }
int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) { int serverfd; struct sockaddr_in uws_addr; int reuse = 1; socket_to_in_addr(socket_name, tcp_port, 0, &uws_addr); serverfd = socket(AF_INET, SOCK_STREAM, 0); if (serverfd < 0) { uwsgi_error("socket()"); uwsgi_nuclear_blast(); } if (setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, (const void *) &reuse, sizeof(int)) < 0) { uwsgi_error("setsockopt()"); uwsgi_nuclear_blast(); } #ifdef __linux__ #ifdef IP_FREEBIND if (uwsgi.freebind) { if (setsockopt(serverfd, SOL_IP, IP_FREEBIND, (const void *) &uwsgi.freebind, sizeof(int)) < 0) { uwsgi_error("setsockopt()"); uwsgi_nuclear_blast(); } } #endif #endif if (uwsgi.reuse_port) { #ifdef SO_REUSEPORT if (setsockopt(serverfd, SOL_SOCKET, SO_REUSEPORT, (const void *) &uwsgi.reuse_port, sizeof(int)) < 0) { uwsgi_error("setsockopt()"); uwsgi_nuclear_blast(); } #else uwsgi_log("!!! your system does not support SO_REUSEPORT !!!\n"); #endif } if (!uwsgi.no_defer_accept) { #ifdef __linux__ if (setsockopt(serverfd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], sizeof(int))) { uwsgi_error("setsockopt()"); } // OSX has no SO_ACCEPTFILTER !!! #elif defined(__freebsd__) struct accept_filter_arg afa; strcpy(afa.af_name, "dataready"); afa.af_arg[0] = 0; if (setsockopt(serverfd, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(struct accept_filter_arg))) { uwsgi_error("setsockopt()"); } #endif } if (bind(serverfd, (struct sockaddr *) &uws_addr, sizeof(uws_addr)) != 0) { if (errno == EADDRINUSE) { uwsgi_log("probably another instance of uWSGI is running on the same address.\n"); } uwsgi_error("bind()"); uwsgi_nuclear_blast(); } if (listen(serverfd, listen_queue) != 0) { uwsgi_error("listen()"); uwsgi_nuclear_blast(); } if (tcp_port) tcp_port[0] = ':'; return serverfd; }