From 5d3d36a8fa534e9144a0c369467231a196c2c8df Mon Sep 17 00:00:00 2001 From: root Date: Sat, 27 Aug 2022 20:53:25 +0200 Subject: [PATCH 1/2] json --- hosts_db.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++-- hosts_db.h | 2 +- http.c | 6 +++ 3 files changed, 109 insertions(+), 5 deletions(-) diff --git a/hosts_db.c b/hosts_db.c index c1dab21..291a55b 100644 --- a/hosts_db.c +++ b/hosts_db.c @@ -1217,6 +1217,99 @@ static const unsigned char static void text_metrics_counter(struct str *buf, const char *metric, const char *type, const char *help); static void text_metrics_format_host(const struct bucket *b, const void *user_data); +static void text_json_format_host(const struct bucket *b, const void *user_data); + + + + +/* --------------------------------------------------------------------------- + * Web interface: export stats in JSON text format on /json + */ +struct str * +text_json() +{ + struct str *buf = str_make(); + str_append(buf, "["); + + hashtable_foreach(hosts_db, &text_json_format_host, (void *)buf); + + size_t len; + char *con; + str_extract(buf, &len, &con); + con[len-1] = '\0'; + + struct str *buf2 = str_make(); + str_append(buf2, con); + + str_append(buf2, "]"); + return buf2; +} + +static void +text_json_format_host(const struct bucket *b, + const void *user_data) +{ + struct str *buf = (struct str *)user_data; + + + const char *ip = addr_to_str(&(b->u.host.addr)); + + str_appendf(buf, + "{" + "\"ip\":\"%s\"," + "\"hostname\":\"%s\",", + ip, + (b->u.host.dns == NULL) ? "" : b->u.host.dns); + + if (hosts_db_show_macs) + str_appendf(buf, + "\"mac\":\"%x:%x:%x:%x:%x:%x\",", + b->u.host.mac_addr[0], + b->u.host.mac_addr[1], + b->u.host.mac_addr[2], + b->u.host.mac_addr[3], + b->u.host.mac_addr[4], + b->u.host.mac_addr[5]); + + str_appendf(buf, + "\"in\": %qu," + "\"out\": %qu," + "\"total\": %qu,", + (qu)b->in, + (qu)b->out, + (qu)b->total); + + if (opt_want_lastseen) { + int64_t last = b->u.host.last_seen_mono; + int64_t now = (int64_t)now_mono(); + struct str *last_str = NULL; + + if ((now >= last) && (last != 0)) + last_str = length_of_time(now - last); + + str_append(buf, "\"lastSeen\": "); + if (last_str == NULL) { + if (last == 0) + str_append(buf, "\"(never)\""); + else + str_appendf(buf, "\"(clock error: last = %qd, now = %qu)\"", + (qd)last, + (qu)now); + } else { + str_append(buf, "\""); + str_appendstr(buf, last_str); + str_append(buf, "\""); + str_free(last_str); + } + } + + str_appendf(buf, "},"); + + /* Only resolve hosts "on demand" */ + if (b->u.host.dns == NULL) + dns_queue(&(b->u.host.addr)); + +} /* --------------------------------------------------------------------------- * Web interface: export stats in Prometheus text format on /metrics @@ -1247,11 +1340,16 @@ text_metrics_counter(struct str *buf, static void text_metrics_format_host_key(struct str *buf, const struct bucket *b) { - const char *ip = addr_to_str(&(b->u.host.addr)); + const char *ip = addr_to_str(&(b->u.host.addr)); - str_appendf(buf, - "host_bytes_total{interface=\"%s\",ip=\"%s\"", - title_interfaces, ip); + if (b->u.host.dns == NULL) + dns_queue(&(b->u.host.addr)); + + //char *hostname = (b->u.host.dns == NULL) ? "" : b->u.host.dns; + + str_appendf(buf, + "host_bytes_total{interface=\"%s\",hostname=\"%s\",ip=\"%s\"", + title_interfaces, (b->u.host.dns == NULL) ? "" : b->u.host.dns, ip); if (hosts_db_show_macs) str_appendf(buf, ",mac=\"%x:%x:%x:%x:%x:%x\"", diff --git a/hosts_db.h b/hosts_db.h index ffb6a03..1bed30f 100644 --- a/hosts_db.h +++ b/hosts_db.h @@ -78,7 +78,7 @@ struct bucket *host_get_ip_proto(struct bucket *host, const uint8_t proto); /* Web pages. */ struct str *html_hosts(const char *uri, const char *query); struct str *text_metrics(); - +struct str *text_json(); /* From hosts_sort */ void qsort_buckets(const struct bucket **a, size_t n, size_t left, size_t right, const enum sort_dir d); diff --git a/http.c b/http.c index 7ba7e47..76cde9c 100644 --- a/http.c +++ b/http.c @@ -43,6 +43,7 @@ static int http_base_len = 0; static const char mime_type_xml[] = "text/xml"; static const char mime_type_html[] = "text/html; charset=us-ascii"; static const char mime_type_text_prometheus[] = "text/plain; version=0.0.4"; +static const char mime_type_text_json[] = "application/json"; static const char mime_type_css[] = "text/css"; static const char mime_type_js[] = "text/javascript"; static const char mime_type_png[] = "image/png"; @@ -694,6 +695,11 @@ static void process_get(struct connection *conn) str_extract(buf, &(conn->reply_length), &(conn->reply)); conn->mime_type = mime_type_text_prometheus; } + else if (str_starts_with(safe_url, "/json")) { + struct str *buf = text_json(); + str_extract(buf, &(conn->reply_length), &(conn->reply)); + conn->mime_type = mime_type_text_json; + } else if (strcmp(safe_url, "/style.css") == 0) static_style_css(conn); else if (strcmp(safe_url, "/graph.js") == 0) From 86ada133c8888dc528a9d701f26efc5624be9db1 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 3 Sep 2022 20:17:10 +0200 Subject: [PATCH 2/2] added total metric to Prometheus Metrics --- hosts_db.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hosts_db.c b/hosts_db.c index 291a55b..f0f85cb 100644 --- a/hosts_db.c +++ b/hosts_db.c @@ -1372,6 +1372,10 @@ text_metrics_format_host(const struct bucket *b, text_metrics_format_host_key(buf, b); str_appendf(buf, ",dir=\"out\"} %qu\n", (qu)b->out); + + text_metrics_format_host_key(buf, b); + str_appendf(buf, ",dir=\"total\"} %qu\n", (qu)b->in + b->out); + } /* ---------------------------------------------------------------------------