diff options
Diffstat (limited to 'web')
-rw-r--r-- | web/api/queries/query.c | 4 | ||||
-rw-r--r-- | web/api/web_api_v1.c | 5 | ||||
-rw-r--r-- | web/rtc/webrtc.c | 37 | ||||
-rw-r--r-- | web/server/h2o/http_server.c | 4 | ||||
-rw-r--r-- | web/server/h2o/streaming.c | 5 | ||||
-rw-r--r-- | web/server/static/static-threaded.c | 4 | ||||
-rw-r--r-- | web/server/web_client.c | 226 | ||||
-rw-r--r-- | web/server/web_client.h | 5 | ||||
-rw-r--r-- | web/server/web_client_cache.c | 1 | ||||
-rw-r--r-- | web/server/web_server.c | 15 |
10 files changed, 198 insertions, 108 deletions
diff --git a/web/api/queries/query.c b/web/api/queries/query.c index b7e89ee978..76d673cae1 100644 --- a/web/api/queries/query.c +++ b/web/api/queries/query.c @@ -3617,12 +3617,12 @@ RRDR *rrd2rrdr(ONEWAYALLOC *owa, QUERY_TARGET *qt) { bool cancel = false; if (qt->request.interrupt_callback && qt->request.interrupt_callback(qt->request.interrupt_callback_data)) { cancel = true; - netdata_log_access("QUERY INTERRUPTED"); + nd_log(NDLS_ACCESS, NDLP_NOTICE, "QUERY INTERRUPTED"); } if (qt->request.timeout_ms && ((NETDATA_DOUBLE)(now_ut - qt->timings.received_ut) / 1000.0) > (NETDATA_DOUBLE)qt->request.timeout_ms) { cancel = true; - netdata_log_access("QUERY CANCELED RUNTIME EXCEEDED %0.2f ms (LIMIT %lld ms)", + nd_log(NDLS_ACCESS, NDLP_WARNING, "QUERY CANCELED RUNTIME EXCEEDED %0.2f ms (LIMIT %lld ms)", (NETDATA_DOUBLE)(now_ut - qt->timings.received_ut) / 1000.0, (long long)qt->request.timeout_ms); } diff --git a/web/api/web_api_v1.c b/web/api/web_api_v1.c index ec0a0b6d61..e08f8aa2f8 100644 --- a/web/api/web_api_v1.c +++ b/web/api/web_api_v1.c @@ -1410,7 +1410,10 @@ int web_client_api_request_v1_function(RRDHOST *host, struct web_client *w, char wb->content_type = CT_APPLICATION_JSON; buffer_no_cacheable(wb); - return rrd_function_run(host, wb, timeout, function, true, NULL, + char transaction[UUID_COMPACT_STR_LEN]; + uuid_unparse_lower_compact(w->transaction, transaction); + + return rrd_function_run(host, wb, timeout, function, true, transaction, NULL, NULL, web_client_interrupt_callback, w, NULL); } diff --git a/web/rtc/webrtc.c b/web/rtc/webrtc.c index 45e5e0dac6..80fff7e940 100644 --- a/web/rtc/webrtc.c +++ b/web/rtc/webrtc.c @@ -279,7 +279,11 @@ static size_t webrtc_send_in_chunks(WEBRTC_DC *chan, const char *data, size_t si } static void webrtc_execute_api_request(WEBRTC_DC *chan, const char *request, size_t size __maybe_unused, bool binary __maybe_unused) { - struct timeval tv; + ND_LOG_STACK lgs[] = { + ND_LOG_FIELD_TXT(NDF_SRC_TRANSPORT, "webrtc"), + ND_LOG_FIELD_END(), + }; + ND_LOG_STACK_PUSH(lgs); internal_error(true, "WEBRTC[%d],DC[%d]: got request '%s' of size %zu and type %s.", chan->conn->pc, chan->dc, request, size, binary?"binary":"text"); @@ -304,6 +308,7 @@ static void webrtc_execute_api_request(WEBRTC_DC *chan, const char *request, siz web_client_timeout_checkpoint_set(w, 0); web_client_decode_path_and_query_string(w, path); path = (char *)buffer_tostring(w->url_path_decoded); + w->response.code = (short)web_client_api_request_with_node_selection(localhost, w, path); web_client_timeout_checkpoint_response_ready(w, NULL); @@ -346,21 +351,7 @@ static void webrtc_execute_api_request(WEBRTC_DC *chan, const char *request, siz w->statistics.sent_bytes = sent_bytes; cleanup: - now_monotonic_high_precision_timeval(&tv); - netdata_log_access("%llu: %d '[RTC]:%d:%d' '%s' (sent/all = %zu/%zu bytes %0.0f%%, prep/sent/total = %0.2f/%0.2f/%0.2f ms) %d '%s'", - w->id - , gettid() - , chan->conn->pc, chan->dc - , "DATA" - , sent_bytes - , response_size - , response_size > sent_bytes ? -(((double)(response_size - sent_bytes) / (double)response_size) * 100.0) : ((response_size > 0) ? (((sent_bytes - response_size) / (double)response_size) * 100.0) : 0.0) - , dt_usec(&w->timings.tv_ready, &w->timings.tv_in) / 1000.0 - , dt_usec(&tv, &w->timings.tv_ready) / 1000.0 - , dt_usec(&tv, &w->timings.tv_in) / 1000.0 - , w->response.code - , strip_control_characters((char *)buffer_tostring(w->url_as_received)) - ); + web_client_log_completed_request(w, false); web_client_release_to_cache(w); } @@ -373,7 +364,7 @@ static void myOpenCallback(int id __maybe_unused, void *user_ptr) { WEBRTC_DC *chan = user_ptr; internal_fatal(chan->dc != id, "WEBRTC[%d],DC[%d]: dc mismatch, expected %d, got %d", chan->conn->pc, chan->dc, chan->dc, id); - netdata_log_access("WEBRTC[%d],DC[%d]: %d DATA CHANNEL '%s' OPEN", chan->conn->pc, chan->dc, gettid(), chan->label); + nd_log(NDLS_ACCESS, NDLP_DEBUG, "WEBRTC[%d],DC[%d]: %d DATA CHANNEL '%s' OPEN", chan->conn->pc, chan->dc, gettid(), chan->label); internal_error(true, "WEBRTC[%d],DC[%d]: data channel opened.", chan->conn->pc, chan->dc); chan->open = true; } @@ -391,7 +382,7 @@ static void myClosedCallback(int id __maybe_unused, void *user_ptr) { DOUBLE_LINKED_LIST_REMOVE_ITEM_UNSAFE(chan->conn->channels.head, chan, link.prev, link.next); spinlock_unlock(&chan->conn->channels.spinlock); - netdata_log_access("WEBRTC[%d],DC[%d]: %d DATA CHANNEL '%s' CLOSED", chan->conn->pc, chan->dc, gettid(), chan->label); + nd_log(NDLS_ACCESS, NDLP_DEBUG, "WEBRTC[%d],DC[%d]: %d DATA CHANNEL '%s' CLOSED", chan->conn->pc, chan->dc, gettid(), chan->label); freez(chan->label); freez(chan); @@ -573,27 +564,27 @@ static void myStateChangeCallback(int pc __maybe_unused, rtcState state, void *u break; case RTC_CONNECTING: - netdata_log_access("WEBRTC[%d]: %d CONNECTING", conn->pc, gettid()); + nd_log(NDLS_ACCESS, NDLP_DEBUG, "WEBRTC[%d]: %d CONNECTING", conn->pc, gettid()); internal_error(true, "WEBRTC[%d]: connecting...", conn->pc); break; case RTC_CONNECTED: - netdata_log_access("WEBRTC[%d]: %d CONNECTED", conn->pc, gettid()); + nd_log(NDLS_ACCESS, NDLP_DEBUG, "WEBRTC[%d]: %d CONNECTED", conn->pc, gettid()); internal_error(true, "WEBRTC[%d]: connected!", conn->pc); break; case RTC_DISCONNECTED: - netdata_log_access("WEBRTC[%d]: %d DISCONNECTED", conn->pc, gettid()); + nd_log(NDLS_ACCESS, NDLP_DEBUG, "WEBRTC[%d]: %d DISCONNECTED", conn->pc, gettid()); internal_error(true, "WEBRTC[%d]: disconnected.", conn->pc); break; case RTC_FAILED: - netdata_log_access("WEBRTC[%d]: %d CONNECTION FAILED", conn->pc, gettid()); + nd_log(NDLS_ACCESS, NDLP_DEBUG, "WEBRTC[%d]: %d CONNECTION FAILED", conn->pc, gettid()); internal_error(true, "WEBRTC[%d]: failed.", conn->pc); break; case RTC_CLOSED: - netdata_log_access("WEBRTC[%d]: %d CONNECTION CLOSED", conn->pc, gettid()); + nd_log(NDLS_ACCESS, NDLP_DEBUG, "WEBRTC[%d]: %d CONNECTION CLOSED", conn->pc, gettid()); internal_error(true, "WEBRTC[%d]: closed.", conn->pc); spinlock_lock(&webrtc_base.unsafe.spinlock); webrtc_destroy_connection_unsafe(conn); diff --git a/web/server/h2o/http_server.c b/web/server/h2o/http_server.c index 6980db2737..08ad120b14 100644 --- a/web/server/h2o/http_server.c +++ b/web/server/h2o/http_server.c @@ -272,7 +272,7 @@ static int netdata_uberhandler(h2o_handler_t *self, h2o_req_t *req) if (host != NULL) uuid_unparse_lower(host->host_uuid, host_uuid_str); - netdata_log_access("HTTPD OK method: " PRINTF_H2O_IOVEC_FMT + nd_log(NDLS_ACCESS, NDLP_DEBUG, "HTTPD OK method: " PRINTF_H2O_IOVEC_FMT ", path: " PRINTF_H2O_IOVEC_FMT ", as host: %s" ", response: %d", @@ -281,7 +281,7 @@ static int netdata_uberhandler(h2o_handler_t *self, h2o_req_t *req) host == NULL ? "unknown" : (localhost ? "localhost" : host_uuid_str), req->res.status); } else { - netdata_log_access("HTTPD %d" + nd_log(NDLS_ACCESS, NDLP_DEBUG, "HTTPD %d" " method: " PRINTF_H2O_IOVEC_FMT ", path: " PRINTF_H2O_IOVEC_FMT ", forwarding to file handler as path: " PRINTF_H2O_IOVEC_FMT, diff --git a/web/server/h2o/streaming.c b/web/server/h2o/streaming.c index d7c9a564a5..063e487afc 100644 --- a/web/server/h2o/streaming.c +++ b/web/server/h2o/streaming.c @@ -294,8 +294,9 @@ void stream_process(h2o_stream_conn_t *conn, int initial) socklen_t len = h2o_socket_getpeername(conn->sock, &client); char peername[NI_MAXHOST]; size_t peername_len = h2o_socket_getnumerichost(&client, len, peername); - memcpy(w.client_ip, peername, peername_len); - w.client_ip[peername_len] = 0; + size_t cpy_len = sizeof(w.client_ip) < peername_len ? sizeof(w.client_ip) : peername_len; + memcpy(w.client_ip, peername, cpy_len); + w.client_ip[cpy_len - 1] = 0; w.user_agent = conn->user_agent; rc = rrdpush_receiver_thread_spawn(&w, conn->url, conn); diff --git a/web/server/static/static-threaded.c b/web/server/static/static-threaded.c index 60d80446eb..e39a46c7c0 100644 --- a/web/server/static/static-threaded.c +++ b/web/server/static/static-threaded.c @@ -294,7 +294,7 @@ static int web_server_rcv_callback(POLLINFO *pi, short int *events) { netdata_log_debug(D_WEB_CLIENT, "%llu: processing received data on fd %d.", w->id, fd); worker_is_idle(); worker_is_busy(WORKER_JOB_PROCESS); - web_client_process_request(w); + web_client_process_request_from_web_server(w); if (unlikely(w->mode == WEB_CLIENT_MODE_STREAM)) { web_client_send(w); @@ -538,8 +538,6 @@ void *socket_listen_main_static_threaded(void *ptr) { static_workers_private_data = callocz((size_t)static_threaded_workers_count, sizeof(struct web_server_static_threaded_worker)); - web_server_is_multithreaded = (static_threaded_workers_count > 1); - int i; for (i = 1; i < static_threaded_workers_count; i++) { static_workers_private_data[i].id = i; diff --git a/web/server/web_client.c b/web/server/web_client.c index ee24632878..3a869bc62a 100644 --- a/web/server/web_client.c +++ b/web/server/web_client.c @@ -163,77 +163,96 @@ static void web_client_reset_allocations(struct web_client *w, bool free_all) { web_client_reset_path_flags(w); } -void web_client_request_done(struct web_client *w) { - web_client_uncork_socket(w); +const char *get_request_method(struct web_client *w) { + switch(w->mode) { + case WEB_CLIENT_MODE_FILECOPY: + return "FILECOPY"; - netdata_log_debug(D_WEB_CLIENT, "%llu: Resetting client.", w->id); + case WEB_CLIENT_MODE_OPTIONS: + return "OPTIONS"; + + case WEB_CLIENT_MODE_STREAM: + return "STREAM"; + + case WEB_CLIENT_MODE_POST: + return "POST"; + + case WEB_CLIENT_MODE_PUT: + return "PUT"; + + case WEB_CLIENT_MODE_GET: + return "GET"; - if(likely(buffer_strlen(w->url_as_received))) { - struct timeval tv; - now_monotonic_high_precision_timeval(&tv); + case WEB_CLIENT_MODE_DELETE: + return "DELETE"; - size_t size = (w->mode == WEB_CLIENT_MODE_FILECOPY)?w->response.rlen:w->response.data->len; - size_t sent = size; - if(likely(w->response.zoutput)) sent = (size_t)w->response.zstream.total_out; + default: + return "UNKNOWN"; + } +} - // -------------------------------------------------------------------- - // global statistics +void web_client_log_completed_request(struct web_client *w, bool update_web_stats) { + struct timeval tv; + now_monotonic_high_precision_timeval(&tv); + size_t size = (w->mode == WEB_CLIENT_MODE_FILECOPY)?w->response.rlen:w->response.data->len; + size_t sent = size; + if(likely(w->response.zoutput)) sent = (size_t)w->response.zstream.total_out; + + if(update_web_stats) global_statistics_web_request_completed(dt_usec(&tv, &w->timings.tv_in), w->statistics.received_bytes, w->statistics.sent_bytes, size, sent); - w->statistics.received_bytes = 0; - w->statistics.sent_bytes = 0; - - - // -------------------------------------------------------------------- - - const char *mode; - switch(w->mode) { - case WEB_CLIENT_MODE_FILECOPY: - mode = "FILECOPY"; - break; - - case WEB_CLIENT_MODE_OPTIONS: - mode = "OPTIONS"; - break; + usec_t prep_ut = w->timings.tv_ready.tv_sec ? dt_usec(&w->timings.tv_ready, &w->timings.tv_in) : 0; + usec_t sent_ut = w->timings.tv_ready.tv_sec ? dt_usec(&tv, &w->timings.tv_ready) : 0; + usec_t total_ut = dt_usec(&tv, &w->timings.tv_in); + strip_control_characters((char *)buffer_tostring(w->url_as_received)); + + ND_LOG_STACK lgs[] = { + ND_LOG_FIELD_U64(NDF_CONNECTION_ID, w->id), + ND_LOG_FIELD_UUID(NDF_TRANSACTION_ID, &w->transaction), + ND_LOG_FIELD_TXT(NDF_NIDL_NODE, w->client_host), + ND_LOG_FIELD_TXT(NDF_REQUEST_METHOD, get_request_method(w)), + ND_LOG_FIELD_BFR(NDF_REQUEST, w->url_as_received), + ND_LOG_FIELD_U64(NDF_RESPONSE_CODE, w->response.code), + ND_LOG_FIELD_U64(NDF_RESPONSE_SENT_BYTES, sent), + ND_LOG_FIELD_U64(NDF_RESPONSE_SIZE_BYTES, size), + ND_LOG_FIELD_U64(NDF_RESPONSE_PREPARATION_TIME_USEC, prep_ut), + ND_LOG_FIELD_U64(NDF_RESPONSE_SENT_TIME_USEC, sent_ut), + ND_LOG_FIELD_U64(NDF_RESPONSE_TOTAL_TIME_USEC, total_ut), + ND_LOG_FIELD_END(), + }; + ND_LOG_STACK_PUSH(lgs); + + ND_LOG_FIELD_PRIORITY prio = NDLP_INFO; + if(w->response.code >= 500) + prio = NDLP_EMERG; + else if(w->response.code >= 400) + prio = NDLP_WARNING; + else if(w->response.code >= 300) + prio = NDLP_NOTICE; + + // access log + nd_log(NDLS_ACCESS, prio, NULL); +} - case WEB_CLIENT_MODE_STREAM: - mode = "STREAM"; - break; +void web_client_request_done(struct web_client *w) { + ND_LOG_STACK lgs[] = { + ND_LOG_FIELD_TXT(NDF_SRC_IP, w->client_ip), + ND_LOG_FIELD_TXT(NDF_SRC_PORT, w->client_port), + ND_LOG_FIELD_END(), + }; + ND_LOG_STACK_PUSH(lgs); - case WEB_CLIENT_MODE_POST: - case WEB_CLIENT_MODE_PUT: - case WEB_CLIENT_MODE_GET: - case WEB_CLIENT_MODE_DELETE: - mode = "DATA"; - break; + web_client_uncork_socket(w); - default: - mode = "UNKNOWN"; - break; - } + netdata_log_debug(D_WEB_CLIENT, "%llu: Resetting client.", w->id); - // access log - netdata_log_access("%llu: %d '[%s]:%s' '%s' (sent/all = %zu/%zu bytes %0.0f%%, prep/sent/total = %0.2f/%0.2f/%0.2f ms) %d '%s'", - w->id - , gettid() - , w->client_ip - , w->client_port - , mode - , sent - , size - , -((size > 0) ? ((double)(size - sent) / (double) size * 100.0) : 0.0) - , (double)dt_usec(&w->timings.tv_ready, &w->timings.tv_in) / 1000.0 - , (double)dt_usec(&tv, &w->timings.tv_ready) / 1000.0 - , (double)dt_usec(&tv, &w->timings.tv_in) / 1000.0 - , w->response.code - , strip_control_characters((char *)buffer_tostring(w->url_as_received)) - ); - } + if(likely(buffer_strlen(w->url_as_received))) + web_client_log_completed_request(w, true); if(unlikely(w->mode == WEB_CLIENT_MODE_FILECOPY)) { if(w->ifd != w->ofd) { @@ -268,6 +287,9 @@ void web_client_request_done(struct web_client *w) { w->response.sent = 0; w->response.code = 0; w->response.zoutput = false; + + w->statistics.received_bytes = 0; + w->statistics.sent_bytes = 0; } static struct { @@ -710,12 +732,22 @@ static inline int UNUSED_FUNCTION(check_host_and_mgmt_acl_and_call)(RRDHOST *hos return check_host_and_call(host, w, url, func); } -int web_client_api_request(RRDHOST *host, struct web_client *w, char *url_path_fragment) -{ +int web_client_api_request(RRDHOST *host, struct web_client *w, char *url_path_fragment) { + ND_LOG_STACK lgs[] = { + ND_LOG_FIELD_TXT(NDF_SRC_IP, w->client_ip), + ND_LOG_FIELD_TXT(NDF_SRC_PORT, w->client_port), + ND_LOG_FIELD_TXT(NDF_NIDL_NODE, w->client_host), + ND_LOG_FIELD_TXT(NDF_REQUEST_METHOD, get_request_method(w)), + ND_LOG_FIELD_BFR(NDF_REQUEST, w->url_as_received), + ND_LOG_FIELD_U64(NDF_CONNECTION_ID, w->id), + ND_LOG_FIELD_UUID(NDF_TRANSACTION_ID, &w->transaction), + ND_LOG_FIELD_END(), + }; + ND_LOG_STACK_PUSH(lgs); + // get the api version char *tok = strsep_skip_consecutive_separators(&url_path_fragment, "/"); if(tok && *tok) { - netdata_log_debug(D_WEB_CLIENT, "%llu: Searching for API version '%s'.", w->id, tok); if(strcmp(tok, "v2") == 0) return web_client_api_request_v2(host, w, url_path_fragment); else if(strcmp(tok, "v1") == 0) @@ -978,7 +1010,7 @@ const char *web_response_code_to_string(int code) { static inline char *http_header_parse(struct web_client *w, char *s, int parse_useragent) { static uint32_t hash_origin = 0, hash_connection = 0, hash_donottrack = 0, hash_useragent = 0, - hash_authorization = 0, hash_host = 0, hash_forwarded_host = 0; + hash_authorization = 0, hash_host = 0, hash_forwarded_host = 0, hash_transaction_id = 0; static uint32_t hash_accept_encoding = 0; if(unlikely(!hash_origin)) { @@ -990,6 +1022,7 @@ static inline char *http_header_parse(struct web_client *w, char *s, int parse_u hash_authorization = simple_uhash("X-Auth-Token"); hash_host = simple_uhash("Host"); hash_forwarded_host = simple_uhash("X-Forwarded-Host"); + hash_transaction_id = simple_uhash("X-Transaction-ID"); } char *e = s; @@ -1057,6 +1090,11 @@ static inline char *http_header_parse(struct web_client *w, char *s, int parse_u strncpyz(buffer, v, ((size_t)(ve - v) < sizeof(buffer) - 1 ? (size_t)(ve - v) : sizeof(buffer) - 1)); w->forwarded_host = strdupz(buffer); } + else if(hash == hash_transaction_id && !strcasecmp(s, "X-Transaction-ID")) { + char buffer[UUID_STR_LEN * 2]; + strncpyz(buffer, v, ((size_t)(ve - v) < sizeof(buffer) - 1 ? (size_t)(ve - v) : sizeof(buffer) - 1)); + uuid_parse_flexi(buffer, w->transaction); // will not alter w->transaction if it fails + } *e = ':'; *ve = '\r'; @@ -1305,16 +1343,9 @@ void web_client_build_http_header(struct web_client *w) { const char *code_msg = web_response_code_to_string(w->response.code); // prepare the last modified and expiration dates - char date[32], edate[32]; - { - struct tm tmbuf, *tm; - - tm = gmtime_r(&w->response.data->date, &tmbuf); - strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %Z", tm); - - tm = gmtime_r(&w->response.data->expires, &tmbuf); - strftime(edate, sizeof(edate), "%a, %d %b %Y %H:%M:%S %Z", tm); - } + char rfc7231_date[RFC7231_MAX_LENGTH], rfc7231_expires[RFC7231_MAX_LENGTH]; + rfc7231_datetime(rfc7231_date, sizeof(rfc7231_date), w->response.data->date); + rfc7231_datetime(rfc7231_expires, sizeof(rfc7231_expires), w->response.data->expires); if (w->response.code == HTTP_RESP_HTTPS_UPGRADE) { buffer_sprintf(w->response.header_output, @@ -1340,7 +1371,7 @@ void web_client_build_http_header(struct web_client *w) { VERSION, w->origin ? w->origin : "*", content_type_string, - date); + rfc7231_date); } if(unlikely(web_x_frame_options)) @@ -1374,7 +1405,7 @@ void web_client_build_http_header(struct web_client *w) { "Cache-Control: %s\r\n" "Expires: %s\r\n", (w->response.data->options & WB_CONTENT_NO_CACHEABLE)?"no-cache, no-store, must-revalidate\r\nPragma: no-cache":"public", - edate); + rfc7231_expires); } // copy a possibly available custom header @@ -1398,6 +1429,11 @@ void web_client_build_http_header(struct web_client *w) { } } + char uuid[UUID_COMPACT_STR_LEN]; + uuid_unparse_lower_compact(w->transaction, uuid); + buffer_sprintf(w->response.header_output, + "X-Transaction-ID: %s\r\n", uuid); + // end of HTTP header buffer_strcat(w->response.header_output, "\r\n"); } @@ -1541,6 +1577,20 @@ static inline int web_client_switch_host(RRDHOST *host, struct web_client *w, ch } int web_client_api_request_with_node_selection(RRDHOST *host, struct web_client *w, char *decoded_url_path) { + // entry point for all API requests + + ND_LOG_STACK lgs[] = { + ND_LOG_FIELD_TXT(NDF_REQUEST_METHOD, get_request_method(w)), + ND_LOG_FIELD_BFR(NDF_REQUEST, w->url_as_received), + ND_LOG_FIELD_U64(NDF_CONNECTION_ID, w->id), + ND_LOG_FIELD_UUID(NDF_TRANSACTION_ID, &w->transaction), + ND_LOG_FIELD_END(), + }; + ND_LOG_STACK_PUSH(lgs); + + // give a new transaction id to the request + uuid_generate_random(w->transaction); + static uint32_t hash_api = 0, hash_host = 0, @@ -1729,7 +1779,37 @@ static inline int web_client_process_url(RRDHOST *host, struct web_client *w, ch return mysendfile(w, filename); } -void web_client_process_request(struct web_client *w) { +static bool web_server_log_transport(BUFFER *wb, void *ptr) { + struct web_client *w = ptr; + if(!w) + return false; + +#ifdef ENABLE_HTTPS + buffer_strcat(wb, SSL_connection(&w->ssl) ? "https" : "http"); +#else + buffer_strcat(wb, "http"); +#endif + return true; +} + +void web_client_process_request_from_web_server(struct web_client *w) { + // entry point for web server requests + + ND_LOG_STACK lgs[] = { + ND_LOG_FIELD_CB(NDF_SRC_TRANSPORT, web_server_log_transport, w), + ND_LOG_FIELD_TXT(NDF_SRC_IP, w->client_ip), + ND_LOG_FIELD_TXT(NDF_SRC_PORT, w->client_port), + ND_LOG_FIELD_TXT(NDF_NIDL_NODE, w->client_host), + ND_LOG_FIELD_TXT(NDF_REQUEST_METHOD, get_request_method(w)), + ND_LOG_FIELD_BFR(NDF_REQUEST, w->url_as_received), + ND_LOG_FIELD_U64(NDF_CONNECTION_ID, w->id), + ND_LOG_FIELD_UUID(NDF_TRANSACTION_ID, &w->transaction), + ND_LOG_FIELD_END(), + }; + ND_LOG_STACK_PUSH(lgs); + + // give a new transaction id to the request + uuid_generate_random(w->transaction); // start timing us web_client_timeout_checkpoint_init(w); diff --git a/web/server/web_client.h b/web/server/web_client.h index ff09fcd548..92d512e3d6 100644 --- a/web/server/web_client.h +++ b/web/server/web_client.h @@ -136,6 +136,8 @@ struct web_client { unsigned long long id; size_t use_count; + uuid_t transaction; + WEB_CLIENT_FLAGS flags; // status flags for the client WEB_CLIENT_MODE mode; // the operational mode of the client WEB_CLIENT_ACL acl; // the access list of the client @@ -207,7 +209,7 @@ ssize_t web_client_send(struct web_client *w); ssize_t web_client_receive(struct web_client *w); ssize_t web_client_read_file(struct web_client *w); -void web_client_process_request(struct web_client *w); +void web_client_process_request_from_web_server(struct web_client *w); void web_client_request_done(struct web_client *w); void buffer_data_options2string(BUFFER *wb, uint32_t options); @@ -234,5 +236,6 @@ void web_client_timeout_checkpoint_set(struct web_client *w, int timeout_ms); usec_t web_client_timeout_checkpoint(struct web_client *w); bool web_client_timeout_checkpoint_and_check(struct web_client *w, usec_t *usec_since_last_checkpoint); usec_t web_client_timeout_checkpoint_response_ready(struct web_client *w, usec_t *usec_since_last_checkpoint); +void web_client_log_completed_request(struct web_client *w, bool update_web_stats); #endif diff --git a/web/server/web_client_cache.c b/web/server/web_client_cache.c index 5a68808c62..364fc76b36 100644 --- a/web/server/web_client_cache.c +++ b/web/server/web_client_cache.c @@ -115,6 +115,7 @@ struct web_client *web_client_get_from_cache(void) { // initialize it w->use_count++; w->mode = WEB_CLIENT_MODE_GET; + memset(w->transaction, 0, sizeof(w->transaction)); return w; } diff --git a/web/server/web_server.c b/web/server/web_server.c index b35fc252b5..8ac0c6595f 100644 --- a/web/server/web_server.c +++ b/web/server/web_server.c @@ -130,5 +130,18 @@ void web_client_update_acl_matches(struct web_client *w) { // -------------------------------------------------------------------------------------- void web_server_log_connection(struct web_client *w, const char *msg) { - netdata_log_access("%llu: %d '[%s]:%s' '%s'", w->id, gettid(), w->client_ip, w->client_port, msg); + ND_LOG_STACK lgs[] = { + ND_LOG_FIELD_U64(NDF_CONNECTION_ID, w->id), +#ifdef ENABLE_HTTPS + ND_LOG_FIELD_TXT(NDF_SRC_TRANSPORT, SSL_connection(&w->ssl) ? "https" : "http"), +#else + ND_LOG_FIELD_TXT(NDF_SRC_TRANSPORT, "http"), +#endif + ND_LOG_FIELD_TXT(NDF_SRC_IP, w->client_ip), + ND_LOG_FIELD_TXT(NDF_SRC_PORT, w->client_port), + ND_LOG_FIELD_END(), + }; + ND_LOG_STACK_PUSH(lgs); + + nd_log(NDLS_ACCESS, NDLP_DEBUG, "[%s]:%s %s", w->client_ip, w->client_port, msg); } |