mirror of
https://github.com/pi-hole/FTL.git
synced 2024-10-26 16:52:18 +02:00
Merge pull request #2054 from pi-hole/new/query_frequency_avg
Add queries per second (QPS) metric
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user