Optimize status and reply handling in the code. Add status object to /api/stats/summary

Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
DL6ER
2023-10-26 19:13:57 +02:00
parent 8664165ebc
commit 0b4abb2bd3
8 changed files with 145 additions and 70 deletions
+76
View File
@@ -406,6 +406,82 @@ components:
type: integer
description: Queries of remaining types
example: 845
status:
type: object
description: Number of individual queries (by status)
properties:
UNKNOWN:
type: integer
description: Type UNKNOWN queries
example: 3
GRAVITY:
type: integer
description: Type GRAVITY queries
example: 72
FORWARDED:
type: integer
description: Type FORWARDED queries
example: 533
CACHE:
type: integer
description: Type CACHE queries
example: 32
REGEX:
type: integer
description: Type REGEX queries
example: 84
DENYLIST:
type: integer
description: Type DENYLIST queries
example: 31
EXTERNAL_BLOCKED_IP:
type: integer
description: Type EXTERNAL_BLOCKED_IP queries
example: 0
EXTERNAL_BLOCKED_NULL:
type: integer
description: Type EXTERNAL_BLOCKED_NULL queries
example: 0
EXTERNAL_BLOCKED_NXRA:
type: integer
description: Type EXTERNAL_BLOCKED_NXRA queries
example: 0
GRAVITY_CNAME:
type: integer
description: Type GRAVITY_CNAME queries
example: 0
REGEX_CNAME:
type: integer
description: Type REGEX_CNAME queries
example: 0
DENYLIST_CNAME:
type: integer
description: Type DENYLIST_CNAME queries
example: 0
RETRIED:
type: integer
description: Type RETRIED queries
example: 0
RETRIED_DNSSEC:
type: integer
description: Type RETRIED_DNSSEC queries
example: 0
IN_PROGRESS:
type: integer
description: Type IN_PROGRESS queries
example: 0
DBBUSY:
type: integer
description: Type DBBUSY queries
example: 0
SPECIAL_DOMAIN:
type: integer
description: Type SPECIAL_DOMAIN queries
example: 0
CACHE_STALE:
type: integer
description: Type CACHE_STALE queries
example: 0
replies:
type: object
description: Number of individual replies
+4
View File
@@ -100,6 +100,10 @@ int api_stats_summary(struct ftl_conn *api)
return ret;
JSON_ADD_ITEM_TO_OBJECT(queries, "types", types);
cJSON *statuses = JSON_NEW_OBJECT();
for(enum query_status status = 0; status < QUERY_STATUS_MAX; status++)
JSON_ADD_NUMBER_TO_OBJECT(statuses, get_query_status_str(status), counters->status[status]);
JSON_ADD_ITEM_TO_OBJECT(queries, "status", statuses);
cJSON *replies = JSON_NEW_OBJECT();
for(enum reply_type reply = 0; reply <QUERY_REPLY_MAX; reply++)
+15 -22
View File
@@ -8,19 +8,19 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
#include "../FTL.h"
#include "FTL.h"
#define QUERY_TABLE_PRIVATE
#include "query-table.h"
#include "sqlite3.h"
#include "../log.h"
#include "../config/config.h"
#include "../enums.h"
#include "../config/config.h"
#include "database/query-table.h"
#include "database/sqlite3.h"
#include "log.h"
#include "config/config.h"
#include "enums.h"
#include "config/config.h"
// counters
#include "../shmem.h"
#include "../overTime.h"
#include "common.h"
#include "../timers.h"
#include "shmem.h"
#include "overTime.h"
#include "database/common.h"
#include "timers.h"
static sqlite3 *memdb = NULL;
static double new_last_timestamp = 0;
@@ -1059,6 +1059,7 @@ void DB_read_queries(void)
query->type = TYPE_OTHER;
query->qtype = type - 100;
}
counters->querytype[query->type]++;
// Status is set below
query->domainID = domainID;
@@ -1084,13 +1085,9 @@ void DB_read_queries(void)
clientsData *client = getClient(clientID, true);
client->lastQuery = queryTimeStamp;
// Handle type counters
if(type >= TYPE_A && type < TYPE_MAX)
counters->querytype[type]++;
// Update overTime data
overTime[timeidx].total++;
// Update overTime data structure with the new client
// Update client's overTime data structure
change_clientcount(client, 0, 0, timeidx, 1);
// Increase DNS queries counter
@@ -1126,12 +1123,8 @@ void DB_read_queries(void)
cache->domainlist_id = sqlite3_column_int(stmt, 7);
}
// Increment status counters, we first have to add one to the count of
// unknown queries because query_set_status() will subtract from there
// when setting a different status
if(status != QUERY_UNKNOWN)
counters->status[QUERY_UNKNOWN]++;
query_set_status(query, status);
// Increment status counters
query_set_status_init(query, status);
// Do further processing based on the query status we read from the database
switch(status)
+38 -24
View File
@@ -926,19 +926,27 @@ static const char* __attribute__ ((const)) query_status_str(const enum query_sta
return NULL;
}
void _query_set_status(queriesData *query, const enum query_status new_status, const char *func, const int line, const char *file)
void _query_set_status(queriesData *query, const enum query_status new_status, const bool init,
const char *func, const int line, const char *file)
{
// Debug logging
if(config.debug.status.v.b)
{
const char *oldstr = query->status < QUERY_STATUS_MAX ? query_status_str(query->status) : "INVALID";
if(query->status == new_status)
if(init)
{
const char *newstr = new_status < QUERY_STATUS_MAX ? query_status_str(new_status) : "INVALID";
log_debug(DEBUG_STATUS, "Query %i: status initialized: %s (%d) in %s() (%s:%i)",
query->id, newstr, new_status, func, short_path(file), line);
}
else if(query->status == new_status)
{
const char *oldstr = query->status < QUERY_STATUS_MAX ? query_status_str(query->status) : "INVALID";
log_debug(DEBUG_STATUS, "Query %i: status unchanged: %s (%d) in %s() (%s:%i)",
query->id, oldstr, query->status, func, short_path(file), line);
}
else
{
const char *oldstr = query->status < QUERY_STATUS_MAX ? query_status_str(query->status) : "INVALID";
const char *newstr = new_status < QUERY_STATUS_MAX ? query_status_str(new_status) : "INVALID";
log_debug(DEBUG_STATUS, "Query %i: status changed: %s (%d) -> %s (%d) in %s() (%s:%i)",
query->id, oldstr, query->status, newstr, new_status, func, short_path(file), line);
@@ -949,30 +957,36 @@ void _query_set_status(queriesData *query, const enum query_status new_status, c
if(new_status >= QUERY_STATUS_MAX)
return;
// Update counters
if(query->status != new_status)
const enum query_status old_status = query->status;
if(old_status == new_status && !init)
{
counters->status[query->status]--;
counters->status[new_status]++;
const int timeidx = getOverTimeID(query->timestamp);
if(is_blocked(query->status))
overTime[timeidx].blocked--;
if(is_blocked(new_status))
overTime[timeidx].blocked++;
if(query->status == QUERY_CACHE)
overTime[timeidx].cached--;
if(new_status == QUERY_CACHE)
overTime[timeidx].cached++;
if(query->status == QUERY_FORWARDED)
overTime[timeidx].forwarded--;
if(new_status == QUERY_FORWARDED)
overTime[timeidx].forwarded++;
// Nothing to do
return;
}
// Update status
// else: update global counters, ...
if(!init)
counters->status[old_status]--;
counters->status[new_status]++;
// ... update overTime counters, ...
const int timeidx = getOverTimeID(query->timestamp);
if(is_blocked(old_status) && !init)
overTime[timeidx].blocked--;
if(is_blocked(new_status))
overTime[timeidx].blocked++;
if(old_status == QUERY_CACHE && !init)
overTime[timeidx].cached--;
if(new_status == QUERY_CACHE)
overTime[timeidx].cached++;
if(old_status == QUERY_FORWARDED && !init)
overTime[timeidx].forwarded--;
if(new_status == QUERY_FORWARDED)
overTime[timeidx].forwarded++;
// ... and set new status
query->status = new_status;
}
+3 -2
View File
@@ -134,8 +134,9 @@ const char *get_cached_statuslist(void) __attribute__ ((pure));
int get_blocked_count(void) __attribute__ ((pure));
int get_forwarded_count(void) __attribute__ ((pure));
int get_cached_count(void) __attribute__ ((pure));
#define query_set_status(query, new_status) _query_set_status(query, new_status, __FUNCTION__, __LINE__, __FILE__)
void _query_set_status(queriesData *query, const enum query_status new_status, const char *func, const int line, const char *file);
#define query_set_status(query, new_status) _query_set_status(query, new_status, false, __FUNCTION__, __LINE__, __FILE__)
#define query_set_status_init(query, new_status) _query_set_status(query, new_status, true, __FUNCTION__, __LINE__, __FILE__)
void _query_set_status(queriesData *query, const enum query_status new_status, const bool init, const char *func, const int line, const char *file);
void FTL_reload_all_domainlists(void);
void FTL_reset_per_client_domain_data(void);
+5 -6
View File
@@ -746,12 +746,12 @@ bool _FTL_new_query(const unsigned int flags, const char *name,
query->magic = MAGICBYTE;
query->timestamp = querytimestamp;
query->type = querytype;
counters->querytype[querytype]++;
query->qtype = qtype;
query->id = id; // Has to be set before calling query_set_status()
// This query is unknown as long as no reply has been found and analyzed
counters->status[QUERY_UNKNOWN]++;
query_set_status(query, QUERY_UNKNOWN);
query_set_status_init(query, QUERY_UNKNOWN);
query->domainID = domainID;
query->clientID = clientID;
// Initialize database field, will be set when the query is stored in the long-term DB
@@ -797,9 +797,6 @@ bool _FTL_new_query(const unsigned int flags, const char *name,
client->lastQuery = querytimestamp;
client->numQueriesARP++;
// Update counters
counters->querytype[querytype]++;
// Process interface information of client (if available)
// Skip interface name length 1 to skip "-". No real interface should
// have a name with a length of 1...
@@ -2528,7 +2525,6 @@ static void FTL_upstream_error(const union all_addr *addr, const unsigned int fl
if(query->reply == REPLY_OTHER)
log_debug(DEBUG_QUERIES, " Unknown rcode = %i", addr->log.rcode);
if(addr->log.ede != EDE_UNSET)
log_debug(DEBUG_QUERIES, " EDE: %s (1/%d)", edestr(addr->log.ede), addr->log.ede);
@@ -3364,7 +3360,10 @@ void FTL_multiple_replies(const int id, int *firstID)
log_debug(DEBUG_QUERIES, "**** sending reply %d also to %d", *firstID, queryID);
// Copy relevant information over
counters->reply[duplicated_query->reply]--;
duplicated_query->reply = source_query->reply;
counters->reply[duplicated_query->reply]++;
duplicated_query->dnssec = source_query->dnssec;
duplicated_query->flags.complete = true;
duplicated_query->CNAME_domainID = source_query->CNAME_domainID;
+4 -7
View File
@@ -189,7 +189,6 @@ void runGC(const time_t now, time_t *lastGCrun, const bool flush)
case QUERY_RETRIED: // (fall through)
case QUERY_RETRIED_DNSSEC:
// Forwarded to an upstream DNS server
// Adjusting counters is done below in moveOverTimeMemory()
break;
case QUERY_CACHE:
case QUERY_CACHE_STALE:
@@ -206,7 +205,6 @@ void runGC(const time_t now, time_t *lastGCrun, const bool flush)
case QUERY_DENYLIST_CNAME: // Exactly denied domain in CNAME chain (fall through)
case QUERY_DBBUSY: // Blocked because gravity database was busy
case QUERY_SPECIAL_DOMAIN: // Blocked by special domain handling
//counters->blocked--;
overTime[timeidx].blocked--;
if(domain != NULL)
domain->blockedcount--;
@@ -220,16 +218,15 @@ void runGC(const time_t now, time_t *lastGCrun, const bool flush)
break;
}
// Update reply countersthread_running[GC] = false;
// Update reply counters
counters->reply[query->reply]--;
// Update type counters
if(query->type >= TYPE_A && query->type < TYPE_MAX)
counters->querytype[query->type]--;
counters->querytype[query->type]--;
// Subtract UNKNOWN from the counters before
// setting the status if different. This ensure
// we are not counting them at all.
// setting the status if different.
// Minus one here and plus one below = net zero
if(query->status != QUERY_UNKNOWN)
counters->status[QUERY_UNKNOWN]--;
-9
View File
@@ -190,15 +190,6 @@ void moveOverTimeMemory(const time_t mintime)
&overTime[moveOverTime],
remainingSlots*sizeof(*overTime));
// Correct time indices of queries. This is necessary because we just moved the slot this index points to
for(int queryID = 0; queryID < counters->queries; queryID++)
{
// Get query pointer
queriesData* query = getQuery(queryID, true);
if(query == NULL)
continue;
}
// Move client-specific overTime memory
for(int clientID = 0; clientID < counters->clients; clientID++)
{