On Tue, Dec 06, 2022 at 12:01:57PM +0100, Claudio Jeker wrote:
> Printing timestamps is rather common thing in OpenMetrics so add a native
> function for this. The benefit is that it prints the timestamp as pseudo
> float with higher precision than a regular float.

This part makes sense to me and is ok

> Also adjust output of doubles to include enough significant digits to
> print the value in full precision.

Not sure. %.17g seems too much as things with reasonable precision like
f = 0.1 will now be printed as

0.10000000000000001,

which is wrong. If you think the default .6 is not enough and want to
crank the precision to .9 or even .12, I'm ok with that (I'd keep it
at a multiple of 3).

> -- 
> :wq Claudio
> 
> Index: ometric.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpctl/ometric.c,v
> retrieving revision 1.5
> diff -u -p -r1.5 ometric.c
> --- ometric.c 5 Dec 2022 11:50:11 -0000       1.5
> +++ ometric.c 6 Dec 2022 10:55:51 -0000
> @@ -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;
>  };
> @@ -273,7 +276,10 @@ ometric_output_value(FILE *out, const st
>       case OVT_INTEGER:
>               return fprintf(out, "%llu", ov->value.i);
>       case OVT_DOUBLE:
> -             return fprintf(out, "%g", ov->value.f);
> +             return fprintf(out, "%.17g", ov->value.f);
> +     case OVT_TIMEVAL:
> +             return fprintf(out, "%lld.%06d", (long long)ov->value.tv.tv_sec,
> +                 (int)ov->value.tv.tv_usec);
>       }
>       return -1;
>  }
> @@ -366,6 +372,28 @@ ometric_set_float(struct ometric *om, do
>  }
>  
>  /*
> + * 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).
>   */
>  void
> @@ -422,5 +450,16 @@ ometric_set_int_with_labels(struct ometr
>  
>       extra = olabels_add_extras(ol, keys, values);
>       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: ometric.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpctl/ometric.h,v
> retrieving revision 1.3
> diff -u -p -r1.3 ometric.h
> --- ometric.h 1 Dec 2022 09:14:40 -0000       1.3
> +++ ometric.h 6 Dec 2022 10:53:12 -0000
> @@ -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: output_ometric.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpctl/output_ometric.c,v
> retrieving revision 1.6
> diff -u -p -r1.6 output_ometric.c
> --- output_ometric.c  1 Dec 2022 09:16:43 -0000       1.6
> +++ output_ometric.c  6 Dec 2022 10:55:02 -0000
> @@ -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();
> 

Reply via email to