It can be sometimes interesting to have a timestamp with
a resolution of less than a second. It is currently painful
to obtain this, because concatenation of date and date_us lead
to a shorter timestamp during the first 100ms of a second, which
is not parseable and needs ugly ACLs in configuration to prepend
0s when needed.
To improve this, add an optional <unit> parameter to date sample.
This allows to have milliseconds or microseconds appended to
timestamp with the correct length.
---
doc/configuration.txt | 8 +++++++-
src/sample.c | 20 ++++++++++++++++++--
2 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/doc/configuration.txt b/doc/configuration.txt
index d8e1b57f1..12c54e6be 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -14151,7 +14151,7 @@ cpu_ns_tot : integer
high cpu_calls count, for example when processing many HTTP chunks, and for
this reason it is often preferred to log cpu_ns_avg instead.
-date([<offset>]) : integer
+date([<offset>, <unit>]) : integer
Returns the current date as the epoch (number of seconds since 01/01/1970).
If an offset value is specified, then it is a number of seconds that is added
to the current date before returning the value. This is particularly useful
@@ -14163,6 +14163,12 @@ date([<offset>]) : integer
# set an expires header to now+1 hour in every response
http-response set-header Expires %[date(3600),http_date]
+ <unit> is facultative, and can be set to "ms" for milliseconds or "us" for
+ microseconds. Default unit is seconds.
+ If <unit> is set, microseconds or milliseconds of current date sample are
+ appended to timestamp. This is useful when a time resolution of less than
+ a second is needed.
+
date_us : integer
Return the microseconds part of the date (the "second" part is returned by
date sample). This sample is coherent with the date sample as it is comes
diff --git a/src/sample.c b/src/sample.c
index 98b5d573f..1f6c925d3 100644
--- a/src/sample.c
+++ b/src/sample.c
@@ -2941,7 +2941,7 @@ smp_fetch_env(const struct arg *args, struct sample *smp,
const char *kw, void *
}
/* retrieve the current local date in epoch time, and applies an optional
offset
- * of args[0] seconds.
+ * of args[0] seconds. Add milli/microseconds if asked to in args[1].
*/
static int
smp_fetch_date(const struct arg *args, struct sample *smp, const char *kw,
void *private)
@@ -2954,6 +2954,22 @@ smp_fetch_date(const struct arg *args, struct sample
*smp, const char *kw, void
smp->data.type = SMP_T_SINT;
smp->flags |= SMP_F_VOL_TEST | SMP_F_MAY_CHANGE;
+
+ if (!args || args[1].type != ARGT_STR)
+ return 1;
+
+ /* add milliseconds if needed */
+ if (strcmp(args[1].data.str.area, "ms") == 0) {
+ smp->data.u.sint *= 1000;
+ smp->data.u.sint += (date.tv_usec + 500) / 1000;
+ }
+
+ /* add microseconds if needed */
+ else if (strcmp(args[1].data.str.area, "us") == 0) {
+ smp->data.u.sint *= 1000000;
+ smp->data.u.sint += date.tv_usec;
+ }
+
return 1;
}
@@ -3259,7 +3275,7 @@ static struct sample_fetch_kw_list smp_kws = {ILH, {
{ "always_false", smp_fetch_false, 0, NULL, SMP_T_BOOL,
SMP_USE_INTRN },
{ "always_true", smp_fetch_true, 0, NULL, SMP_T_BOOL,
SMP_USE_INTRN },
{ "env", smp_fetch_env, ARG1(1,STR), NULL, SMP_T_STR,
SMP_USE_INTRN },
- { "date", smp_fetch_date, ARG1(0,SINT), NULL, SMP_T_SINT,
SMP_USE_INTRN },
+ { "date", smp_fetch_date, ARG2(0,SINT,STR), NULL, SMP_T_SINT,
SMP_USE_INTRN },
{ "date_us", smp_fetch_date_us, 0, NULL, SMP_T_SINT,
SMP_USE_INTRN },
{ "hostname", smp_fetch_hostname, 0, NULL, SMP_T_STR,
SMP_USE_INTRN },
{ "nbproc", smp_fetch_nbproc,0, NULL, SMP_T_SINT,
SMP_USE_INTRN },
--
2.20.1