forked from lei.chen/myxce
Add ctrlstatus_fmt.h (ctrlstatus_format_time_ms): renders responder_time_ms as local YYYY-MM-DD HH:MM:SS,mmm, byte-equivalent to the controller log prefix (tlog/my_tlog_format) so a captured ctrlstatus lines up against ctrl-N.log. cmd_ctrlstatus prints a responderTime line; TZ-pinned exact-string unit test. Req 11.2, 11.3. ctrlstatus group passes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
61 lines
2.2 KiB
C
61 lines
2.2 KiB
C
#ifndef _CTRLSTATUS_FMT_H_
|
|
#define _CTRLSTATUS_FMT_H_
|
|
|
|
/* ctrlstatus_fmt.h — render a responder snapshot timestamp (epoch-millis) in
|
|
* the EXACT wall-clock string the controller logger emits, so the test client's
|
|
* `ctrlstatus` output is byte-comparable against ctrl-N.log (controller-status
|
|
* task 6.3, Req 11.2/11.3).
|
|
*
|
|
* The tlog prefix (vendored tinylog, _tlog_root_default_format) is built inline
|
|
* as:
|
|
*
|
|
* snprintf(... "[%.4d-%.2d-%.2d %.2d:%.2d:%.2d,%.3d]...",
|
|
* tm->year, tm->mon, tm->mday, tm->hour, tm->min, tm->sec,
|
|
* tm->usec / 1000, ...);
|
|
*
|
|
* where the broken-down time comes from gettimeofday() + localtime_r() — i.e.
|
|
* LOCAL time, with sub-second precision rendered as zero-padded MILLISECONDS
|
|
* (usec / 1000). tlog exposes no reusable formatter for callers, so this helper
|
|
* REPLICATES that construction: localtime_r + strftime("%Y-%m-%d %H:%M:%S")
|
|
* (byte-identical to "%.4d-%.2d-%.2d %.2d:%.2d:%.2d") then ",%03u" for the
|
|
* millisecond fraction. Both the logger and this helper use local time, so the
|
|
* rendered value matches the log line under the same TZ. */
|
|
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
|
|
/* Render `ms` (epoch milliseconds, e.g. xce_ctrlstatus_t.responder_time_ms)
|
|
* into `buf` as local-time "YYYY-MM-DD HH:MM:SS,mmm". Needs at least 24 bytes.
|
|
* Returns `buf` on success, NULL if buf is NULL / too small / time conversion
|
|
* fails. */
|
|
static inline char* ctrlstatus_format_time_ms(uint64_t ms, char* buf, size_t n)
|
|
{
|
|
/* "YYYY-MM-DD HH:MM:SS,mmm" + NUL == 24 bytes. */
|
|
if (buf == NULL || n < 24) {
|
|
return NULL;
|
|
}
|
|
|
|
time_t secs = (time_t)(ms / 1000u);
|
|
unsigned msec = (unsigned)(ms % 1000u);
|
|
struct tm tm;
|
|
|
|
if (localtime_r(&secs, &tm) == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
char datetime[20]; /* "YYYY-MM-DD HH:MM:SS" + NUL */
|
|
if (strftime(datetime, sizeof(datetime), "%Y-%m-%d %H:%M:%S", &tm) == 0) {
|
|
return NULL;
|
|
}
|
|
|
|
/* Match tlog's ",%.3d" millisecond fraction (zero-padded to 3 digits). */
|
|
if (snprintf(buf, n, "%s,%03u", datetime, msec) < 0) {
|
|
return NULL;
|
|
}
|
|
|
|
return buf;
|
|
}
|
|
|
|
#endif /* _CTRLSTATUS_FMT_H_ */
|