From fb4adac58c50e6909f34679a01da5b25f0516b71 Mon Sep 17 00:00:00 2001 From: jesseward Date: Sun, 27 Jul 2025 11:40:52 -0400 Subject: [PATCH 1/3] Adds new constructor NewFromEndOfFile Ignores OOMs that occurred before the parser was created. --- utils/oomparser/oomparser.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/utils/oomparser/oomparser.go b/utils/oomparser/oomparser.go index f5909032aa..61274fc638 100644 --- a/utils/oomparser/oomparser.go +++ b/utils/oomparser/oomparser.go @@ -151,6 +151,21 @@ func (p *OomParser) StreamOoms(outStream chan<- *OomInstance) { klog.Errorf("exiting analyzeLines. OOM events will not be reported.") } +// NewFromEndOfFile initializes an OomParser object that starts reading from the end of the kernel log. +// This will ignore any OOM events that occurred before the parser was created. +func NewFromEndOfFile() (*OomParser, error) { + parser, err := New() + if err != nil { + return nil, err + } + + // seek to and set the offset at the end of /dev/kmsg to avoid reporting old OOM events + if err := parser.parser.SeekEnd(); err != nil { + return nil, err + } + return parser, nil +} + // initializes an OomParser object. Returns an OomParser object and an error. func New() (*OomParser, error) { parser, err := kmsgparser.NewParser() From 4706684dfd15e4a0b9bc606b5cf8e2d50eb10a88 Mon Sep 17 00:00:00 2001 From: jesseward Date: Sun, 27 Jul 2025 20:14:41 +0000 Subject: [PATCH 2/3] Constructor name is now NewFromNow(). --- utils/oomparser/oomparser.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/utils/oomparser/oomparser.go b/utils/oomparser/oomparser.go index 61274fc638..a3e30f8fe6 100644 --- a/utils/oomparser/oomparser.go +++ b/utils/oomparser/oomparser.go @@ -151,9 +151,9 @@ func (p *OomParser) StreamOoms(outStream chan<- *OomInstance) { klog.Errorf("exiting analyzeLines. OOM events will not be reported.") } -// NewFromEndOfFile initializes an OomParser object that starts reading from the end of the kernel log. -// This will ignore any OOM events that occurred before the parser was created. -func NewFromEndOfFile() (*OomParser, error) { +// NewFromNow initializes an OomParser object that returns current OOM events only. In this mode the OomParser object +// will not send OOM events that occurred before the OomParser object was constructed. +func NewFromNow() (*OomParser, error) { parser, err := New() if err != nil { return nil, err From 9c58223b3be416c194363b69195fcb74a73daaf4 Mon Sep 17 00:00:00 2001 From: Jesse Ward Date: Mon, 29 Jun 2026 15:09:40 +0000 Subject: [PATCH 3/3] utils/oomparser: refactor NewFromNow for testability and add tests --- utils/oomparser/oomparser.go | 11 ++++++++--- utils/oomparser/oomparser_test.go | 32 +++++++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/utils/oomparser/oomparser.go b/utils/oomparser/oomparser.go index a3e30f8fe6..a232e50068 100644 --- a/utils/oomparser/oomparser.go +++ b/utils/oomparser/oomparser.go @@ -154,16 +154,21 @@ func (p *OomParser) StreamOoms(outStream chan<- *OomInstance) { // NewFromNow initializes an OomParser object that returns current OOM events only. In this mode the OomParser object // will not send OOM events that occurred before the OomParser object was constructed. func NewFromNow() (*OomParser, error) { - parser, err := New() + parser, err := kmsgparser.NewParser() if err != nil { return nil, err } + parser.SetLogger(glogAdapter{}) + return newFromNow(parser) +} + +func newFromNow(parser kmsgparser.Parser) (*OomParser, error) { // seek to and set the offset at the end of /dev/kmsg to avoid reporting old OOM events - if err := parser.parser.SeekEnd(); err != nil { + if err := parser.SeekEnd(); err != nil { return nil, err } - return parser, nil + return &OomParser{parser: parser}, nil } // initializes an OomParser object. Returns an OomParser object and an error. diff --git a/utils/oomparser/oomparser_test.go b/utils/oomparser/oomparser_test.go index d08ac4a37e..4e52a2a61b 100644 --- a/utils/oomparser/oomparser_test.go +++ b/utils/oomparser/oomparser_test.go @@ -473,11 +473,14 @@ func TestStreamOOMs(t *testing.T) { } type mockKmsgParser struct { - messages chan kmsgparser.Message + messages chan kmsgparser.Message + seekEndCalled bool + seekEndErr error } func (m *mockKmsgParser) SeekEnd() error { - return nil + m.seekEndCalled = true + return m.seekEndErr } func (m *mockKmsgParser) Parse() <-chan kmsgparser.Message { @@ -489,3 +492,28 @@ func (m *mockKmsgParser) Close() error { close(m.messages) return nil } + +func TestNewFromNow(t *testing.T) { + mockParser := &mockKmsgParser{ + messages: make(chan kmsgparser.Message), + } + + p, err := newFromNow(mockParser) + assert.NoError(t, err) + assert.NotNil(t, p) + assert.Equal(t, mockParser, p.parser) + assert.True(t, mockParser.seekEndCalled, "SeekEnd should have been called") +} + +func TestNewFromNow_SeekEndError(t *testing.T) { + expectedErr := fmt.Errorf("seek error") + mockParser := &mockKmsgParser{ + messages: make(chan kmsgparser.Message), + seekEndErr: expectedErr, + } + + p, err := newFromNow(mockParser) + assert.ErrorIs(t, err, expectedErr) + assert.Nil(t, p) + assert.True(t, mockParser.seekEndCalled) +}