From 287b4af722b7ec089645cf9cd75233c6c90908cf Mon Sep 17 00:00:00 2001 From: arf20 Date: Mon, 20 Oct 2025 23:18:26 +0200 Subject: HTTP monitoring --- Makefile | 2 +- README.md | 8 +++++++ main.c | 16 +++++++++---- monitor | Bin 29912 -> 52712 bytes monitor.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 97 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index bc05321..11226e7 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC = gcc CFLAGS = -g -Wall -pedantic -LDFLAGS = -lmicrohttpd +LDFLAGS = -lmicrohttpd -lcurl BIN = monitor SRC = main.c monitor.c diff --git a/README.md b/README.md index a373746..19a4a5b 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,14 @@ ARFNET Status Monitor +## Building + +Depends on libmicrohttpd, libcurl + +``` +make +``` + ## Features (TODO) - Current service status table diff --git a/main.c b/main.c index f01d928..15379b3 100644 --- a/main.c +++ b/main.c @@ -1,16 +1,18 @@ #include #include #include - #include #include -#include - #include #include #include #include +#include + +#include + + #include "monitor.h" @@ -35,7 +37,13 @@ enum MHD_Result answer_to_connection( (const struct sockaddr_in**)MHD_get_connection_info( connection, MHD_CONNECTION_INFO_CLIENT_ADDRESS); - printf("%s - %s %s: ", inet_ntoa((*coninfo)->sin_addr), method, url); + time_t time_now = time(NULL); + struct tm *tm_now = gmtime(&time_now); + static char timestr[256]; + strftime(timestr, 256, "%Y-%m-%d %H-%M-%S", tm_now); + + printf("[%s] [webserver] %s %s %s: ", + timestr, inet_ntoa((*coninfo)->sin_addr), method, url); struct MHD_Response *response; int ret; diff --git a/monitor b/monitor index 3992ddc..9c88a54 100755 Binary files a/monitor and b/monitor differ diff --git a/monitor.c b/monitor.c index c9903ce..e86154b 100644 --- a/monitor.c +++ b/monitor.c @@ -2,6 +2,9 @@ #include #include #include +#include + +#include #include "monitor.h" @@ -24,9 +27,20 @@ typedef struct { status_t status; } target_t; + static target_t targets[256]; static size_t target_n = 0; +static CURL *curl; + +static char timestr[256]; + +static size_t +write_data(void *ptr, size_t size, size_t nmemb, void *stream) +{ + return size * nmemb; +} + int monitor_init(const char *cfg_file) { FILE *cfgf = fopen(cfg_file, "r"); @@ -42,6 +56,8 @@ monitor_init(const char *cfg_file) { if (*line == '#' || *line == '\n') continue; + line[strlen(line) - 1] = '\0'; /* strip \n */ + char *type = line; char *target = strchr(line, '='); if (!target) { @@ -49,7 +65,6 @@ monitor_init(const char *cfg_file) { continue; } - *target = '\0'; target++; @@ -63,7 +78,7 @@ monitor_init(const char *cfg_file) { targets[target_n].target = strdup(target); targets[target_n].status = STATUS_DOWN; - printf("\t%s: %s", type_str[targets[target_n].type], + printf("\t%s: %s\n", type_str[targets[target_n].type], targets[target_n].target); target_n++; @@ -71,6 +86,22 @@ monitor_init(const char *cfg_file) { fclose(cfgf); + CURLcode res = curl_global_init(CURL_GLOBAL_ALL); + if (res) { + fprintf(stderr, "Error initializing cURL: %s\n", + curl_easy_strerror(res)); + return -1; + } + + curl = curl_easy_init(); + if (!curl) { + fprintf(stderr, "Error allocating cURL handle\n"); + return -1; + } + + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); + return 0; } @@ -97,9 +128,52 @@ monitor_generate_status_html() return buff; } +static int +check_reach(const char *endpoint) +{ + return STATUS_DOWN; +} + +static int +check_dns(const char *endpoint) +{ + return STATUS_DOWN; +} + +static int +check_http(const char *endpoint) +{ + curl_easy_setopt(curl, CURLOPT_URL, endpoint); + CURLcode curl_code = curl_easy_perform(curl); + if (curl_code != CURLE_OK) { + printf("[%s] [monitor] check http: %s: curl_easy_perform() failed: %s\n", + timestr, endpoint, curl_easy_strerror(curl_code)); + return STATUS_DOWN; + } + + long http_code; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); + + printf("[%s] [monitor] check http: %s: %ld\n", + timestr, endpoint, http_code); + + return STATUS_UP; +} + void monitor_check() { + time_t time_now = time(NULL); + struct tm *tm_now = gmtime(&time_now); + strftime(timestr, 256, "%Y-%m-%d %H-%M-%S", tm_now); + + static const int (*check_funcs[])(const char *) = { + check_reach, + check_dns, + check_http + }; + for (size_t i = 0; i < target_n; i++) + targets[i].status = check_funcs[targets[i].type](targets[i].target); } -- cgit v1.2.3