Implement actual TOP suggestions for the Query Log

Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
DL6ER
2024-06-25 09:02:29 +02:00
parent c29e87df82
commit af7ea105eb
+18 -5
View File
@@ -47,7 +47,7 @@ static int add_strings_to_array(struct ftl_conn *api, cJSON *array, const char *
// Loop through returned rows
int counter = 0;
while((rc = sqlite3_step(stmt)) == SQLITE_ROW &&
(max_count < 0 || ++counter < max_count))
(max_count < 0 || ++counter <= max_count))
JSON_COPY_STR_TO_ARRAY(array, (const char*)sqlite3_column_text(stmt, 0));
// Acceptable return codes are either
@@ -77,19 +77,24 @@ int api_queries_suggestions(struct ftl_conn *api)
// Get domains
cJSON *domain = JSON_NEW_ARRAY();
rc = add_strings_to_array(api, domain, "SELECT domain FROM domain_by_id", count);
log_debug(DEBUG_API, "Reading top domains from database");
rc = add_strings_to_array(api, domain, "WITH CTE AS (SELECT COUNT(*) cnt, domain FROM query_storage GROUP BY domain ORDER BY cnt DESC)"\
"SELECT d.domain FROM CTE JOIN domain_by_id d ON CTE.domain = d.id", count);
if(rc != 0)
{
log_err("Cannot read domains from database");
cJSON_Delete(domain);
return rc;
}
log_debug(DEBUG_API, "Read %d domains from database", cJSON_GetArraySize(domain));
// Get clients, both by IP and names
// We have to call DISTINCT() here as multiple IPs can map to and name and
// vice versa
cJSON *client_ip = JSON_NEW_ARRAY();
rc = add_strings_to_array(api, client_ip, "SELECT DISTINCT(ip) FROM client_by_id", count);
log_debug(DEBUG_API, "Reading top client IPs from database");
rc = add_strings_to_array(api, client_ip, "WITH CTE AS (SELECT COUNT(*) cnt, client FROM query_storage GROUP BY client ORDER BY cnt DESC)"\
"SELECT c.ip FROM CTE JOIN client_by_id c ON CTE.client = c.id", count);
if(rc != 0)
{
log_err("Cannot read client IPs from database");
@@ -97,8 +102,12 @@ int api_queries_suggestions(struct ftl_conn *api)
cJSON_Delete(client_ip);
return rc;
}
log_debug(DEBUG_API, "Read %d client IPs from database", cJSON_GetArraySize(client_ip));
cJSON *client_name = JSON_NEW_ARRAY();
rc = add_strings_to_array(api, client_name, "SELECT DISTINCT(name) FROM client_by_id", count);
log_debug(DEBUG_API, "Reading top client names from database");
rc = add_strings_to_array(api, client_name, "WITH CTE AS (SELECT COUNT(*) cnt, client FROM query_storage GROUP BY client ORDER BY cnt DESC)"\
"SELECT c.name FROM CTE JOIN client_by_id c ON CTE.client = c.id WHERE c.name IS NOT NULL", count);
if(rc != 0)
{
log_err("Cannot read client names from database");
@@ -107,10 +116,13 @@ int api_queries_suggestions(struct ftl_conn *api)
cJSON_Delete(client_name);
return rc;
}
log_debug(DEBUG_API, "Read %d client names from database", cJSON_GetArraySize(client_name));
// Get upstreams
cJSON *upstream = JSON_NEW_ARRAY();
rc = add_strings_to_array(api, upstream, "SELECT forward FROM forward_by_id", count);
log_debug(DEBUG_API, "Reading top upstreams from database");
rc = add_strings_to_array(api, upstream, "WITH CTE AS (SELECT COUNT(*) cnt, forward FROM query_storage GROUP BY forward ORDER BY cnt DESC)"\
"SELECT f.forward FROM CTE JOIN forward_by_id f ON CTE.forward = f.id", count);
if(rc != 0)
{
log_err("Cannot read forward from database");
@@ -120,6 +132,7 @@ int api_queries_suggestions(struct ftl_conn *api)
cJSON_Delete(upstream);
return rc;
}
log_debug(DEBUG_API, "Read %d upstreams from database", cJSON_GetArraySize(upstream));
// Get types
cJSON *type = JSON_NEW_ARRAY();