Skip to content

Commit 6f7d20b

Browse files
committed
feat: calculate boot time correctly if the time jumps
Instead of capturing boot time difference with `time.Now()` just once at the beginning of streaming kmsg events, re-check the `time.Now()` while processing each message. This fixes issue with kmsg logs as seens e.g. from RPi: as it has not RTC, it might streaming ksmg logs while time is back at zero (1970), but as NTP catches up, the stream still reports dates in 1970, not accepting the fact that the NTP caught up. Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
1 parent 47655ee commit 6f7d20b

File tree

5 files changed

+22
-22
lines changed

5 files changed

+22
-22
lines changed

go.mod

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
module github.com/siderolabs/go-kmsg
22

3-
go 1.21.5
3+
go 1.25.0
44

55
require (
6-
github.com/siderolabs/gen v0.4.7
7-
github.com/stretchr/testify v1.8.4
6+
github.com/siderolabs/gen v0.8.6
7+
github.com/stretchr/testify v1.11.1
88
go.uber.org/goleak v1.3.0
9-
golang.org/x/sys v0.16.0
9+
golang.org/x/sys v0.42.0
1010
)
1111

1212
require (

go.sum

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
77
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
88
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
99
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
10-
github.com/siderolabs/gen v0.4.7 h1:lM69UYggT7yzpubf7hEFaNujPdY55Y9zvQf/NC18GvA=
11-
github.com/siderolabs/gen v0.4.7/go.mod h1:4PBYMdXxTg292IDRq4CGn5AymyDxJVEDvobVKDqFBEA=
12-
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
13-
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
10+
github.com/siderolabs/gen v0.8.6 h1:pE6shuqov3L+5rEcAUJ/kY6iJofimljQw5G95P8a5c4=
11+
github.com/siderolabs/gen v0.8.6/go.mod h1:J9IbusbES2W6QWjtSHpDV9iPGZHc978h1+KJ4oQRspQ=
12+
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
13+
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
1414
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
1515
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
16-
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
17-
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
16+
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
17+
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
1818
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
1919
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
2020
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

reader.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ func NewReader(options ...Option) (Reader, error) {
6868

6969
var err error
7070

71-
r.bootTime, err = getBootTime()
71+
r.bootOffset, err = getBootTimeOffset()
7272
if err != nil {
7373
return nil, err
7474
}
@@ -91,9 +91,9 @@ func NewReader(options ...Option) (Reader, error) {
9191
}
9292

9393
type reader struct {
94-
f *os.File
95-
bootTime time.Time
96-
options options
94+
f *os.File
95+
bootOffset time.Duration
96+
options options
9797
}
9898

9999
func (r *reader) Close() error {
@@ -148,7 +148,7 @@ func (r *reader) scanNoFollow(ctx context.Context, ch chan<- Packet) {
148148
}
149149

150150
var packet Packet
151-
packet.Message, packet.Err = ParseMessage(buf[:n], r.bootTime)
151+
packet.Message, packet.Err = ParseMessage(buf[:n], time.Now().Add(r.bootOffset))
152152

153153
if !channel.SendWithContext(ctx, ch, packet) {
154154
return
@@ -182,7 +182,7 @@ func (r *reader) scanFollow(ctx context.Context, ch chan<- Packet) {
182182
}
183183

184184
var packet Packet
185-
packet.Message, packet.Err = ParseMessage(buf[:n], r.bootTime)
185+
packet.Message, packet.Err = ParseMessage(buf[:n], time.Now().Add(r.bootOffset))
186186

187187
if !channel.SendWithContext(ctx, ch, packet) {
188188
return

utils_bsd.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ import (
1313
"golang.org/x/sys/unix"
1414
)
1515

16-
func getBootTime() (time.Time, error) {
16+
func getBootTimeOffset() (time.Duration, error) {
1717
timeval, err := unix.SysctlTimeval("kern.boottime")
1818
if err != nil {
19-
return time.Time{}, fmt.Errorf("could not get boot time: %w", err)
19+
return 0, fmt.Errorf("could not get boot time: %w", err)
2020
}
2121

22-
return time.Unix(timeval.Unix()), nil
22+
return time.Until(time.Unix(timeval.Unix())), nil
2323
}

utils_linux.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ import (
1313
"golang.org/x/sys/unix"
1414
)
1515

16-
func getBootTime() (time.Time, error) {
16+
func getBootTimeOffset() (time.Duration, error) {
1717
var sysinfo unix.Sysinfo_t
1818

1919
err := unix.Sysinfo(&sysinfo)
2020
if err != nil {
21-
return time.Time{}, fmt.Errorf("could not get boot time: %w", err)
21+
return 0, fmt.Errorf("could not get boot time: %w", err)
2222
}
2323

2424
// sysinfo only has seconds
25-
return time.Now().Add(-1 * (time.Duration(sysinfo.Uptime) * time.Second)), nil
25+
return -1 * (time.Duration(sysinfo.Uptime) * time.Second), nil
2626
}

0 commit comments

Comments
 (0)