From: Willy Tarreau Date: Fri, 29 Jan 2021 09:47:52 +0000 (+0100) Subject: MINOR: tools: add print_time_short() to print a condensed duration value X-Git-Tag: v2.4-dev7~65 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4deeb1055f8f7e3feec195233f1ad3b3bf90accb;p=thirdparty%2Fhaproxy.git MINOR: tools: add print_time_short() to print a condensed duration value When reporting some values in debugging output we often need to have some condensed, stable-length values. This function prints a duration from nanosecond to years with at least 4 digits of accuracy using the most suitable unit, always on 7 chars. --- diff --git a/include/haproxy/tools.h b/include/haproxy/tools.h index 5be00b7fcb..4e3e4af980 100644 --- a/include/haproxy/tools.h +++ b/include/haproxy/tools.h @@ -790,6 +790,7 @@ int parse_http_date(const char *date, int len, struct tm *tm); int parse_imf_date(const char *date, int len, struct tm *tm); int parse_rfc850_date(const char *date, int len, struct tm *tm); int parse_asctime_date(const char *date, int len, struct tm *tm); +int print_time_short(struct buffer *out, const char *pfx, uint64_t ns, const char *sfx); /* Dynamically allocates a string of the proper length to hold the formatted * output. NULL is returned on error. The caller is responsible for freeing the diff --git a/src/tools.c b/src/tools.c index 19b612250e..f2f456fc2a 100644 --- a/src/tools.c +++ b/src/tools.c @@ -3817,6 +3817,44 @@ int parse_http_date(const char *date, int len, struct tm *tm) return 0; } +/* print the time in a short form (exactly 7 chars) at the end of buffer + * . "-" is printed if the value is zero, "inf" if larger than 1000 years. + * It returns the new buffer length, or 0 if it doesn't fit. The value will be + * surrounded by and respectively if not NULL. + */ +int print_time_short(struct buffer *out, const char *pfx, uint64_t ns, const char *sfx) +{ + double val = ns; // 52 bits of mantissa keep ns accuracy over 52 days + const char *unit; + + if (!pfx) + pfx = ""; + if (!sfx) + sfx = ""; + + do { + unit = " - "; if (val <= 0.0) break; + unit = "ns"; if (val < 1000.0) break; + unit = "us"; val /= 1000.0; if (val < 1000.0) break; + unit = "ms"; val /= 1000.0; if (val < 1000.0) break; + unit = "s "; val /= 1000.0; if (val < 60.0) break; + unit = "m "; val /= 60.0; if (val < 60.0) break; + unit = "h "; val /= 60.0; if (val < 24.0) break; + unit = "d "; val /= 24.0; if (val < 365.0) break; + unit = "yr"; val /= 365.0; if (val < 1000.0) break; + unit = " inf "; val = 0.0; break; + } while (0); + + if (val <= 0.0) + return chunk_appendf(out, "%s%7s%s", pfx, unit, sfx); + else if (val < 10.0) + return chunk_appendf(out, "%s%1.3f%s%s", pfx, val, unit, sfx); + else if (val < 100.0) + return chunk_appendf(out, "%s%2.2f%s%s", pfx, val, unit, sfx); + else + return chunk_appendf(out, "%s%3.1f%s%s", pfx, val, unit, sfx); +} + /* Dynamically allocates a string of the proper length to hold the formatted * output. NULL is returned on error. The caller is responsible for freeing the * memory area using free(). The resulting string is returned in if the