From c901194d3bfebc4f1d7faebce5b70137205f85c0 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Mon, 16 Jan 2023 21:41:10 +0100 Subject: [PATCH] Rename /api/ftl/logs/dns -> /api/logs/dnsmasq Signed-off-by: DL6ER --- src/api/CMakeLists.txt | 1 + src/api/api.c | 2 +- src/api/api.h | 4 +- src/api/docs/content/specs/logs.yaml | 80 ++++++++++++++++++++++++++ src/api/docs/content/specs/main.yaml | 6 +- src/api/ftl.c | 86 ++++------------------------ src/api/logs.c | 76 ++++++++++++++++++++++++ 7 files changed, 176 insertions(+), 79 deletions(-) create mode 100644 src/api/docs/content/specs/logs.yaml create mode 100644 src/api/logs.c diff --git a/src/api/CMakeLists.txt b/src/api/CMakeLists.txt index eaf95d85..1aaf6008 100644 --- a/src/api/CMakeLists.txt +++ b/src/api/CMakeLists.txt @@ -18,6 +18,7 @@ set(sources network.c history.c list.c + logs.c queries.c stats_database.c stats.c diff --git a/src/api/api.c b/src/api/api.c index 992cea68..7cced495 100644 --- a/src/api/api.c +++ b/src/api/api.c @@ -44,9 +44,9 @@ static struct { { "/api/groups", "/{name}", api_list, { false, false }, true, HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_DELETE }, { "/api/lists", "/{list}", api_list, { false, false }, true, HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_DELETE }, { "/api/ftl/client", "", api_ftl_client, { false, false }, false, HTTP_GET }, - { "/api/ftl/logs/dns", "", api_ftl_logs_dns, { false, false }, true, HTTP_GET }, { "/api/ftl/sysinfo", "", api_ftl_sysinfo, { false, false }, true, HTTP_GET }, { "/api/ftl/dbinfo", "", api_ftl_dbinfo, { false, false }, true, HTTP_GET }, + { "/api/logs/dnsmasq", "", api_logs_dnsmasq, { false, false }, true, HTTP_GET }, { "/api/history/clients", "", api_history_clients, { false, false }, true, HTTP_GET }, { "/api/history/database/clients", "", api_history_database_clients, { false, false }, true, HTTP_GET }, { "/api/history/database", "", api_history_database, { false, false }, true, HTTP_GET }, diff --git a/src/api/api.h b/src/api/api.h index 4f6b66d8..4560636c 100644 --- a/src/api/api.h +++ b/src/api/api.h @@ -47,13 +47,15 @@ int api_stats_database_upstreams(struct ftl_conn *api); // FTL methods int api_ftl_client(struct ftl_conn *api); -int api_ftl_logs_dns(struct ftl_conn *api); int api_ftl_dbinfo(struct ftl_conn *api); int api_ftl_sysinfo(struct ftl_conn *api); int get_ftl_obj(struct ftl_conn *api, cJSON *ftl, const bool is_locked); int get_system_obj(struct ftl_conn *api, cJSON *system); int api_config(struct ftl_conn *api); +// Log methods +int api_logs_dnsmasq(struct ftl_conn *api); + // Network methods int api_network_gateway(struct ftl_conn *api); int api_network_interfaces(struct ftl_conn *api); diff --git a/src/api/docs/content/specs/logs.yaml b/src/api/docs/content/specs/logs.yaml new file mode 100644 index 00000000..2c2d93bc --- /dev/null +++ b/src/api/docs/content/specs/logs.yaml @@ -0,0 +1,80 @@ +openapi: 3.0.2 +components: + paths: + logs: + dnsmasq: + get: + summary: Get DNS log content + tags: + - "FTL information" + operationId: "get_dns_log" + description: | + This API hook returns content from the log of the embedded DNS resolver `dnsmasq`. + + Every successful request will return a `nextID`. + This ID can be used on the next request to only get lines which were added *after* the last request. + This makes periodic polling for new log lines easy as no check for duplicated log lines is necessary. + The expected behavior for an immediate re-request of a log line with the same ID is an empty response. + As soon as the next message arrived, this will be included in your request and `nextID` is incremented by one. + parameters: + - $ref: 'logs.yaml#/components/parameters/logs/dnsmasq/nextID' + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: 'logs.yaml#/components/schemas/logs/dnsmasq/log' + - $ref: 'logs.yaml#/components/schemas/logs/dnsmasq/nextID' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: 'common.yaml#/components/errors/unauthorized' + schemas: + logs: + dnsmasq: + log: + type: object + properties: + log: + type: array + description: Request headers + items: + type: object + properties: + timestamp: + type: number + description: Unix timestamp of log line creation (server time) + message: + type: string + description: Log line content + example: + - timestamp: 1611729969.0 + message: "started, version pi-hole-2.84 cachesize 10000" + - timestamp: 1611729969.0 + message: "reading /etc/resolv.conf" + - timestamp: 1611729969.0 + message: "read /etc/hosts - 7 addresses" + - timestamp: 1611729969.0 + message: "query[A] connectivity-check.ubuntu.com from 127.0.0.1" + nextID: + type: object + properties: + nextID: + type: integer + description: next ID to query if checking for new log lines + example: 229 + parameters: + logs: + dnsmasq: + nextID: + in: query + description: (Optional) ID of next line to return + name: nextID + schema: + type: integer + required: false + example: 219 diff --git a/src/api/docs/content/specs/main.yaml b/src/api/docs/content/specs/main.yaml index 07385821..631a1c0d 100644 --- a/src/api/docs/content/specs/main.yaml +++ b/src/api/docs/content/specs/main.yaml @@ -144,15 +144,15 @@ paths: /ftl/client: $ref: 'ftl.yaml#/components/paths/client' - /ftl/logs/dns: - $ref: 'ftl.yaml#/components/paths/logs/dns' - /ftl/sysinfo: $ref: 'ftl.yaml#/components/paths/sysinfo' /ftl/dbinfo: $ref: 'ftl.yaml#/components/paths/dbinfo' + /logs/dnsmasq: + $ref: 'logs.yaml#/components/paths/logs/dnsmasq' + /endpoints: $ref: 'endpoints.yaml#/components/paths/endpoints' diff --git a/src/api/ftl.c b/src/api/ftl.c index affd42a5..594ffeed 100644 --- a/src/api/ftl.c +++ b/src/api/ftl.c @@ -8,34 +8,32 @@ * 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 "../webserver/http-common.h" -#include "../webserver/json_macros.h" -#include "api.h" -// struct fifologData -#include "../fifo.h" +#include "FTL.h" +#include "webserver/http-common.h" +#include "webserver/json_macros.h" +#include "api/api.h" // sysinfo() #include // get_blockingstatus() -#include "../setupVars.h" +#include "setupVars.h" // counters -#include "../shmem.h" +#include "shmem.h" // get_FTL_db_filesize() -#include "../files.h" +#include "files.h" // get_sqlite3_version() -#include "../database/common.h" +#include "database/common.h" // get_number_of_queries_in_DB() -#include "../database/query-table.h" +#include "database/query-table.h" // getgrgid() #include // config struct -#include "../config/config.h" +#include "config/config.h" // struct clientsData -#include "../datastructure.h" +#include "datastructure.h" // uname() #include // get_cpu_percentage() -#include "../daemon.h" +#include "daemon.h" // getProcessMemory() #include "procps.h" @@ -66,66 +64,6 @@ int api_ftl_client(struct ftl_conn *api) JSON_SEND_OBJECT(json); } -// fifologData is allocated in shared memory for cross-fork compatibility -fifologData *fifo_log = NULL; -int api_ftl_logs_dns(struct ftl_conn *api) -{ - unsigned int start = 0u; - if(api->request->query_string != NULL) - { - // Does the user request an ID to sent from? - unsigned int nextID; - if(get_uint_var(api->request->query_string, "nextID", &nextID)) - { - if(nextID >= fifo_log->next_id) - { - // Do not return any data - start = LOG_SIZE; - } - else if((fifo_log->next_id > LOG_SIZE) && nextID < (fifo_log->next_id) - LOG_SIZE) - { - // Requested an ID smaller than the lowest one we have - // We return the entire buffer - start = 0u; - } - else if(fifo_log->next_id >= LOG_SIZE) - { - // Reply with partial buffer, measure from the end - // (the log is full) - start = LOG_SIZE - (fifo_log->next_id - nextID); - } - else - { - // Reply with partial buffer, measure from the start - // (the log is not yet full) - start = nextID; - } - } - } - - // Process data - cJSON *json = JSON_NEW_OBJECT(); - cJSON *log = JSON_NEW_ARRAY(); - for(unsigned int i = start; i < LOG_SIZE; i++) - { - if(fifo_log->timestamp[i] < 1.0) - { - // Uninitialized buffer entry - break; - } - - cJSON *entry = JSON_NEW_OBJECT(); - JSON_ADD_NUMBER_TO_OBJECT(entry, "timestamp", fifo_log->timestamp[i]); - JSON_REF_STR_IN_OBJECT(entry, "message", fifo_log->message[i]); - JSON_ADD_ITEM_TO_ARRAY(log, entry); - } - JSON_ADD_ITEM_TO_OBJECT(json, "log", log); - JSON_ADD_NUMBER_TO_OBJECT(json, "nextID", fifo_log->next_id); - - // Send data - JSON_SEND_OBJECT(json); -} - int api_ftl_dbinfo(struct ftl_conn *api) { cJSON *json = JSON_NEW_OBJECT(); diff --git a/src/api/logs.c b/src/api/logs.c new file mode 100644 index 00000000..8b72a7dc --- /dev/null +++ b/src/api/logs.c @@ -0,0 +1,76 @@ +/* Pi-hole: A black hole for Internet advertisements +* (c) 2023 Pi-hole, LLC (https://pi-hole.net) +* Network-wide ad blocking via your own hardware. +* +* FTL Engine +* API Implementation /api/logs +* +* 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 "webserver/http-common.h" +#include "webserver/json_macros.h" +#include "api/api.h" +// struct fifologData +#include "fifo.h" + +// fifologData is allocated in shared memory for cross-fork compatibility +fifologData *fifo_log = NULL; +int api_logs_dnsmasq(struct ftl_conn *api) +{ + unsigned int start = 0u; + if(api->request->query_string != NULL) + { + // Does the user request an ID to sent from? + unsigned int nextID; + if(get_uint_var(api->request->query_string, "nextID", &nextID)) + { + if(nextID >= fifo_log->next_id) + { + // Do not return any data + start = LOG_SIZE; + } + else if((fifo_log->next_id > LOG_SIZE) && nextID < (fifo_log->next_id) - LOG_SIZE) + { + // Requested an ID smaller than the lowest one we have + // We return the entire buffer + start = 0u; + } + else if(fifo_log->next_id >= LOG_SIZE) + { + // Reply with partial buffer, measure from the end + // (the log is full) + start = LOG_SIZE - (fifo_log->next_id - nextID); + } + else + { + // Reply with partial buffer, measure from the start + // (the log is not yet full) + start = nextID; + } + } + } + + // Process data + cJSON *json = JSON_NEW_OBJECT(); + cJSON *log = JSON_NEW_ARRAY(); + for(unsigned int i = start; i < LOG_SIZE; i++) + { + if(fifo_log->timestamp[i] < 1.0) + { + // Uninitialized buffer entry + break; + } + + cJSON *entry = JSON_NEW_OBJECT(); + JSON_ADD_NUMBER_TO_OBJECT(entry, "timestamp", fifo_log->timestamp[i]); + JSON_REF_STR_IN_OBJECT(entry, "message", fifo_log->message[i]); + JSON_ADD_ITEM_TO_ARRAY(log, entry); + } + JSON_ADD_ITEM_TO_OBJECT(json, "log", log); + JSON_ADD_NUMBER_TO_OBJECT(json, "nextID", fifo_log->next_id); + + // Send data + JSON_SEND_OBJECT(json); +}