int nagios() { struct uwsgi_header uh; char *buf = NULL; if (!use_nagios) { return 1; } if (!uwsgi.sockets) { fprintf(stdout, "UWSGI UNKNOWN: you have specified an invalid socket\n"); exit(3); } int fd = uwsgi_connect(uwsgi.sockets->name, uwsgi.socket_timeout, 0); if (fd < 0) { fprintf(stdout, "UWSGI CRITICAL: could not connect() to workers %s\n", strerror(errno)); if (errno == EPERM || errno == EACCES) { exit(3); } exit(2); } uh.modifier1 = UWSGI_MODIFIER_PING; uh.pktsize = 0; uh.modifier2 = 0; if (write(fd, &uh, 4) != 4) { uwsgi_error("write()"); fprintf(stdout, "UWSGI CRITICAL: could not send ping packet to workers\n"); exit(2); } int ret = uwsgi_read_response(fd, &uh, uwsgi.socket_timeout, &buf); if (ret == -2) { fprintf(stdout, "UWSGI CRITICAL: timed out waiting for response\n"); exit(2); } else if (ret == -1) { fprintf(stdout, "UWSGI CRITICAL: error reading response\n"); exit(2); } else { if (uh.pktsize > 0 && buf) { fprintf(stdout, "UWSGI WARNING: %.*s\n", uh.pktsize, buf); exit(1); } else { fprintf(stdout, "UWSGI OK: armed and ready\n"); exit(0); } } // never here fprintf(stdout, "UWSGI UNKNOWN: probably you hit a bug of uWSGI !!!\n"); exit(3); }
void uwsgi_opt_corerouter_zerg(char *opt, char *value, void *cr) { int j; int count = 8; struct uwsgi_gateway_socket *ugs; struct uwsgi_corerouter *ucr = (struct uwsgi_corerouter *) cr; int zerg_fd = uwsgi_connect(value, 30, 0); if (zerg_fd < 0) { uwsgi_log("--- unable to connect to zerg server ---\n"); exit(1); } int last_count = count; int *zerg = uwsgi_attach_fd(zerg_fd, &count, "uwsgi-zerg", 10); if (zerg == NULL) { if (last_count != count) { close(zerg_fd); zerg_fd = uwsgi_connect(value, 30, 0); if (zerg_fd < 0) { uwsgi_log("--- unable to connect to zerg server ---\n"); exit(1); } zerg = uwsgi_attach_fd(zerg_fd, &count, "uwsgi-zerg", 10); } else { uwsgi_log("--- invalid data received from zerg-server ---\n"); exit(1); } } if (zerg == NULL) { uwsgi_log("--- invalid data received from zerg-server ---\n"); exit(1); } close(zerg_fd); for(j=0;j<count;j++) { if (zerg[j] == -1) break; ugs = uwsgi_new_gateway_socket_from_fd(zerg[j], ucr->name); ugs->zerg = optarg; } free(zerg); }
int uwsgi_routing_func_uwsgi_remote(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) { struct uwsgi_header *uh = (struct uwsgi_header *) ur->data; char *addr = ur->data + sizeof(struct uwsgi_header); // mark a route request wsgi_req->status = -17; // append appid if (ur->data2_len > 0) { uwsgi_req_append(wsgi_req, "UWSGI_APPID", 11, ur->data2, ur->data2_len); } // ok now if have offload threads, directly use them if (wsgi_req->socket->can_offload) { struct uwsgi_buffer *ub = uwsgi_buffer_new(4 + wsgi_req->uh.pktsize); if (ub) { uh->pktsize = wsgi_req->uh.pktsize; if (uwsgi_buffer_append(ub, (char *) uh, 4)) goto bad; if (uwsgi_buffer_append(ub, wsgi_req->buffer, uh->pktsize)) goto bad; if (!uwsgi_offload_request_net_do(wsgi_req, addr, ub)) { wsgi_req->status = -30; return UWSGI_ROUTE_BREAK; } bad: uwsgi_buffer_destroy(ub); } } int uwsgi_fd = uwsgi_connect(addr, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], 0); if (uwsgi_fd < 0) { uwsgi_log("unable to connect to host %s\n", addr); return UWSGI_ROUTE_NEXT; } int post_fd = wsgi_req->poll.fd; if (wsgi_req->async_post) { post_fd = fileno((FILE*)wsgi_req->async_post); } if (uwsgi_send_message(uwsgi_fd, uh->modifier1, uh->modifier2, wsgi_req->buffer, wsgi_req->uh.pktsize, post_fd, wsgi_req->post_cl, 0) < 0) { uwsgi_log("unable to send uwsgi request to host %s", addr); return UWSGI_ROUTE_NEXT; } ssize_t ret = uwsgi_pipe(uwsgi_fd, wsgi_req->poll.fd, 0); if (ret > 0) { wsgi_req->response_size += ret; } else { uwsgi_log("unable to manage uwsgi route response for %s\n", addr); } close(uwsgi_fd); return UWSGI_ROUTE_BREAK; }
int uwsgi_proxy_nb(struct wsgi_request *wsgi_req, char *addr, struct uwsgi_buffer *ub, size_t remains, int timeout) { int fd = uwsgi_connect(addr, 0, 1); if (fd < 0) { return -1; } int ret = uwsgi.wait_write_hook(fd, timeout); if (ret <= 0) { goto end; } // send the request (+ remaining data) if (ub) { if (uwsgi_write_true_nb(fd, ub->buf, ub->pos, timeout)) { goto end; } } // send the body while(remains > 0) { ssize_t rlen = 0; char *buf = uwsgi_request_body_read(wsgi_req, 8192, &rlen); if (!buf) { goto end; } if (buf == uwsgi.empty) break; // write data to the node if (uwsgi_write_true_nb(fd, buf, rlen, timeout)) { goto end; } remains -= rlen; } // read the response for(;;) { char buf[8192]; ssize_t rlen = uwsgi_read_true_nb(fd, buf, 8192, timeout); if (rlen > 0) { if (uwsgi_response_write_body_do(wsgi_req, buf, rlen)) { break; } continue; } break; } close(fd); return 0; end: close(fd); return -1; }
static int u_offload_transfer_prepare(struct wsgi_request *wsgi_req, struct uwsgi_offload_request *uor) { if (!uor->name) { return -1; } uor->fd = uwsgi_connect(uor->name, 0, 1); if (uor->fd < 0) { uwsgi_error("u_offload_transfer_prepare()/connect()"); return -1; } return 0; }
int uwsgi_wstcp(struct wsgi_request *wsgi_req) { if (uwsgi_parse_vars(wsgi_req)) return -1; // handshake the websocket connection if (uwsgi_websocket_handshake(wsgi_req, NULL, 0, NULL, 0, NULL, 0)) return -1; // async connect to the tcp server int fd = uwsgi_connect("127.0.0.1:9090", 0, 1); if (fd < 0) return -1; // wait for connection int ret = uwsgi.wait_write_hook(fd, 30); if (ret <= 0) { close(fd); return -1; } // ok we are connected, enter the main loop for(;;) { int ready_fd = -1; // wait for both websockets and tcp int ret = uwsgi.wait_read2_hook(wsgi_req->fd, fd, 30, &ready_fd); if (ret <= 0) break; // websocket message if (ready_fd == wsgi_req->fd) { // read websocket message struct uwsgi_buffer *ub = uwsgi_websocket_recv_nb(wsgi_req); if (!ub) break; // send to tcp if (uwsgi_write_true_nb(fd, ub->buf, ub->pos, 30)) break; } // packet from tcp else if (ready_fd == fd) { char buf[8192]; // read from the tcp socket ssize_t rlen = uwsgi_read_true_nb(fd, buf, 8192, 30); if (rlen <= 0) break; // send to the websocket if (uwsgi_websocket_send_binary(wsgi_req, buf, rlen)) break; } } // end of the session close(fd); return UWSGI_OK; }
static int fcgi_send(struct wsgi_request *wsgi_req, char *addr, struct uwsgi_buffer *ub, int timeout) { int fd = uwsgi_connect(addr, 0, 1); if (fd < 0) return -1; int ret = uwsgi.wait_write_hook(fd, timeout); if (ret <= 0) goto error; if (uwsgi_write_true_nb(fd, ub->buf, ub->pos, timeout)) goto error; return fd; error: close(fd); return -1; }
static void ping() { struct uwsgi_header uh; char *buf = NULL; // use a 3 secs timeout by default if (!uping.ping_timeout) uping.ping_timeout = 3; uwsgi_log("PING uwsgi host %s (timeout: %d)\n", uping.ping, uping.ping_timeout); int fd = uwsgi_connect(uping.ping, uping.ping_timeout, 0); if (fd < 0) { exit(1); } uh.modifier1 = UWSGI_MODIFIER_PING; uh.pktsize = 0; uh.modifier2 = 0; if (write(fd, &uh, 4) != 4) { uwsgi_error("write()"); exit(2); } int ret = uwsgi_read_response(fd, &uh, uping.ping_timeout, &buf); if (ret < 0) { exit(1); } else { if (uh.pktsize > 0) { uwsgi_log("[WARNING] node %s message: %.*s\n", uping.ping, uh.pktsize, buf); exit(2); } else { exit(0); } } }
void uwsgi_imperial_monitor_amqp_init(struct uwsgi_emperor_scanner *ues) { char *vhost = "/"; char *username = "******"; char *password = "******"; ues->fd = uwsgi_connect(ues->arg+7, -1, 0); if (ues->fd < 0) { uwsgi_log("unable to connect to AMQP server\n"); return; } if (uwsgi_amqp_consume_queue(ues->fd, vhost, username, password, "", "uwsgi.emperor", "fanout") < 0) { close(ues->fd); ues->fd = -1; uwsgi_log("unable to subscribe to AMQP queue\n"); return; } ues->event_func = uwsgi_imperial_monitor_amqp_event; event_queue_add_fd_read(uwsgi.emperor_queue, ues->fd); }
int uwsgi_remote_signal_send(char *addr, uint8_t sig) { struct uwsgi_header uh; uh.modifier1 = 110; uh.pktsize = 0; uh.modifier2 = sig; int fd = uwsgi_connect(addr, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], 0); if (fd < 0) return -1; if (write(fd, (char *) &uh, 4) != 4) { uwsgi_error("uwsgi_remote_signal_send()"); close(fd); return -1; } int ret = uwsgi_read_response(fd, &uh, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], NULL); close(fd); return ret; }
void uwsgi_python_harakiri(int wid) { if (up.tracebacker) { char buf[8192]; char *address = uwsgi_concat2(up.tracebacker, uwsgi_num2str(wid)); int fd = uwsgi_connect(address, -1, 0); for (;;) { int ret = uwsgi_waitfd(fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); if (ret <= 0) { break; } ssize_t len = read(fd, buf, 8192); if (len <= 0) { break; } uwsgi_log("%.*s", (int) len, buf); } free(address); } }
static int uwsgi_routing_func_memcached(struct wsgi_request *wsgi_req, struct uwsgi_route *ur){ // this is the buffer for the memcached response char buf[MEMCACHED_BUFSIZE]; size_t i; char last_char = 0; struct uwsgi_router_memcached_conf *urmc = (struct uwsgi_router_memcached_conf *) ur->data2; char **subject = (char **) (((char *)(wsgi_req))+ur->subject); uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len); struct uwsgi_buffer *ub_key = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urmc->key, urmc->key_len); if (!ub_key) return UWSGI_ROUTE_BREAK; int fd = uwsgi_connect(urmc->addr, 0, 1); if (fd < 0) { uwsgi_buffer_destroy(ub_key) ; goto end; } // wait for connection; int ret = uwsgi.wait_write_hook(fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); if (ret <= 0) { uwsgi_buffer_destroy(ub_key) ; close(fd); goto end; } // build the request and send it char *cmd = uwsgi_concat3n("get ", 4, ub_key->buf, ub_key->pos, "\r\n", 2); if (uwsgi_write_true_nb(fd, cmd, 6+ub_key->pos, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT])) { uwsgi_buffer_destroy(ub_key); free(cmd); close(fd); goto end; } uwsgi_buffer_destroy(ub_key); free(cmd); // ok, start reading the response... // first we need to get a full line; size_t found = 0; size_t pos = 0; for(;;) { ssize_t len = read(fd, buf + pos, MEMCACHED_BUFSIZE - pos); if (len > 0) { pos += len; goto read; } if (len < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) goto wait; } close(fd); goto end; wait: ret = uwsgi.wait_read_hook(fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); // when we have a chunk try to read the first line if (ret > 0) { len = read(fd, buf + pos, MEMCACHED_BUFSIZE - pos); if (len > 0) { pos += len; goto read; } } close(fd); goto end; read: for(i=0;i<pos;i++) { if (last_char == '\r' && buf[i] == '\n') { found = i-1; break; } last_char = buf[i]; } if (found) break; } // ok parse the first line size_t response_size = memcached_firstline_parse(buf, found); if (response_size == 0) { close(fd); goto end; } if (urmc->type_num == 1) { if (uwsgi_response_prepare_headers(wsgi_req, "200 OK", 6)) { close(fd); goto end; } if (uwsgi_response_add_content_type(wsgi_req, urmc->content_type, urmc->content_type_len)) { close(fd); goto end; } if (uwsgi_response_add_content_length(wsgi_req, response_size)) { close(fd); goto end; } } size_t remains = pos-(found+2); if (remains >= response_size) { uwsgi_response_write_body_do(wsgi_req, buf+found+2, response_size); close(fd); goto end; } // send what we have if (uwsgi_response_write_body_do(wsgi_req, buf+found+2, remains)) { close(fd); goto end; } // and now start reading til the output is consumed response_size -= remains; while(response_size > 0) { ssize_t len = read(fd, buf, UMIN(MEMCACHED_BUFSIZE, response_size)); if (len > 0) goto write; if (len < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) goto wait2; } goto error; wait2: ret = uwsgi.wait_read_hook(fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); if (ret > 0) { len = read(fd, buf, UMIN(MEMCACHED_BUFSIZE, response_size)); if (len > 0) goto write; } goto error; write: if (uwsgi_response_write_body_do(wsgi_req, buf, len)) { goto error; } response_size -= len; } close(fd); return UWSGI_ROUTE_BREAK; error: close(fd); end: if (ur->custom) return UWSGI_ROUTE_NEXT; return UWSGI_ROUTE_BREAK; }
static int uwsgi_init_ssh_session( struct uwsgi_ssh_mountpoint *usm, int* socket_fd, LIBSSH2_SESSION **session) { int sock = uwsgi_connect(usm->remote, ulibssh2.ssh_timeout, 1); if (sock < 0) { uwsgi_error("uwsgi_init_ssh_session()/uwsgi_connect()"); return 1; } int rc = libssh2_init(0); if (rc) { uwsgi_error("uwsgi_init_ssh_session()/libssh2_init()"); goto shutdown; } *session = libssh2_session_init(); if (!session) { uwsgi_error("uwsgi_init_ssh_session()/libssh2_session_init()"); goto shutdown; } libssh2_session_set_blocking(*session, 0); while ((rc = libssh2_session_handshake(*session, sock)) == LIBSSH2_ERROR_EAGAIN) { uwsgi_ssh_waitsocket(sock, *session); } if (rc) { uwsgi_error("uwsgi_init_ssh_session()/libssh2_session_handshake()"); goto shutdown; } if (!ulibssh2.disable_remote_fingerprint_check) { LIBSSH2_KNOWNHOSTS *nh = libssh2_knownhost_init(*session); if (!nh) { uwsgi_error("uwsgi_init_ssh_session()/libssh2_knownhost_init()"); goto shutdown; } if (libssh2_knownhost_readfile(nh, ulibssh2.known_hosts_path, LIBSSH2_KNOWNHOST_FILE_OPENSSH) < 0) { uwsgi_error("uwsgi_init_ssh_session()/libssh2_knownhost_readfile()"); } size_t len; int type; const char *fingerprint = libssh2_session_hostkey(*session, &len, &type); if (!fingerprint) { uwsgi_error("uwsgi_init_ssh_session()/libssh2_session_hostkey()"); libssh2_knownhost_free(nh); goto shutdown; } char *remoteaddr_str = uwsgi_str(usm->remote); char *port_str = strchr(remoteaddr_str, ':'); int port = SSH_DEFAULT_PORT; if (port_str) { port_str[0] = 0; port_str++; port = atoi(port_str); } struct libssh2_knownhost *host; int check = libssh2_knownhost_checkp( nh, remoteaddr_str, port, fingerprint, len, LIBSSH2_KNOWNHOST_TYPE_PLAIN|LIBSSH2_KNOWNHOST_KEYENC_RAW, &host ); free(remoteaddr_str); if (check != LIBSSH2_KNOWNHOST_CHECK_MATCH) { uwsgi_log("[SSH] Remote fingerprint check failed!\n"); libssh2_knownhost_free(nh); goto shutdown; } libssh2_knownhost_free(nh); } // If specified, username and password are honored if (usm->username && usm->password) { while ((rc = libssh2_userauth_password( *session, usm->username, usm->password) ) == LIBSSH2_ERROR_EAGAIN) { uwsgi_ssh_waitsocket(sock, *session); } if (rc) { uwsgi_error("uwsgi_init_ssh_session()/libssh2_userauth_password()"); goto shutdown; } else { goto end; } // Else, let's try the fallback authentication methods: } else if (usm->username || ulibssh2.username) { // Let's choose which username to use char* auth_user = ulibssh2.username; if (usm->username) { auth_user = usm->username; } // Password authentication if (ulibssh2.auth_pw && ulibssh2.password) { while ((rc = libssh2_userauth_password( *session, auth_user, ulibssh2.password) ) == LIBSSH2_ERROR_EAGAIN) { uwsgi_ssh_waitsocket(sock, *session); } if (rc) { uwsgi_error("uwsgi_init_ssh_session()/libssh2_userauth_password()"); // goto shutdown; } else { goto end; } } // SSH agent authentication if (usm->ssh_agent || ulibssh2.auth_ssh_agent) { if (uwsgi_ssh_agent_auth(*session, sock, auth_user)) { uwsgi_error("uwsgi_init_ssh_session()/uwsgi_ssh_agent_auth()"); // goto shutdown; } else { goto end; } } // Public key authentication if ((ulibssh2.private_key_path && ulibssh2.private_key_passphrase) || (usm->priv_key_path && usm->priv_key_passphrase)) { char *actual_pubk_path = ulibssh2.public_key_path; if (usm->pub_key_path) { actual_pubk_path = usm->pub_key_path; } char *actual_privk_path = ulibssh2.private_key_path; if (usm->priv_key_path) { actual_privk_path = usm->priv_key_path; } char *actual_passphrase = ulibssh2.private_key_passphrase; if (usm->priv_key_passphrase) { actual_passphrase = usm->priv_key_passphrase; } while ((rc = libssh2_userauth_publickey_fromfile( *session, auth_user, actual_pubk_path, actual_privk_path, actual_passphrase) ) == LIBSSH2_ERROR_EAGAIN) { uwsgi_ssh_waitsocket(sock, *session); } if (rc == LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED) { uwsgi_log("[SSH] ssh authentication failed (bad passphrase)\n"); // goto shutdown; } else if (rc) { uwsgi_error("uwsgi_init_ssh_session()/libssh2_userauth_publickey_fromfile()"); // goto shutdown; } else { goto end; } } } // If we arrive here, something went wrong. uwsgi_log("[SSH] session initialization failed (no authentication method worked)\n"); shutdown: close(sock); return 1; end: // Otherwise, we're fine! *socket_fd = sock; return 0; }
void carbon_push_stats(int retry_cycle) { struct carbon_server_list *usl = u_carbon.servers_data; int i; int fd; int wok; for (i = 0; i < uwsgi.numproc; i++) { u_carbon.current_busyness_values[i] = uwsgi.workers[i+1].running_time - u_carbon.last_busyness_values[i]; u_carbon.last_busyness_values[i] = uwsgi.workers[i+1].running_time; } u_carbon.need_retry = 0; while(usl) { if (retry_cycle && usl->healthy) // skip healthy servers during retry cycle goto nxt; if (retry_cycle && usl->healthy == 0) uwsgi_log("[carbon] Retrying failed server at %s (%d)\n", usl->value, usl->errors); if (!retry_cycle) { usl->healthy = 1; usl->errors = 0; } fd = uwsgi_connect(usl->value, u_carbon.timeout, 0); if (fd < 0) { uwsgi_log("[carbon] Could not connect to carbon server at %s\n", usl->value); if (usl->errors < u_carbon.max_retries) { u_carbon.need_retry = 1; u_carbon.next_retry = uwsgi_now() + u_carbon.retry_delay; } else { uwsgi_log("[carbon] Maximum number of retries for %s (%d)\n", usl->value, u_carbon.max_retries); usl->healthy = 0; usl->errors = 0; } usl->healthy = 0; usl->errors++; goto nxt; } // put the socket in non-blocking mode uwsgi_socket_nb(fd); unsigned long long total_rss = 0; unsigned long long total_vsz = 0; unsigned long long total_tx = 0; unsigned long long total_avg_rt = 0; // total avg_rt unsigned long long avg_rt = 0; // per worker avg_rt reported to carbon unsigned long long active_workers = 0; // number of workers used to calculate total avg_rt unsigned long long total_busyness = 0; unsigned long long total_avg_busyness = 0; unsigned long long worker_busyness = 0; unsigned long long total_harakiri = 0; wok = carbon_write(&fd, "uwsgi.%s.%s.requests %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) uwsgi.workers[0].requests, (unsigned long long) uwsgi.current_time); if (!wok) goto clear; for(i=1;i<=uwsgi.numproc;i++) { total_tx += uwsgi.workers[i].tx; if (uwsgi.workers[i].cheaped) { // also if worker is cheaped than we report its average response time as zero, sending last value might be confusing avg_rt = 0; worker_busyness = 0; } else { // global average response time is calculated from active/idle workers, cheaped workers are excluded, otherwise it is not accurate avg_rt = uwsgi.workers[i].avg_response_time; active_workers++; total_avg_rt += uwsgi.workers[i].avg_response_time; // calculate worker busyness worker_busyness = ((u_carbon.current_busyness_values[i-1]*100) / (u_carbon.freq*1000000)); if (worker_busyness > 100) worker_busyness = 100; total_busyness += worker_busyness; // only running workers are counted in total memory stats total_rss += uwsgi.workers[i].rss_size; total_vsz += uwsgi.workers[i].vsz_size; total_harakiri += uwsgi.workers[i].harakiri_count; } //skip per worker metrics when disabled if (u_carbon.no_workers) continue; wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.requests %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) uwsgi.workers[i].requests, (unsigned long long) uwsgi.current_time); if (!wok) goto clear; wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.rss_size %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) uwsgi.workers[i].rss_size, (unsigned long long) uwsgi.current_time); if (!wok) goto clear; wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.vsz_size %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) uwsgi.workers[i].vsz_size, (unsigned long long) uwsgi.current_time); if (!wok) goto clear; wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.avg_rt %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) avg_rt, (unsigned long long) uwsgi.current_time); if (!wok) goto clear; wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.tx %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) uwsgi.workers[i].tx, (unsigned long long) uwsgi.current_time); if (!wok) goto clear; wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.busyness %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) worker_busyness, (unsigned long long) uwsgi.current_time); if (!wok) goto clear; wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.harakiri %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) uwsgi.workers[i].harakiri_count, (unsigned long long) uwsgi.current_time); if (!wok) goto clear; } wok = carbon_write(&fd, "uwsgi.%s.%s.rss_size %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) total_rss, (unsigned long long) uwsgi.current_time); if (!wok) goto clear; wok = carbon_write(&fd, "uwsgi.%s.%s.vsz_size %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) total_vsz, (unsigned long long) uwsgi.current_time); if (!wok) goto clear; wok = carbon_write(&fd, "uwsgi.%s.%s.avg_rt %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) (active_workers ? total_avg_rt / active_workers : 0), (unsigned long long) uwsgi.current_time); if (!wok) goto clear; wok = carbon_write(&fd, "uwsgi.%s.%s.tx %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) total_tx, (unsigned long long) uwsgi.current_time); if (!wok) goto clear; if (active_workers > 0) { total_avg_busyness = total_busyness / active_workers; if (total_avg_busyness > 100) total_avg_busyness = 100; } else { total_avg_busyness = 0; } wok = carbon_write(&fd, "uwsgi.%s.%s.busyness %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) total_avg_busyness, (unsigned long long) uwsgi.current_time); if (!wok) goto clear; wok = carbon_write(&fd, "uwsgi.%s.%s.active_workers %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) active_workers, (unsigned long long) uwsgi.current_time); if (!wok) goto clear; if (uwsgi.cheaper) { wok = carbon_write(&fd, "uwsgi.%s.%s.cheaped_workers %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) uwsgi.numproc - active_workers, (unsigned long long) uwsgi.current_time); if (!wok) goto clear; } wok = carbon_write(&fd, "uwsgi.%s.%s.harakiri %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) total_harakiri, (unsigned long long) uwsgi.current_time); if (!wok) goto clear; usl->healthy = 1; usl->errors = 0; clear: close(fd); nxt: usl = usl->next; } if (!retry_cycle) u_carbon.last_update = uwsgi_now(); if (u_carbon.need_retry) // timeouts and retries might cause additional lags in carbon cycles, we will adjust timer to fix that u_carbon.last_update -= u_carbon.timeout; }
ssize_t uwsgi_redis_logger(struct uwsgi_logger *ul, char *message, size_t len) { ssize_t ret,ret2; struct uwsgi_redislog_state *uredislog = NULL; if (!ul->configured) { if (!ul->data) { ul->data = uwsgi_calloc(sizeof(struct uwsgi_redislog_state)); uredislog = (struct uwsgi_redislog_state *) ul->data; } if (ul->arg != NULL) { char *logarg = uwsgi_str(ul->arg); char *comma1 = strchr(logarg, ','); if (!comma1) { uredislog->address = logarg; goto done; } *comma1 = 0; uredislog->address = logarg; comma1++; if (*comma1 == 0) goto done; char *comma2 = strchr(comma1,','); if (!comma2) { uredislog->command = uwsgi_redis_logger_build_command(comma1); goto done; } *comma2 = 0; uredislog->command = uwsgi_redis_logger_build_command(comma1); comma2++; if (*comma2 == 0) goto done; uredislog->prefix = comma2; } done: if (!uredislog->address) uredislog->address = uwsgi_str("127.0.0.1:6379"); if (!uredislog->command) uredislog->command = "*3\r\n$7\r\npublish\r\n$5\r\nuwsgi\r\n"; if (!uredislog->prefix) uredislog->prefix = ""; uredislog->fd = -1; uredislog->iovec[0].iov_base = uredislog->command; uredislog->iovec[0].iov_len = strlen(uredislog->command); uredislog->iovec[1].iov_base = "$"; uredislog->iovec[1].iov_len = 1; uredislog->iovec[2].iov_base = uredislog->msgsize; uredislog->iovec[3].iov_base = "\r\n"; uredislog->iovec[3].iov_len = 2; uredislog->iovec[4].iov_base = uredislog->prefix; uredislog->iovec[4].iov_len = strlen(uredislog->prefix); uredislog->iovec[6].iov_base = "\r\n"; uredislog->iovec[6].iov_len = 2; ul->configured = 1; } uredislog = (struct uwsgi_redislog_state *) ul->data; if (uredislog->fd == -1) { uredislog->fd = uwsgi_connect(uredislog->address, uwsgi.socket_timeout, 0); } if (uredislog->fd == -1) return -1; // drop newline if (message[len-1] == '\n') len--; uwsgi_num2str2(len + uredislog->iovec[4].iov_len, uredislog->msgsize); uredislog->iovec[2].iov_len = strlen(uredislog->msgsize); uredislog->iovec[5].iov_base = message; uredislog->iovec[5].iov_len = len; ret = writev(uredislog->fd, uredislog->iovec, 7); if (ret <= 0) { close(uredislog->fd); uredislog->fd = -1; return -1; } again: // read til a \n is found (ugly but fast) ret2 = read(uredislog->fd, uredislog->response, 8); if (ret2 <= 0) { close(uredislog->fd); uredislog->fd = -1; return -1; } if (!memchr(uredislog->response, '\n', ret2)) { goto again; } return ret; }
/* extremely complex function for reading resources (files, url...) need a lot of refactoring... */ char *uwsgi_open_and_read(char *url, size_t *size, int add_zero, char *magic_table[]) { int fd; struct stat sb; char *buffer = NULL; char byte; ssize_t len; char *uri, *colon; char *domain; char *ip; int body = 0; char *magic_buf; // stdin ? if (!strcmp(url, "-")) { buffer = uwsgi_read_fd(0, size, add_zero); } // fd ? else if (!strncmp("fd://", url, 5)) { fd = atoi(url + 5); buffer = uwsgi_read_fd(fd, size, add_zero); } // exec ? else if (!strncmp("exec://", url, 5)) { int cpipe[2]; if (pipe(cpipe)) { uwsgi_error("pipe()"); exit(1); } uwsgi_run_command(url + 7, NULL, cpipe[1]); buffer = uwsgi_read_fd(cpipe[0], size, add_zero); close(cpipe[0]); close(cpipe[1]); } // http url ? else if (!strncmp("http://", url, 7)) { domain = url + 7; uri = strchr(domain, '/'); if (!uri) { uwsgi_log("invalid http url\n"); exit(1); } uri[0] = 0; uwsgi_log("domain: %s\n", domain); colon = uwsgi_get_last_char(domain, ':'); if (colon) { colon[0] = 0; } ip = uwsgi_resolve_ip(domain); if (!ip) { uwsgi_log("unable to resolve address %s\n", domain); exit(1); } if (colon) { colon[0] = ':'; ip = uwsgi_concat2(ip, colon); } else { ip = uwsgi_concat2(ip, ":80"); } fd = uwsgi_connect(ip, 0, 0); if (fd < 0) { exit(1); } free(ip); uri[0] = '/'; len = write(fd, "GET ", 4); len = write(fd, uri, strlen(uri)); len = write(fd, " HTTP/1.0\r\n", 11); len = write(fd, "Host: ", 6); uri[0] = 0; len = write(fd, domain, strlen(domain)); uri[0] = '/'; len = write(fd, "\r\nUser-Agent: uWSGI on ", 23); len = write(fd, uwsgi.hostname, uwsgi.hostname_len); len = write(fd, "\r\n\r\n", 4); int http_status_code_ptr = 0; while (read(fd, &byte, 1) == 1) { if (byte == '\r' && body == 0) { body = 1; } else if (byte == '\n' && body == 1) { body = 2; } else if (byte == '\r' && body == 2) { body = 3; } else if (byte == '\n' && body == 3) { body = 4; } else if (body == 4) { *size = *size + 1; char *tmp = realloc(buffer, *size); if (!tmp) { uwsgi_error("uwsgi_open_and_read()/realloc()"); exit(1); } buffer = tmp; buffer[*size - 1] = byte; } else { body = 0; http_status_code_ptr++; if (http_status_code_ptr == 10) { if (byte != '2') { uwsgi_log("Not usable HTTP response: %cxx\n", byte); if (uwsgi.has_emperor) { exit(UWSGI_EXILE_CODE); } else { exit(1); } } } } } close(fd); if (add_zero) { *size = *size + 1; char *tmp = realloc(buffer, *size); if (!tmp) { uwsgi_error("uwsgi_open_and_read()/realloc()"); exit(1); } buffer = tmp; buffer[*size - 1] = 0; } } else if (!strncmp("emperor://", url, 10)) { if (uwsgi.emperor_fd_config < 0) { uwsgi_log("this is not a vassal instance\n"); exit(1); } ssize_t rlen; *size = 0; struct uwsgi_header uh; size_t remains = 4; char *ptr = (char *) &uh; while(remains) { int ret = uwsgi_waitfd(uwsgi.emperor_fd_config, 5); if (ret <= 0) { uwsgi_log("[uwsgi-vassal] error waiting for config header %s !!!\n", url); exit(1); } rlen = read(uwsgi.emperor_fd_config, ptr, remains); if (rlen <= 0) { uwsgi_log("[uwsgi-vassal] error reading config header from !!!\n", url); exit(1); } ptr+=rlen; remains-=rlen; } remains = uh.pktsize; if (!remains) { uwsgi_log("[uwsgi-vassal] invalid config from %s\n", url); exit(1); } buffer = uwsgi_calloc(remains + add_zero); ptr = buffer; while (remains) { int ret = uwsgi_waitfd(uwsgi.emperor_fd_config, 5); if (ret <= 0) { uwsgi_log("[uwsgi-vassal] error waiting for config %s !!!\n", url); exit(1); } rlen = read(uwsgi.emperor_fd_config, ptr, remains); if (rlen <= 0) { uwsgi_log("[uwsgi-vassal] error reading config from !!!\n", url); exit(1); } ptr+=rlen; remains-=rlen; } *size = uh.pktsize + add_zero; } #ifdef UWSGI_EMBED_CONFIG else if (url[0] == 0) { *size = &UWSGI_EMBED_CONFIG_END - &UWSGI_EMBED_CONFIG; if (add_zero) { *size += 1; } buffer = uwsgi_malloc(*size); memset(buffer, 0, *size); memcpy(buffer, &UWSGI_EMBED_CONFIG, &UWSGI_EMBED_CONFIG_END - &UWSGI_EMBED_CONFIG); } #endif else if (!strncmp("data://", url, 7)) { fd = open(uwsgi.binary_path, O_RDONLY); if (fd < 0) { uwsgi_error_open(uwsgi.binary_path); exit(1); } int slot = atoi(url + 7); if (slot < 0) { uwsgi_log("invalid binary data slot requested\n"); exit(1); } uwsgi_log("requesting binary data slot %d\n", slot); off_t fo = lseek(fd, 0, SEEK_END); if (fo < 0) { uwsgi_error("lseek()"); uwsgi_log("invalid binary data slot requested\n"); exit(1); } int i = 0; uint64_t datasize = 0; for (i = 0; i <= slot; i++) { fo = lseek(fd, -9, SEEK_CUR); if (fo < 0) { uwsgi_error("lseek()"); uwsgi_log("invalid binary data slot requested\n"); exit(1); } ssize_t len = read(fd, &datasize, 8); if (len != 8) { uwsgi_error("read()"); uwsgi_log("invalid binary data slot requested\n"); exit(1); } if (datasize == 0) { uwsgi_log("0 size binary data !!!\n"); exit(1); } fo = lseek(fd, -(datasize + 9), SEEK_CUR); if (fo < 0) { uwsgi_error("lseek()"); uwsgi_log("invalid binary data slot requested\n"); exit(1); } if (i == slot) { *size = datasize; if (add_zero) { *size += 1; } buffer = uwsgi_malloc(*size); memset(buffer, 0, *size); len = read(fd, buffer, datasize); if (len != (ssize_t) datasize) { uwsgi_error("read()"); uwsgi_log("invalid binary data slot requested\n"); exit(1); } } } } else if (!strncmp("sym://", url, 6)) { char *symbol = uwsgi_concat3("_binary_", url + 6, "_start"); void *sym_start_ptr = dlsym(RTLD_DEFAULT, symbol); if (!sym_start_ptr) { uwsgi_log("unable to find symbol %s\n", symbol); exit(1); } free(symbol); symbol = uwsgi_concat3("_binary_", url + 6, "_end"); void *sym_end_ptr = dlsym(RTLD_DEFAULT, symbol); if (!sym_end_ptr) { uwsgi_log("unable to find symbol %s\n", symbol); exit(1); } free(symbol); *size = sym_end_ptr - sym_start_ptr; if (add_zero) { *size += 1; } buffer = uwsgi_malloc(*size); memset(buffer, 0, *size); memcpy(buffer, sym_start_ptr, sym_end_ptr - sym_start_ptr); } #ifdef UWSGI_ELF else if (!strncmp("section://", url, 10)) { size_t s_len = 0; buffer = uwsgi_elf_section(uwsgi.binary_path, url + 10, &s_len); if (!buffer) { uwsgi_log("unable to find section %s in %s\n", url + 10, uwsgi.binary_path); exit(1); } *size = s_len; if (add_zero) *size += 1; } #endif // fallback to file else { fd = open(url, O_RDONLY); if (fd < 0) { uwsgi_error_open(url); exit(1); } if (fstat(fd, &sb)) { uwsgi_error("fstat()"); exit(1); } if (S_ISFIFO(sb.st_mode)) { buffer = uwsgi_read_fd(fd, size, add_zero); close(fd); goto end; } buffer = uwsgi_malloc(sb.st_size + add_zero); len = read(fd, buffer, sb.st_size); if (len != sb.st_size) { uwsgi_error("read()"); exit(1); } close(fd); *size = sb.st_size + add_zero; if (add_zero) buffer[sb.st_size] = 0; } end: if (magic_table) { magic_buf = magic_sub(buffer, *size, size, magic_table); free(buffer); return magic_buf; } return buffer; }
int bind_to_unix_dgram(char *socket_name) { int serverfd; struct sockaddr_un *uws_addr; socklen_t len; serverfd = socket(AF_UNIX, SOCK_DGRAM, 0); if (serverfd < 0) { uwsgi_error("socket()"); uwsgi_nuclear_blast(); } if (unlink(socket_name) != 0 && errno != ENOENT) { uwsgi_error("unlink()"); } uws_addr = uwsgi_calloc(sizeof(struct sockaddr_un)); uws_addr->sun_family = AF_UNIX; memcpy(uws_addr->sun_path, socket_name, UMIN(strlen(socket_name), 102)); len = strlen(socket_name); #ifdef __HAIKU__ if (bind(serverfd, (struct sockaddr *) uws_addr, sizeof(struct sockaddr_un))) { #else if (bind(serverfd, (struct sockaddr *) uws_addr, len + ((void *) uws_addr->sun_path - (void *) uws_addr)) != 0) { #endif uwsgi_error("bind()"); uwsgi_nuclear_blast(); } return serverfd; } int bind_to_unix(char *socket_name, int listen_queue, int chmod_socket, int abstract_socket) { int serverfd; struct sockaddr_un *uws_addr; socklen_t len; // leave 1 byte for abstract namespace (108 linux -> 104 bsd/mac) if (strlen(socket_name) > 102) { uwsgi_log("invalid socket name\n"); uwsgi_nuclear_blast(); } if (socket_name[0] == '@') { abstract_socket = 1; } else if (strlen(socket_name) > 1 && socket_name[0] == '\\' && socket_name[1] == '0') { abstract_socket = 1; } uws_addr = malloc(sizeof(struct sockaddr_un)); if (uws_addr == NULL) { uwsgi_error("malloc()"); uwsgi_nuclear_blast(); } memset(uws_addr, 0, sizeof(struct sockaddr_un)); serverfd = socket(AF_UNIX, SOCK_STREAM, 0); if (serverfd < 0) { uwsgi_error("socket()"); uwsgi_nuclear_blast(); } if (abstract_socket == 0) { if (unlink(socket_name) != 0 && errno != ENOENT) { uwsgi_error("unlink()"); } } if (abstract_socket == 1) { uwsgi_log("setting abstract socket mode (warning: only Linux supports this)\n"); } uws_addr->sun_family = AF_UNIX; if (socket_name[0] == '@') { memcpy(uws_addr->sun_path + abstract_socket, socket_name + 1, UMIN(strlen(socket_name + 1), 101)); len = strlen(socket_name) + 1; } else if (strlen(socket_name) > 1 && socket_name[0] == '\\' && socket_name[1] == '0') { memcpy(uws_addr->sun_path + abstract_socket, socket_name + 2, UMIN(strlen(socket_name + 2), 101)); len = strlen(socket_name + 1) + 1; } else if (abstract_socket) { memcpy(uws_addr->sun_path + 1, socket_name, UMIN(strlen(socket_name), 101)); len = strlen(socket_name) + 1; } else { memcpy(uws_addr->sun_path + abstract_socket, socket_name, UMIN(strlen(socket_name), 102)); len = strlen(socket_name); } #ifdef __HAIKU__ if (bind(serverfd, (struct sockaddr *) uws_addr, sizeof(struct sockaddr_un))) { #else if (bind(serverfd, (struct sockaddr *) uws_addr, len + ((void *) uws_addr->sun_path - (void *) uws_addr)) != 0) { #endif uwsgi_error("bind()"); uwsgi_nuclear_blast(); } if (listen(serverfd, listen_queue) != 0) { uwsgi_error("listen()"); uwsgi_nuclear_blast(); } // chmod unix socket for lazy users if (chmod_socket == 1 && abstract_socket == 0) { if (uwsgi.chmod_socket_value) { if (chmod(socket_name, uwsgi.chmod_socket_value) != 0) { uwsgi_error("chmod()"); } } else { uwsgi_log("chmod() socket to 666 for lazy and brave users\n"); if (chmod(socket_name, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) != 0) { uwsgi_error("chmod()"); } } } free(uws_addr); return serverfd; } #ifdef UWSGI_UDP int bind_to_udp(char *socket_name, int multicast, int broadcast) { int serverfd; struct sockaddr_in uws_addr; char *udp_port; int bcast = 1; int reuse = 1; #ifdef UWSGI_MULTICAST struct ip_mreq mc; uint8_t loop = 1; #endif udp_port = strchr(socket_name, ':'); if (udp_port == NULL) { return -1; } udp_port[0] = 0; if (socket_name[0] == 0 && multicast) { uwsgi_log("invalid multicast address\n"); return -1; } memset(&uws_addr, 0, sizeof(struct sockaddr_in)); uws_addr.sin_family = AF_INET; uws_addr.sin_port = htons(atoi(udp_port + 1)); #ifdef UWSGI_MULTICAST if (!broadcast && !multicast) { char quad[4]; char *first_part = strchr(socket_name, '.'); if (first_part && first_part - socket_name < 4) { memset(quad, 0, 4); memcpy(quad, socket_name, first_part - socket_name); if (atoi(quad) >= 224 && atoi(quad) <= 239) { multicast = 1; } } #else if (!broadcast) { #endif if (!strcmp(socket_name, "255.255.255.255")) { broadcast = 1; } } if (broadcast) { uws_addr.sin_addr.s_addr = INADDR_BROADCAST; } else if (socket_name[0] != 0) { uws_addr.sin_addr.s_addr = inet_addr(socket_name); } else { uws_addr.sin_addr.s_addr = INADDR_ANY; } serverfd = socket(AF_INET, SOCK_DGRAM, 0); if (serverfd < 0) { uwsgi_error("socket()"); return -1; } if (setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, (const void *) &reuse, sizeof(int)) < 0) { uwsgi_error("setsockopt()"); } #ifdef UWSGI_MULTICAST if (multicast) { // if multicast is enabled remember to bind to INADDR_ANY uws_addr.sin_addr.s_addr = INADDR_ANY; mc.imr_multiaddr.s_addr = inet_addr(socket_name); mc.imr_interface.s_addr = INADDR_ANY; } #endif if (broadcast) { if (setsockopt(serverfd, SOL_SOCKET, SO_BROADCAST, &bcast, sizeof(bcast))) { perror("setsockopt"); close(serverfd); return -1; } } if (bind(serverfd, (struct sockaddr *) &uws_addr, sizeof(uws_addr)) != 0) { uwsgi_error("bind()"); close(serverfd); return -1; } #ifdef UWSGI_MULTICAST if (multicast) { uwsgi_log("[uWSGI] joining multicast group: %s:%d\n", socket_name, ntohs(uws_addr.sin_port)); if (setsockopt(serverfd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop))) { uwsgi_error("setsockopt()"); } if (setsockopt(serverfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mc, sizeof(mc))) { uwsgi_error("setsockopt()"); } if (setsockopt(serverfd, IPPROTO_IP, IP_MULTICAST_TTL, &uwsgi.multicast_ttl, sizeof(uwsgi.multicast_ttl))) { uwsgi_error("setsockopt()"); } } #endif udp_port[0] = ':'; return serverfd; } #endif int uwsgi_connectn(char *socket_name, uint16_t len, int timeout, int async) { int fd; char *zeroed_socket_name = uwsgi_concat2n(socket_name, len, "", 0); fd = uwsgi_connect(zeroed_socket_name, timeout, async); free(zeroed_socket_name); return fd; }
void carbon_master_cycle() { static time_t last_update = 0; char ptr[4096]; int rlen, i; int fd; struct uwsgi_string_list *usl = u_carbon.servers; if (!u_carbon.servers) return ; if (last_update == 0) last_update = time(NULL); // update if (uwsgi.current_time - last_update >= u_carbon.freq) { while(usl) { fd = uwsgi_connect(usl->value, u_carbon.timeout, 0); if (fd < 0) goto nxt; // put the socket in non-blocking mode uwsgi_socket_nb(fd); unsigned long long total_rss = 0; unsigned long long total_vsz = 0; unsigned long long total_tx = 0; unsigned long long total_avg_rt = 0; // total avg_rt unsigned long long avg_rt = 0; // per worker avg_rt reported to carbon unsigned long long avg_rt_workers = 0; // number of workers used to calculate total avg_rt rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.requests %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long ) uwsgi.workers[0].requests, (unsigned long long ) uwsgi.current_time); if (rlen < 1) goto clear; if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;} if (u_carbon.no_workers) goto gmetrics; for(i=1;i<=uwsgi.numproc;i++) { rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.worker%d.requests %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long ) uwsgi.workers[i].requests, (unsigned long long ) uwsgi.current_time); if (rlen < 1) goto clear; if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;} total_rss += uwsgi.workers[i].rss_size; rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.worker%d.rss_size %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long ) uwsgi.workers[i].rss_size, (unsigned long long ) uwsgi.current_time); if (rlen < 1) goto clear; if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;} total_vsz += uwsgi.workers[i].vsz_size; rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.worker%d.vsz_size %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long ) uwsgi.workers[i].vsz_size, (unsigned long long ) uwsgi.current_time); if (rlen < 1) goto clear; if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;} if (uwsgi.workers[i].cheaped) { // also if worker is cheaped than we report its average response time as zero, sending last value might be confusing avg_rt = 0; } else { // global average response time is calcucalted from active/idle workers, cheaped workers are excluded, otherwise it is not accurate avg_rt = uwsgi.workers[i].avg_response_time; avg_rt_workers++; total_avg_rt += uwsgi.workers[i].avg_response_time; } rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.worker%d.avg_rt %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long ) avg_rt, (unsigned long long ) uwsgi.current_time); if (rlen < 1) goto clear; if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;} total_tx += uwsgi.workers[i].tx; rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.worker%d.tx %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long ) uwsgi.workers[i].tx, (unsigned long long ) uwsgi.current_time); if (rlen < 1) goto clear; if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;} } gmetrics: rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.rss_size %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long ) total_rss, (unsigned long long ) uwsgi.current_time); if (rlen < 1) goto clear; if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;} rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.vsz_size %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long ) total_vsz, (unsigned long long ) uwsgi.current_time); if (rlen < 1) goto clear; if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;} rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.avg_rt %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long ) (avg_rt_workers ? total_avg_rt / avg_rt_workers : 0), (unsigned long long ) uwsgi.current_time); if (rlen < 1) goto clear; if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;} rlen = snprintf(ptr, 4096, "uwsgi.%s.%s.tx %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long ) total_tx, (unsigned long long ) uwsgi.current_time); if (rlen < 1) goto clear; if (write(fd, ptr, rlen) <= 0) { uwsgi_error("write()"); goto clear;} clear: close(fd); nxt: usl = usl->next; } last_update = time(NULL); } }
int connect_prober_callback(int interesting_fd, struct uwsgi_signal_probe *up) { // is this a timeout event ? if (interesting_fd == -1) { // am i wating for something ? if (up->fd != -1) { if (up->cycles > (uint64_t) up->timeout) { // reset the cycle up->cycles = 0; close(up->fd); up->fd = -1; // state = NOOP up->state = 0; // avoid duplicated events if (!up->bad) { up->bad = 1; return 1; } } } // ok register a new event else { if ((up->cycles % up->freq) == 0) { up->fd = uwsgi_connect(up->args, -1, 1); if (up->fd != -1) { // status = CONNECTING up->state = 1; event_queue_add_fd_write(uwsgi.master_queue, up->fd); return 0; } // signal the bad event (if not already bad) if (!up->bad) { up->bad = 1; return 1; } } } } else if (up->fd != -1) { // is this event for me ? if (interesting_fd == up->fd) { // uselsess here (we have only one state), only to show a good practice // check the state if (up->state == 1) { if (uwsgi_is_bad_connection(up->fd)) { // signal the bad connection (if needed) up->cycles = 0; close(up->fd); up->fd = -1; // state = NOOP up->state = 0; if (!up->bad) { up->bad = 1; return 1; } return 0; } // this is a good connection up->cycles = 0; close(up->fd); up->fd = -1; // state = NOOP up->state = 0; if (up->bad) { up->bad = 0; return 1; } } } } // default action return 0; }