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:
@@ -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)))))))))
|
||||
|
||||
Reference in New Issue
Block a user