2
0

log backfill: synthesize timestamps when in 1970s

if the log message timestamp is in 1970, treat it as if
the epoch were the system boot time
This commit is contained in:
2025-10-28 23:29:20 +00:00
parent f4b87430ea
commit ead6cb918a

View File

@@ -6,11 +6,15 @@
(local O_RDWR 2)
(local O_CREAT 64)
(fn send-message [fd message]
(case (write fd message)
n (if (> (# message) n) (send-message (string.sub message n)) true)
(fn send-string [fd str]
(case (write fd str)
n (if (> (# str) n) (send-string (string.sub str n)) true)
(nil code) nil))
(fn send-message [fd tai message]
(let [ts (tai64.to-timestamp tai)]
(send-string fd (.. ts (string.sub message 26)))))
(fn parse-timestamp [message]
(let [{ : s : n } (tai64.from-timestamp message)]
(+ (* s 1000000000) n)))
@@ -27,7 +31,30 @@
(with-open [f (assert (io.open filename :r))]
(f:read "a")))
;; Any message which claims to have been generated before the
;; first public release of Linux is most likely instead generated
;; by a device that has no battery-backed clock and no
;; sync with NTP. Because the system clock starts at 1970-1-1
;; we treat this timestamp as an offset from the actual boot time
(local earliest-plausible-timestamp
(tai64.from-unix (os.time {:year 1991 :month 9 :day 17})))
(fn read-boot-time []
(let [uptime (with-open [f (io.open "/proc/uptime" :r)] (f:read "n"))
s (math.floor uptime)
now (tai64.from-unix (os.time))]
;; we deduct an extra second to ensure there are no backfilled messages
;; sent with timestamps later than the earliest live message.
{:s (- now.s s 1) :n 0 }))
(fn maybe-offset [timestamp boot-time]
(if (< timestamp.s earliest-plausible-timestamp.s)
{:s (+ timestamp.s boot-time.s) :n timestamp.n}
timestamp))
(let [[fifo-name stampfile] arg
boot-time (read-boot-time)
fifo (ll.open fifo-name O_WRONLY 0)]
(var backfill? true)
(var next-ts
@@ -42,16 +69,17 @@
"# LOG-SHIPPING-STOP\n"
(set backfill? true)
message
(let [message-ts (parse-timestamp message)]
(let [tai (tai64.from-timestamp message)
message-ts (+ (* tai.s 1000000000) tai.n)]
(when (> message-ts next-ts)
(set next-ts (write-timestamp stampfile message-ts)))
(when (>= message-ts next-ts)
; (io.stderr:write (.. "writing " message (if backfill? "true" "false")))
(if backfill?
(when (not (send-message fifo message))
;; If the fifo write fails, it could be a glitch or it
;; could be some kind of wider outage. Give up,
;; and rely on the supervisor to restart us when
;; conditions are again auspicious
(io.stderr:write "write failed\n")
(os.exit 1))))))))
(let [actual-time (maybe-offset tai boot-time)]
(when (not (send-message fifo actual-time message))
;; If the fifo write fails, it could be a glitch or it
;; could be some kind of wider outage. Give up,
;; and rely on the supervisor to restart us when
;; conditions are again auspicious
(io.stderr:write "write failed\n")
(os.exit 1)))))))))