// SPDX-License-Identifier: GPL-3.0-or-later
#include "common.h"
#define GLOBAL_STATS_RESET_WEB_USEC_MAX 0x01
#define CONFIG_SECTION_GLOBAL_STATISTICS "global statistics"
static struct global_statistics {
volatile uint16_t connected_clients;
volatile uint64_t web_requests;
volatile uint64_t web_usec;
volatile uint64_t web_usec_max;
volatile uint64_t bytes_received;
volatile uint64_t bytes_sent;
volatile uint64_t content_size;
volatile uint64_t compressed_content_size;
volatile uint64_t web_client_count;
volatile uint64_t rrdr_queries_made;
volatile uint64_t rrdr_db_points_read;
volatile uint64_t rrdr_result_points_generated;
} global_statistics = {
.connected_clients = 0,
.web_requests = 0,
.web_usec = 0,
.bytes_received = 0,
.bytes_sent = 0,
.content_size = 0,
.compressed_content_size = 0,
.web_client_count = 1,
.rrdr_queries_made = 0,
.rrdr_db_points_read = 0,
.rrdr_result_points_generated = 0,
};
#if defined(HAVE_C___ATOMIC) && !defined(NETDATA_NO_ATOMIC_INSTRUCTIONS)
#else
netdata_mutex_t global_statistics_mutex = NETDATA_MUTEX_INITIALIZER;
static inline void global_statistics_lock(void) {
netdata_mutex_lock(&global_statistics_mutex);
}
static inline void global_statistics_unlock(void) {
netdata_mutex_unlock(&global_statistics_mutex);
}
#endif
void rrdr_query_completed(uint64_t db_points_read, uint64_t result_points_generated) {
#if defined(HAVE_C___ATOMIC) && !defined(NETDATA_NO_ATOMIC_INSTRUCTIONS)
__atomic_fetch_add(&global_statistics.rrdr_queries_made, 1, __ATOMIC_SEQ_CST);
__atomic_fetch_add(&global_statistics.rrdr_db_points_read, db_points_read, __ATOMIC_SEQ_CST);
__atomic_fetch_add(&global_statistics.rrdr_result_points_generated, result_points_generated, __ATOMIC_SEQ_CST);
#else
#warning NOT using atomic operations - using locks for global statistics
if (web_server_is_multithreaded)
global_statistics_lock();
global_statistics.rrdr_queries_made++;
global_statistics.rrdr_db_points_read += db_points_read;
global_statistics.rrdr_result_points_generated += result_points_generated;
if (web_server_is_multithreaded)
global_statistics_unlock();
#endif
}
void finished_web_request_statistics(uint64_t dt,
uint64_t bytes_received,
uint64_t bytes_sent,
uint64_t content_size,
uint64_t compressed_content_size) {
#if defined(HAVE_C___ATOMIC) && !defined(NETDATA_NO_ATOMIC_INSTRUCTIONS)
uint64_t old_web_usec_max = global_statistics.web_usec_max;
while(dt > old_web_usec_max)
__atomic_compare_exchange(&global_statistics.web_usec_max, &old_web_usec_max, &dt, 1, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
__atomic_fetch_add(&global_statistics.web_requests, 1, __ATOMIC_SEQ_CST);
__atomic_fetch_add(&global_statistics.web_usec, dt, __ATOMIC_SEQ_CST);
__atomic_fetch_add(&global_statistics.bytes_received, bytes_received, __ATOMIC_SEQ_CST);
__atomic_fetch_add(&global_statistics.bytes_sent, bytes_sent, __ATOMIC_SEQ_CST);
__atomic_fetch_add(&global_statistics.content_size, content_size, __ATOMIC_SEQ_CST);
__atomic_fetch_add(&global_statistics.compressed_content_size, compressed_content_size, __ATOMIC_SEQ_CST);
#else
#warning NOT using atomic operations - using locks for global statistics
if (web_server_is_multithreaded)
global_statistics_lock();
if (dt > global_statistics.web_usec_max)
global_statistics.web_usec_max = dt;
global_statistics.web_requests++;
global_statistics.web_usec += dt;
global_statistics.bytes_received += bytes_received;
global_statistics.bytes_sent += bytes_sent;
global_statistics.content_size += content_size;
global_statistics.compressed_content_size += compressed_content_size;
if (web_server_is_multithreaded)
global_statistics_unlock();
#endif
}
uint64_t web_client_connected(void) {
#if defined(HAVE_C___ATOMIC) && !defined(NETDATA_NO_ATOMIC_INSTRUCTIONS)
__atomic_fetch_add(&global_statistics.connected_clients, 1, __ATOMIC_SEQ_CST);
uint64_t id = __atomic_fetch_add(&global_statistics.web_client_count, 1, __ATOMIC_SEQ_CST);
#else
if (web_server_is_multithreaded)
global_statistics_lock();
global_statistics.connected_clients++;
uint64_t id = global_statistics.web_client_count++;
if (web_server_is_multithreaded)
global_statistics_unlock();
#endif
return id;
}
void web_client_disconnected(void) {
#if defined(HAVE_C___ATOMIC) && !defined(NETDATA_NO_ATOMIC_INSTRUCTIONS)
__atomic_fetch_sub(&global_statistics.