#include <haproxy/api.h>
#include <haproxy/buf.h>
#include <haproxy/chunk.h>
+#include <haproxy/clock.h>
#include <haproxy/errors.h>
#include <haproxy/global.h>
#include <haproxy/guid.h>
#include <haproxy/proxy-t.h>
#include <haproxy/server-t.h>
#include <haproxy/stats.h>
+#include <haproxy/time.h>
/* Dump all fields from <stats> into <out> for stats-file. */
int stats_dump_fields_file(struct buffer *out,
value.u.u64 = read_uint64(&ptr, istend(token));
break;
+ case FF_S32:
case FF_U32:
value.u.u32 = read_uint(&ptr, istend(token));
break;
else if (fn == FN_RATE && ff == FF_U32) {
preload_freq_ctr(counter, value.u.u32);
}
+ else if (fn == FN_AGE && (ff == FF_U32 || ff == FF_S32)) {
+ *(uint32_t *)counter = ns_to_sec(now_ns) - value.u.u32;
+ }
else {
/* Unsupported field format/nature combination. */
return 1;
/* Only generic stat column must be used as input. */
BUG_ON(!stcol_is_generic(col));
+ fn = stcol_nature(col);
+
switch (cap) {
case STATS_PX_CAP_FE:
case STATS_PX_CAP_LI:
}
else {
/* Ensure metric is defined for the current cap. */
- if (!(col->cap & cap) || stcol_hide(idx, objt))
+ if (!(col->cap & cap))
return (struct field){ .type = FF_EMPTY };
+
+ if (stcol_hide(idx, objt)) {
+ if (fn == FN_AGE)
+ return mkf_s32(FN_AGE, -1);
+ else
+ return (struct field){ .type = FF_EMPTY };
+ }
}
- fn = stcol_nature(col);
if (fn == FN_COUNTER) {
switch (stcol_format(col)) {
case FF_U64:
BUG_ON(stcol_format(col) != FF_U32);
value = mkf_u32(FN_RATE, read_freq_ctr(counter));
}
+ else if (fn == FN_AGE) {
+ unsigned long age = *(unsigned long *)counter;
+ if (age)
+ age = ns_to_sec(now_ns) - age;
+
+ switch (stcol_format(col)) {
+ case FF_U32:
+ value = mkf_u32(FN_AGE, age);
+ break;
+ case FF_S32:
+ value = mkf_s32(FN_AGE, age);
+ break;
+ default:
+ /* only FF_U32/FF+S32 for age as generic stat column */
+ ABORT_NOW();
+ }
+ }
else {
/* No generic column available for other field nature. */
ABORT_NOW();