[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 10/23] implemented uptime %


MIME-Version: 1.0
Content-Transfer-Encoding: 8bit

From: arf20 <aruizfernandez05@xxxxxxxxx>

---
 main.c    |   1 +
 monitor.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 monitor.h |   1 +
 3 files changed, 99 insertions(+), 9 deletions(-)

diff --git a/main.c b/main.c
index 8c0405f..197d1b2 100644
--- a/main.c
+++ b/main.c
@@ -101,6 +101,7 @@ int main() {
 
     while (1) {
         monitor_check();
+        monitor_update_events();
         sleep(5);
     }
 }
diff --git a/monitor.c b/monitor.c
index 2c81be5..573f200 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4,6 +4,7 @@
 #include <string.h>
 #include <errno.h>
 #include <time.h>
+#include <ctype.h>
 
 #include <curl/curl.h>
 
@@ -63,13 +64,23 @@ static char timestr[256];
 
 
 static void
-target_events_push(target_t *target, event_t event)
+target_events_push_ordered(target_t *target, const event_t *event)
 {
     if (target->events_size + 1 > target->events_capacity)
         target->events = realloc(target->events,
             2 * sizeof(event_t) * target->events_capacity);
 
-    target->events[target->events_size++] = event;
+    size_t i = 0;
+    while (target->events[i].time < event->time
+            && i < target->events_size)
+        i++;
+    /* incidents[i].started_time >= incident.started_time */
+    memmove(&target->events[i + 1], &target->events[i],
+        (target->events_size - i) * sizeof(event_t));
+
+    target->events[i] = *event;
+
+    target->events_size++;
 }
 
 static void
@@ -132,7 +143,7 @@ target_events_load(target_t *target, const char *logbuff)
             strcmp(status, "up") == 0 ? STATUS_UP : STATUS_DOWN
         };
 
-        target_events_push(target, event);
+        target_events_push_ordered(target, &event);
 
         n++;
     }
@@ -158,7 +169,9 @@ incidents_render()
                 resolved = 0;
 
             time_t start = targets[i].events[j].time;
-            time_t duration = targets[i].events[j + 1].time - start;
+            time_t duration = resolved ?
+                targets[i].events[j + 1].time - start :
+                time(NULL) - start;
 
             snprintf(buff, 256, "%ldh %ldm %lds", duration / 3600,
                 (duration / 60) % 60, duration % 60);
@@ -300,6 +313,49 @@ target_uptime(const target_t *target)
     return buff;
 }
 
+float
+target_perc_uptime_since(const target_t *target, time_t since)
+{
+    time_t downtime = 0;
+
+    if (since < target->events[0].time)
+        downtime += target->events[0].time - since;
+
+    for (size_t i = 0; i < incidents_size; i++) {
+        if (strcmp(incidents[i].service, target->name) != 0)
+            continue;
+
+        if (incidents[i].started_time + incidents[i].duration_time < since)
+            continue;
+
+        time_t clamped_duration = incidents[i].duration_time;
+        if (incidents[i].started_time < since)
+            clamped_duration -= since - incidents[i].started_time;
+
+        downtime += clamped_duration;
+    }
+
+    return 100.0f * (1.0f - ((float)downtime / (float)(time(NULL) - since)));
+}
+
+float
+target_perc_uptime_total(const target_t *target)
+{
+    time_t downtime = 0, since = 0;
+
+    for (size_t i = 0; i < incidents_size; i++) {
+        if (strcmp(incidents[i].service, target->name) != 0)
+            continue;
+
+        if (since == 0)
+            since = incidents[i].started_time;
+
+        downtime += incidents[i].duration_time;
+    }
+
+    return 100.0f * (1.0f - ((float)downtime / (float)(time(NULL) - since)));
+}
+
 const char *
 monitor_generate_status_html()
 {
@@ -314,13 +370,13 @@ monitor_generate_status_html()
 
     for (size_t i = 0; i < targets_n; i++) {
         pos += snprintf(pos, BUFF_SIZE - (pos - buff),
-            "<tr><td>%s</td><td>%s</td>%s<td>%s</td><td>%s</td><td>%s</td></tr>\n",
+            "<tr><td>%s</td><td>%s</td>%s<td>%s</td><td>%f</td><td>%f</td></tr>\n",
             type_str[targets[i].type],          /* type */
             targets[i].target,                  /* target */
             status_html[targets[i].status],     /* status */
             target_uptime(&targets[i]),         /* uptime */
-            "",                                 /* %up month */
-            ""                                  /* %up total */
+            target_perc_uptime_since(&targets[i], time(NULL) - (30*24*3600)),
+            target_perc_uptime_total(&targets[i])
         );
     }
 
@@ -392,8 +448,8 @@ check_dns(const char *name)
     fread(cmd_out, 256, 1, pf);
     pclose(pf);
     
-    if (*cmd_out == '\0') {
-        printf("no a\n");
+    if (*cmd_out == '\0' || !isdigit(*cmd_out)) {
+        printf("no a: %s\n", cmd_out);
         return STATUS_DOWN;
     }
     
@@ -464,3 +520,35 @@ monitor_check()
     check_num++;
 }
 
+void
+monitor_update_events()
+{
+    static char *status_str[] = {
+        "down",
+        "up"
+    };
+
+    time_t time_now = time(NULL);
+    struct tm *tm_now = gmtime(&time_now);
+    strftime(timestr, 256, "%Y-%m-%d %H:%M:%S", tm_now);
+
+    for (size_t i = 0; i < targets_n; i++) {
+        if (targets[i].events_size > 0 && (
+            targets[i].status ==
+            targets[i].events[targets[i].events_size - 1].status))
+        {
+            continue;
+        }
+
+        event_t event = {
+            time_now,
+            STATUS_UP
+        };
+
+        target_events_push_ordered(&targets[i], &event);
+
+        printf("[%s] [monitor] %s is now %s\n",
+            timestr, targets[i].name, status_str[targets[i].status]);
+    }
+}
+
diff --git a/monitor.h b/monitor.h
index 8c2529e..198908e 100644
--- a/monitor.h
+++ b/monitor.h
@@ -5,5 +5,6 @@ int monitor_init(const char *cfg_file, const char *log_file);
 const char *monitor_generate_status_html();
 const char *monitor_generate_incidents_html();
 void monitor_check();
+void monitor_update_events();
 
 #endif /* _MONITOR_H */
-- 
2.47.3


References:
[arfnet2-status PATCH 00/23] First releasearf20 <arf20@xxxxxxxxx>