Merge pull request #2054 from pi-hole/new/query_frequency_avg

Add queries per second (QPS) metric
This commit is contained in:
Dominik
2024-09-10 19:57:21 +02:00
committed by GitHub
8 changed files with 69 additions and 0 deletions
+4
View File
@@ -143,6 +143,10 @@
// Default: 2592000 (once per month)
#define DATABASE_MACVENDOR_INTERVAL 2592000
// Over how many seconds should the query-per-second (QPS) value be averaged?
// Default: 30 (seconds)
#define QPS_AVGLEN 30
// Use out own syscalls handling functions that will detect possible errors
// and report accordingly in the log. This will make debugging FTL crash
// caused by insufficient memory or by code bugs (not properly dealing
+4
View File
@@ -721,6 +721,10 @@ components:
type: integer
description: Currently used privacy level
example: 0
query_frequency:
type: number
description: Average number of queries per second
example: 1.1
clients:
type: object
properties:
+4
View File
@@ -338,6 +338,10 @@ components:
type: integer
description: Number of queries replied to from cache or local configuration
example: 9765
frequency:
type: number
description: Average number of queries per second
example: 1.1
types:
type: object
description: Number of individual queries
+2
View File
@@ -548,6 +548,7 @@ static int get_ftl_obj(struct ftl_conn *api, cJSON *ftl)
const int db_denied = counters->database.domains.denied;
const int clients_total = counters->clients;
const int privacylevel = config.misc.privacylevel.v.privacy_level;
const double qps = get_qps();
// unique_clients: count only clients that have been active within the most recent 24 hours
int activeclients = 0;
@@ -575,6 +576,7 @@ static int get_ftl_obj(struct ftl_conn *api, cJSON *ftl)
JSON_ADD_ITEM_TO_OBJECT(ftl, "database", database);
JSON_ADD_NUMBER_TO_OBJECT(ftl, "privacy_level", privacylevel);
JSON_ADD_NUMBER_TO_OBJECT(ftl, "query_frequency", qps);
cJSON *clients = JSON_NEW_OBJECT();
JSON_ADD_NUMBER_TO_OBJECT(clients, "total",clients_total);
+2
View File
@@ -143,6 +143,8 @@ int api_stats_summary(struct ftl_conn *api)
JSON_ADD_NUMBER_TO_OBJECT(queries, "forwarded", forwarded);
JSON_ADD_NUMBER_TO_OBJECT(queries, "cached", cached);
JSON_ADD_NUMBER_TO_OBJECT(queries, "frequency", get_qps());
cJSON *types = JSON_NEW_OBJECT();
int ret = get_query_types_obj(api, types);
if(ret != 0)
+3
View File
@@ -664,6 +664,9 @@ bool _FTL_new_query(const unsigned int flags, const char *name,
return false;
}
// Update rolling window of queries per second
update_qps(querytimestamp);
// Interface name is only available for regular queries, not for
// automatically generated DNSSEC queries
const char *interface = internal_query ? "-" : next_iface.name;
+43
View File
@@ -1206,3 +1206,46 @@ int __attribute__((pure)) is_shm_fd(const int fd)
// Not found
return 0;
}
// Update queries per second (qps) value
// This is done in shared memory to allow for both UDP and TCP workers to
// contribute.
void update_qps(const double timestamp)
{
// Get the timeslot for the current timestamp
const unsigned int slot = (unsigned int)timestamp % QPS_AVGLEN;
// Check if the timestamp is in the same slot as the last one
if(shmSettings->qps.last != slot)
{
// Reset all the slots in between
// This is relevant if less than one query per second is
// received and the intermediate slots are not updated
for(unsigned int i = (shmSettings->qps.last + 1) % QPS_AVGLEN; i != slot; i = (i + 1) % QPS_AVGLEN)
shmSettings->qps.buf[i] = 0;
// Reset the current slot
shmSettings->qps.buf[slot] = 0;
// Update the last slot index
shmSettings->qps.last = slot;
}
// Add the query
shmSettings->qps.buf[slot]++;
}
// Compute queries per second (qps) value
double __attribute__((pure)) get_qps(void)
{
// Compute the arithmetic mean of all slots
// 1 N
// QPS = --- Σ buf[i]
// N i=0
//
double qps = 0.0;
for(unsigned int i = 0; i < QPS_AVGLEN; i++)
qps += shmSettings->qps.buf[i];
return qps / QPS_AVGLEN;
}
+7
View File
@@ -31,6 +31,10 @@ typedef struct {
pid_t pid;
unsigned int global_shm_counter;
unsigned int next_str_pos;
struct {
unsigned int last;
unsigned int buf[QPS_AVGLEN];
} qps;
} ShmSettings;
typedef struct {
@@ -145,4 +149,7 @@ void set_per_client_regex(const int clientID, const int regexID, const bool valu
// Used in dnsmasq/utils.c
int is_shm_fd(const int fd);
void update_qps(const double timestamp);
double get_qps(void) __attribute__((pure));
#endif //SHARED_MEMORY_SERVER_H