Skip to content

Commit a024adc

Browse files
committed
Update query to use lte instead of lt
1 parent eb90d2f commit a024adc

3 files changed

Lines changed: 39 additions & 35 deletions

File tree

plugins/inputs/windows_event_log/wineventlog/utils.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const (
2828
eventLogQueryTemplate = `<QueryList><Query Id="0"><Select Path="%s">*[System[%s]]</Select></Query></QueryList>`
2929
eventLogLevelFilter = "Level='%s'"
3030
eventIgnoreOldFilter = "TimeCreated[timediff(@SystemTime) &lt;= %d]"
31-
eventRangeFilter = "EventRecordID &gt; %d and EventRecordID &lt; %d"
31+
eventRangeFilter = "EventRecordID &gt; %d and EventRecordID &lt;= %d"
3232
emptySpaceScanLength = 100
3333
UnknownBytesPerCharacter = 0
3434

plugins/inputs/windows_event_log/wineventlog/wineventlog.go

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,8 @@ func (w *windowsEventLog) run() {
177177
}
178178
// Prioritize gaps to read on this tick of the timer
179179
var records []*windowsEventLogRecord
180-
readingFromGap := false
181180
if len(w.gapsToRead) > 0 {
182181
records = w.readGaps()
183-
readingFromGap = true
184182
} else {
185183
records = w.read()
186184
}
@@ -191,12 +189,7 @@ func (w *windowsEventLog) run() {
191189
continue
192190
}
193191
recordNumber, _ := strconv.ParseUint(record.System.EventRecordID, 10, 64)
194-
// Need to shift by 1 because the range logic assumes [start, end) whereas Windows events is [start, end]
195-
if readingFromGap {
196-
r.Shift(recordNumber + 1)
197-
} else {
198-
r.Shift(recordNumber)
199-
}
192+
r.Shift(recordNumber)
200193
evt := &LogEvent{
201194
msg: value,
202195
t: record.System.TimeCreated.SystemTime,

plugins/inputs/windows_event_log/wineventlog/wineventlog_test.go

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -123,18 +123,18 @@ func TestReadGaps(t *testing.T) {
123123

124124
t.Run("BasicGapReading", func(t *testing.T) {
125125
rl := state.RangeList{
126-
state.NewRange(0, 1),
127-
state.NewRange(4, 5),
126+
// Inverted range: 0-5, 10-15, 20-25, 30-inf
127+
state.NewRange(5, 10),
128+
state.NewRange(15, 20),
129+
state.NewRange(25, 30),
128130
}
129131
elog, stateFileName := newTestEventLogWithState(t, NAME, LEVELS, rl)
130132
mockAPI := NewMockWindowsEventAPI()
131133
winEventAPI = mockAPI
132134

133-
// This is per EvtHandle hence the necessity to break up these calls
134-
// 0, 1, 4 were "sent" previously (should be skipped)
135-
mockAPI.AddMockEventsForQuery(createMockEventRecords(0, 1, 4, 5))
136-
// Gap records (should be read by gap reading)
137-
mockAPI.AddMockEventsForQuery(createMockEventRecords(2, 3))
135+
mockAPI.AddMockEventsForQuery(createMockEventRecordsRange(0, 5))
136+
mockAPI.AddMockEventsForQuery(createMockEventRecordsRange(10, 15))
137+
mockAPI.AddMockEventsForQuery(createMockEventRecordsRange(20, 25))
138138

139139
elog.Init()
140140

@@ -147,24 +147,33 @@ func TestReadGaps(t *testing.T) {
147147
time.Sleep(8 * time.Second)
148148
elog.Stop()
149149

150+
expectedRecords := []int{
151+
1, 2, 3, 4, 5, 11, 12, 13, 14, 15, 21, 22, 23, 24, 25,
152+
}
153+
150154
assert.Empty(t, elog.gapsToRead, "Gaps should be cleared after reading")
151-
assert.Len(t, records, 2, "Should return 2 mock events")
152-
assert.Len(t, mockAPI.QueryCalls, 1, "Should make one query call")
155+
assert.Len(t, records, len(expectedRecords), "Should return correct number of mock events")
156+
assert.Len(t, mockAPI.QueryCalls, 3, "Should make three query calls")
153157
assert.Equal(t, NAME, mockAPI.QueryCalls[0].Path, "Should query correct path")
154-
assert.Contains(t, mockAPI.QueryCalls[0].Query, "EventRecordID &gt; 1", "Query should contain start range")
155-
assert.Contains(t, mockAPI.QueryCalls[0].Query, "EventRecordID &lt; 4", "Query should contain end range")
158+
assert.Contains(t, mockAPI.QueryCalls[0].Query, "EventRecordID &gt; 0", "Query should contain start range")
159+
assert.Contains(t, mockAPI.QueryCalls[0].Query, "EventRecordID &lt;= 5", "Query should contain end range")
160+
assert.Contains(t, mockAPI.QueryCalls[1].Query, "EventRecordID &gt; 10", "Query should contain start range")
161+
assert.Contains(t, mockAPI.QueryCalls[1].Query, "EventRecordID &lt;= 15", "Query should contain end range")
162+
assert.Contains(t, mockAPI.QueryCalls[2].Query, "EventRecordID &gt; 20", "Query should contain start range")
163+
assert.Contains(t, mockAPI.QueryCalls[2].Query, "EventRecordID &lt;= 25", "Query should contain end range")
156164
assert.Greater(t, len(mockAPI.CloseCalls), 0, "Should make close calls")
157165

158166
for i, record := range records {
159-
assert.Contains(t, record.Message(), fmt.Sprintf("Event %d", 2+i))
167+
assert.Contains(t, record.Message(), fmt.Sprintf("Event %d", expectedRecords[i]))
160168
}
161169

162170
assertStateFileRange(t, stateFileName, state.RangeList{
163-
state.NewRange(0, 5),
171+
state.NewRange(0, 30),
164172
})
165173
})
166174
t.Run("ReadGapThenSubscribe", func(t *testing.T) {
167175
rl := state.RangeList{
176+
// Inverted range: 2-4
168177
state.NewRange(0, 2),
169178
state.NewRange(4, 5),
170179
}
@@ -174,7 +183,7 @@ func TestReadGaps(t *testing.T) {
174183

175184
// This is per EvtHandle hence the necessity to break up these calls
176185
// 0, 1, 4 were "sent" previously (should be skipped)
177-
mockAPI.AddMockEventsForQuery(createMockEventRecords(0, 2, 4, 5))
186+
mockAPI.AddMockEventsForQuery(createMockEventRecords(0, 2, 5))
178187
// Gap records (should be read by gap reading)
179188
mockAPI.AddMockEventsForQuery(createMockEventRecords(3, 4))
180189

@@ -192,18 +201,19 @@ func TestReadGaps(t *testing.T) {
192201
time.Sleep(5 * time.Second)
193202
elog.Stop()
194203

204+
expectedRecords := []int{
205+
3, 4, 5, 6, 7, 8,
206+
}
207+
195208
assert.Empty(t, elog.gapsToRead, "Gaps should be cleared after reading")
196-
assert.Len(t, records, 5, "Should return 5 mock events")
209+
assert.Len(t, records, len(expectedRecords), "Should return correct number of mock events")
197210
assert.Len(t, mockAPI.QueryCalls, 1, "Should make one query call")
198211
assert.Equal(t, NAME, mockAPI.QueryCalls[0].Path, "Should query correct path")
199212
assert.Contains(t, mockAPI.QueryCalls[0].Query, "EventRecordID &gt; 2", "Query should contain start range")
200-
assert.Contains(t, mockAPI.QueryCalls[0].Query, "EventRecordID &lt; 4", "Query should contain end range")
213+
assert.Contains(t, mockAPI.QueryCalls[0].Query, "EventRecordID &lt;= 4", "Query should contain end range")
201214
assert.Len(t, mockAPI.SubscribeCalls, 1, "Should make one subscribe call")
202215
assert.Greater(t, len(mockAPI.CloseCalls), 0, "Should make close calls")
203216

204-
expectedRecords := []int{
205-
3, 5, 6, 7, 8,
206-
}
207217
for i, record := range records {
208218
assert.Contains(t, record.Message(), fmt.Sprintf("Event %d", expectedRecords[i]))
209219
}
@@ -225,7 +235,7 @@ func TestReadGaps(t *testing.T) {
225235

226236
elog.Init()
227237

228-
mockAPI.SimulateSubscriptionEvents(createMockEventRecordsRange(5, 9))
238+
mockAPI.SimulateSubscriptionEvents(createMockEventRecordsRange(6, 9))
229239

230240
var records []logs.LogEvent
231241
// SetOutput calls run as well hence the omission of elog.run()
@@ -244,11 +254,11 @@ func TestReadGaps(t *testing.T) {
244254

245255
for i, record := range records {
246256
// Offset by 5 since we "already read" events 0-4
247-
assert.Contains(t, record.Message(), fmt.Sprintf("Event %d", 5+i))
257+
assert.Contains(t, record.Message(), fmt.Sprintf("Event %d", 6+i))
248258
}
249259

250260
assertStateFileRange(t, stateFileName, state.RangeList{
251-
state.NewRange(0, 8),
261+
state.NewRange(0, 9),
252262
})
253263
})
254264
}
@@ -330,9 +340,10 @@ func assertStateFileRange(t *testing.T, fileName string, rl state.RangeList) {
330340
assert.Contains(t, string(content), marshalRangeList(rl))
331341
}
332342

343+
// Start and end are both inclusive
333344
func createMockEventRecordsRange(start, end int) []*MockEventRecord {
334345
var records []*MockEventRecord
335-
for i := start; i < end; i++ {
346+
for i := start; i <= end; i++ {
336347
records = append(records, &MockEventRecord{
337348
EventRecordID: fmt.Sprintf("%d", i),
338349
TimeCreated: time.Now(),
@@ -903,13 +914,13 @@ func (m *MockWindowsEventAPI) EvtOpenPublisherMetadata(session EvtHandle, publis
903914
// Helper methods
904915
func (m *MockWindowsEventAPI) extractRangeFromQuery(query string) state.Range {
905916
// Parse the XML query to extract EventRecordID constraints using a single regex
906-
// Look for pattern like "EventRecordID &gt; 2 and EventRecordID &lt; 4"
917+
// Look for pattern like "EventRecordID &gt; 2 and EventRecordID &lt;= 4"
907918

908919
var start, end uint64 = 0, 1000 // Default range
909920

910921
if query != "" {
911922
// Extract both start and end in one regex
912-
rangeRegex := regexp.MustCompile(`EventRecordID &gt; (\d+) and EventRecordID &lt; (\d+)`)
923+
rangeRegex := regexp.MustCompile(`EventRecordID &gt; (\d+) and EventRecordID &lt;= (\d+)`)
913924
if matches := rangeRegex.FindStringSubmatch(query); len(matches) > 2 {
914925
if parsedStart, err := strconv.ParseUint(matches[1], 10, 64); err == nil {
915926
start = parsedStart
@@ -931,7 +942,7 @@ func (m *MockWindowsEventAPI) findOrCreateHandleForRange(r state.Range) EvtHandl
931942
filteredEvents := []*MockEventRecord{}
932943
for _, event := range events {
933944
eventID, _ := strconv.ParseUint(event.EventRecordID, 10, 64)
934-
inRange := eventID > r.StartOffset() && eventID < r.EndOffset()
945+
inRange := eventID > r.StartOffset() && eventID <= r.EndOffset()
935946
if inRange {
936947
filteredEvents = append(filteredEvents, event)
937948
}

0 commit comments

Comments
 (0)