Implement ometric_set_timeval() and ometric_set_timeval_with_labels()
authorclaudio <claudio@openbsd.org>
Tue, 6 Dec 2022 11:27:58 +0000 (11:27 +0000)
committerclaudio <claudio@openbsd.org>
Tue, 6 Dec 2022 11:27:58 +0000 (11:27 +0000)
Timestamps are special since they can require more significant bits
than a double provides. Instead print them as pseudo float as suggested
by the OpenMetrics draft.
OK cheloha@

usr.sbin/bgpctl/ometric.c
usr.sbin/bgpctl/ometric.h
usr.sbin/bgpctl/output_ometric.c

index 296c080..c7fd626 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ometric.c,v 1.5 2022/12/05 11:50:11 claudio Exp $ */
+/*     $OpenBSD: ometric.c,v 1.6 2022/12/06 11:27:58 claudio Exp $ */
 
 /*
  * Copyright (c) 2022 Claudio Jeker <claudio@openbsd.org>
@@ -17,6 +17,7 @@
  */
 
 #include <sys/queue.h>
+#include <sys/time.h>
 
 #include <err.h>
 #include <stdarg.h>
@@ -42,6 +43,7 @@ struct olabels {
 enum ovalue_type {
        OVT_INTEGER,
        OVT_DOUBLE,
+       OVT_TIMEVAL,
 };
 
 struct ovalue {
@@ -50,6 +52,7 @@ struct ovalue {
        union {
                unsigned long long      i;
                double                  f;
+               struct timeval          tv;
        }                        value;
        enum ovalue_type         valtype;
 };
@@ -274,6 +277,9 @@ ometric_output_value(FILE *out, const struct ovalue *ov)
                return fprintf(out, "%llu", ov->value.i);
        case OVT_DOUBLE:
                return fprintf(out, "%g", ov->value.f);
+       case OVT_TIMEVAL:
+               return fprintf(out, "%lld.%06ld",
+                   (long long)ov->value.tv.tv_sec, (long)ov->value.tv.tv_usec);
        }
        return -1;
 }
@@ -365,6 +371,28 @@ ometric_set_float(struct ometric *om, double val, struct olabels *ol)
        STAILQ_INSERT_TAIL(&om->vals, ov, entry);
 }
 
+/*
+ * Set an timeval value with label ol. ol can be NULL.
+ */
+void
+ometric_set_timeval(struct ometric *om, const struct timeval *tv,
+    struct olabels *ol)
+{
+       struct ovalue *ov;
+
+       if (om->type != OMT_GAUGE)
+               errx(1, "%s incorrect ometric type", __func__);
+
+       if ((ov = malloc(sizeof(*ov))) == NULL)
+               err(1, NULL);
+
+       ov->value.tv = *tv;
+       ov->valtype = OVT_TIMEVAL;
+       ov->labels = olabels_ref(ol);
+
+       STAILQ_INSERT_TAIL(&om->vals, ov, entry);
+}
+
 /*
  * Add an info value (which is the value 1 but with extra key-value pairs).
  */
@@ -424,3 +452,14 @@ ometric_set_int_with_labels(struct ometric *om, uint64_t val,
        ometric_set_int(om, val, extra);
        olabels_free(extra);
 }
+
+void
+ometric_set_timeval_with_labels(struct ometric *om, struct timeval *tv,
+    const char **keys, const char **values, struct olabels *ol)
+{
+       struct olabels *extra;
+
+       extra = olabels_add_extras(ol, keys, values);
+       ometric_set_timeval(om, tv, extra);
+       olabels_free(extra);
+}
index bd90f2d..0e66857 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ometric.h,v 1.3 2022/12/01 09:14:40 claudio Exp $ */
+/*     $OpenBSD: ometric.h,v 1.4 2022/12/06 11:27:58 claudio Exp $ */
 
 /*
  * Copyright (c) 2022 Claudio Jeker <claudio@openbsd.org>
@@ -41,9 +41,13 @@ int           ometric_output_all(FILE *);
 /* functions to set gauge and counter metrics */
 void   ometric_set_int(struct ometric *, uint64_t, struct olabels *);
 void   ometric_set_float(struct ometric *, double, struct olabels *);
+void   ometric_set_timeval(struct ometric *, const struct timeval *,
+           struct olabels *);
 void   ometric_set_info(struct ometric *, const char **, const char **,
            struct olabels *); 
 void   ometric_set_state(struct ometric *, const char *, struct olabels *); 
 void   ometric_set_int_with_labels(struct ometric *, uint64_t, const char **,
            const char **, struct olabels *);
+void   ometric_set_timeval_with_labels(struct ometric *, struct timeval *,
+           const char **, const char **, struct olabels *);
 #define OKV(...)               (const char *[]){ __VA_ARGS__, NULL }
index ba016f1..b9572a0 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: output_ometric.c,v 1.6 2022/12/01 09:16:43 claudio Exp $ */
+/*     $OpenBSD: output_ometric.c,v 1.7 2022/12/06 11:27:58 claudio Exp $ */
 
 /*
  * Copyright (c) 2022 Claudio Jeker <claudio@openbsd.org>
@@ -319,15 +319,11 @@ static void
 ometric_tail(void)
 {
        struct timeval elapsed_time;
-       double scrape;
 
        gettimeofday(&end_time, NULL);
        timersub(&end_time, &start_time, &elapsed_time);
 
-       scrape = (double)elapsed_time.tv_sec +
-           (double)elapsed_time.tv_usec / 1000000;
-
-       ometric_set_float(bgpd_scrape_time, scrape, NULL);
+       ometric_set_timeval(bgpd_scrape_time, &elapsed_time, NULL);
        ometric_output_all(stdout);
 
        ometric_free_all();