From 81cf3b2f31a55a2caf8222c6847ca8d9c01f8eee Mon Sep 17 00:00:00 2001 From: Josh N Date: Mon, 3 Aug 2020 08:54:15 -0400 Subject: Added optional POWER argument to $response_time This argument allows for conversion of response_time to microsecond or nanosecond by multiplying by a power of 10, up to a limit of 9. Defaults to 0 so backwards compatible. --- ext/clogger_ext/clogger.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'ext/clogger_ext') diff --git a/ext/clogger_ext/clogger.c b/ext/clogger_ext/clogger.c index fdc23e3..a1f3bc4 100644 --- a/ext/clogger_ext/clogger.c +++ b/ext/clogger_ext/clogger.c @@ -374,12 +374,40 @@ static void append_ts(struct clogger *c, VALUE op, struct timespec *ts) rb_str_buf_cat(c->log_buf, buf, nr); } +#define NANO_PER_SEC (1000 * 1000 * 1000) static void append_request_time_fmt(struct clogger *c, VALUE op) { struct timespec now; + unsigned long ipow = NUM2ULONG(rb_ary_entry(op, 3)); clock_gettime(hopefully_CLOCK_MONOTONIC, &now); clock_diff(&now, &c->ts_start); + if (ipow) { + struct timespec prev; + unsigned long adj = 1; + /* + * n.b. timespec.tv_sec may not be time_t on some platforms, + * so we use a full timespec struct instead of time_t: + */ + prev.tv_sec = now.tv_sec; + do { adj *= 10; } while (--ipow); + now.tv_sec *= adj; + now.tv_nsec *= adj; + if (now.tv_nsec >= NANO_PER_SEC) { + int64_t add = now.tv_nsec / NANO_PER_SEC; + now.tv_sec += add; + now.tv_nsec %= NANO_PER_SEC; + } + if (now.tv_sec < prev.tv_sec) { /* overflowed */ + now.tv_nsec = NANO_PER_SEC - 1; + /* + * some platforms may use unsigned .tv_sec, but + * they're not worth supporting, so keep unsigned: + */ + now.tv_sec = (time_t)(sizeof(now.tv_sec) == 4 ? + INT_MAX : LONG_MAX); + } + } append_ts(c, op, &now); } -- cgit v1.2.3-24-ge0c7