Skip to content

High resolution time format

Florian Forster edited this page Nov 26, 2023 · 1 revision

The high resolution time format is a representation of time used internally to store the time at which a value was collected and the interval in which it is collected. The format allows statistics to be collected at arbitrary intervals instead of forcing one second steps. It was introduced in Version-5.0.

The time is stored using the type cdtime_t which is defined in src/collectd.h. Macros for converting to and from this type are available from src/utils_time.h, as well as a function returning the current wall-clock time, cdtime().

The type cdtime_t is a 64-bit unsigned integer. The time is stored in 2–30 seconds, i.e. in 0.00000000093132257461 second steps. This means that you can convert seconds (i.e. time_t) to cdtime_t using a 30-bit left shift. You can convert back using a 30-bit right shift. Please use the conversion macros defined in src/utils_time.h though, for example TIME_T_TO_CDTIME_T().

At first glance, the maximum resolution may seem unusual. It was chosen for two reasons:

  1. The resolution is very close to the nanosecond resolution used by the standard struct timespec.
  2. Calculating time differences is as simple as subtracting two cdtime_t from one another.

Using an integer instead of a structure makes it a lot easier to compare two times.

Printing

The preferred method of printing a cdtime_t value is by converting it to a double and using the %.3f format:

 cdtime_t now;

 now = cdtime ();
 printf ("The current time is: %.3f\n",
     CDTIME_T_TO_DOUBLE (now));

Configuration

When reading a time value from the configuration, please use the cf_util_get_cdtime() function from src/configfile.h. For example:

 /* const oconfig_item_t *ci; */
 cdtime_t tmp = 0;
 int status;

 status = cf_util_get_cdtime (ci, &tmp);
 if (status != 0)
   tmp = DEFAULT_VALUE;

Parsing

If you need to read a time value from the user, for example when using the plain-text-protocol, expect a floating point number and convert that to cdtime_t:

 /* const char *str; */
 char *endptr = str;
 double tmp_d;
 cdtime_t tmp_t;

 errno = 0;
 tmp_d = strtod (str, &endptr);
 if ((errno != 0)
     || (endptr == str)
     || (endptr == NULL) /* avoid NULL dereference */
     || (*endptr != 0) /* trailing characters */
     || !isfinite (tmp_d)
     || (tmp_d < 0.0))
   ERROR;
 tmp_t = DOUBLE_TO_CDTIME_T (tmp_d);
Clone this wiki locally