diff --git a/utils/oomparser/oomparser.go b/utils/oomparser/oomparser.go index f5909032aa..a232e50068 100644 --- a/utils/oomparser/oomparser.go +++ b/utils/oomparser/oomparser.go @@ -151,6 +151,26 @@ func (p *OomParser) StreamOoms(outStream chan<- *OomInstance) { klog.Errorf("exiting analyzeLines. OOM events will not be reported.") } +// 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 := 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.SeekEnd(); err != nil { + return nil, err + } + return &OomParser{parser: parser}, nil +} + // initializes an OomParser object. Returns an OomParser object and an error. func New() (*OomParser, error) { parser, err := kmsgparser.NewParser() 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) +}