diff --git a/.github/workflows/test-artifacts.yml b/.github/workflows/test-artifacts.yml
index ab7a033f7a..819e055e22 100644
--- a/.github/workflows/test-artifacts.yml
+++ b/.github/workflows/test-artifacts.yml
@@ -1319,4 +1319,4 @@ jobs:
else
cd terraform/eks/addon/gpu
fi
- terraform destroy -auto-approve
\ No newline at end of file
+ terraform destroy -auto-approve
diff --git a/cmd/config-translator/translator_test.go b/cmd/config-translator/translator_test.go
index b276fc4632..1b24e4fa5b 100644
--- a/cmd/config-translator/translator_test.go
+++ b/cmd/config-translator/translator_test.go
@@ -103,6 +103,7 @@ func TestLogWindowsEventConfig(t *testing.T) {
checkIfSchemaValidateAsExpected(t, "../../translator/config/sampleSchema/invalidLogWindowsEventsWithInvalidEventName.json", false, expectedErrorMap)
expectedErrorMap1 := map[string]int{}
expectedErrorMap1["required"] = 2
+ expectedErrorMap1["number_any_of"] = 1
checkIfSchemaValidateAsExpected(t, "../../translator/config/sampleSchema/invalidLogWindowsEventsWithMissingEventNameAndLevel.json", false, expectedErrorMap1)
expectedErrorMap2 := map[string]int{}
expectedErrorMap2["invalid_type"] = 1
@@ -110,6 +111,18 @@ func TestLogWindowsEventConfig(t *testing.T) {
expectedErrorMap3 := map[string]int{}
expectedErrorMap3["enum"] = 1
checkIfSchemaValidateAsExpected(t, "../../translator/config/sampleSchema/invalidLogWindowsEventsWithInvalidEventFormatType.json", false, expectedErrorMap3)
+
+ //New tests for event_ids feature
+ checkIfSchemaValidateAsExpected(t, "../../translator/config/sampleSchema/invalidLogWindowsEventsWithInvalidEventFormatType.json", false, expectedErrorMap3)
+ expectedErrorMap4 := map[string]int{}
+ expectedErrorMap4["invalid_type"] = 1
+ checkIfSchemaValidateAsExpected(t, "../../translator/config/sampleSchema/invalidLogWindowsEventsWithInvalidEventIdsType.json", false, expectedErrorMap4)
+
+ expectedErrorMap5 := map[string]int{}
+ expectedErrorMap5["required"] = 1
+ expectedErrorMap5["number_any_of"] = 1
+ checkIfSchemaValidateAsExpected(t, "../../translator/config/sampleSchema/invalidLogWindowsEventsWithMissingEventIdsAndEventLevels.json", false, expectedErrorMap5)
+
}
func TestMetricsConfig(t *testing.T) {
@@ -198,7 +211,9 @@ func TestSampleConfigSchema(t *testing.T) {
for _, file := range files {
if re.MatchString(file.Name()) {
t.Logf("Validating ../../translator/tocwconfig/sampleConfig/%s\n", file.Name())
+
checkIfSchemaValidateAsExpected(t, "../../translator/tocwconfig/sampleConfig/"+file.Name(), true, map[string]int{})
+
t.Logf("Validated ../../translator/tocwconfig/sampleConfig/%s\n", file.Name())
}
}
diff --git a/plugins/inputs/windows_event_log/windows_event_log.go b/plugins/inputs/windows_event_log/windows_event_log.go
index 2cf4cb8786..70eafab377 100644
--- a/plugins/inputs/windows_event_log/windows_event_log.go
+++ b/plugins/inputs/windows_event_log/windows_event_log.go
@@ -31,6 +31,7 @@ var startOnlyOnce sync.Once
type EventConfig struct {
Name string `toml:"event_name"`
Levels []string `toml:"event_levels"`
+ EventIDs []int `toml:"event_ids"`
RenderFormat string `toml:"event_format"`
BatchReadSize int `toml:"batch_read_size"`
LogGroupName string `toml:"log_group_name"`
@@ -39,7 +40,6 @@ type EventConfig struct {
Destination string `toml:"destination"`
Retention int `toml:"retention_in_days"`
}
-
type Plugin struct {
FileStateFolder string `toml:"file_state_folder"`
Events []EventConfig `toml:"event_config"`
@@ -61,6 +61,7 @@ func (s *Plugin) SampleConfig() string {
[[inputs.windows_event_log.event_config]]
event_name = "System"
event_levels = ["2", "3"]
+ event_ids = [1001, 1002]
batch_read_size = 1
log_group_name = "System"
log_stream_name = "STREAM_NAME"
@@ -106,6 +107,7 @@ func (s *Plugin) Start(acc telegraf.Accumulator) error {
eventLog := wineventlog.NewEventLog(
eventConfig.Name,
eventConfig.Levels,
+ eventConfig.EventIDs,
eventConfig.LogGroupName,
eventConfig.LogStreamName,
eventConfig.RenderFormat,
diff --git a/plugins/inputs/windows_event_log/wineventlog/utils.go b/plugins/inputs/windows_event_log/wineventlog/utils.go
index e903670dc1..716b5eaf26 100644
--- a/plugins/inputs/windows_event_log/wineventlog/utils.go
+++ b/plugins/inputs/windows_event_log/wineventlog/utils.go
@@ -1,29 +1,18 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT
-//go:build windows
-// +build windows
-
package wineventlog
import (
- "bytes"
"fmt"
- "io"
- "log"
- "strconv"
- "strings"
- "syscall"
"time"
-
- "golang.org/x/text/encoding/unicode"
- "golang.org/x/text/transform"
)
const (
bookmarkTemplate = ``
eventLogQueryTemplate = ``
eventLogLevelFilter = "Level='%s'"
+ eventLogeventIDFilter = "EventID='%d'"
eventIgnoreOldFilter = "TimeCreated[timediff(@SystemTime) <= %d]"
emptySpaceScanLength = 100
UnknownBytesPerCharacter = 0
@@ -36,34 +25,7 @@ const (
UNKNOWN = "UNKNOWN"
)
-var NumberOfBytesPerCharacter = UnknownBytesPerCharacter
-
-func RenderEventXML(eventHandle EvtHandle, renderBuf []byte) ([]byte, error) {
- var bufferUsed, propertyCount uint32
-
- if err := EvtRender(0, eventHandle, EvtRenderEventXml, uint32(len(renderBuf)), &renderBuf[0], &bufferUsed, &propertyCount); err != nil {
- return nil, fmt.Errorf("error when rendering events. Details: %v", err)
- }
-
- // Per MSDN as of Mar 14th 2022(https://docs.microsoft.com/en-us/windows/win32/api/winevt/nf-winevt-evtrender)
- // EvtRender function is still returning buffer used as BYTES, not characters. So keep using utf16ToUTF8Bytes()
- return utf16ToUTF8Bytes(renderBuf, bufferUsed)
-}
-
-func CreateBookmark(channel string, recordID uint64) (h EvtHandle, err error) {
- xml := fmt.Sprintf(bookmarkTemplate, channel, recordID)
- p, err := syscall.UTF16PtrFromString(xml)
- if err != nil {
- return 0, err
- }
- h, err = EvtCreateBookmark(p)
- if err != nil {
- return 0, fmt.Errorf("error when creating a bookmark. Details: %v", err)
- }
- return h, nil
-}
-
-func CreateQuery(path string, levels []string) (*uint16, error) {
+func createFilterQuery(levels []string, eventIDs []int) string {
var filterLevels string
for _, level := range levels {
if filterLevels == "" {
@@ -73,149 +35,34 @@ func CreateQuery(path string, levels []string) (*uint16, error) {
}
}
- //Ignore events older than 2 weeks
- cutOffPeriod := (time.Hour * 24 * 14).Nanoseconds()
- ignoreOlderThanTwoWeeksFilter := fmt.Sprintf(eventIgnoreOldFilter, cutOffPeriod/int64(time.Millisecond))
- if filterLevels != "" {
- filterLevels = "*[System[(" + filterLevels + ") and " + ignoreOlderThanTwoWeeksFilter + "]]"
- } else {
- filterLevels = "*[System[" + ignoreOlderThanTwoWeeksFilter + "]]"
- }
-
- xml := fmt.Sprintf(eventLogQueryTemplate, path, filterLevels)
- return syscall.UTF16PtrFromString(xml)
-}
-
-func utf16ToUTF8Bytes(in []byte, length uint32) ([]byte, error) {
-
- i := length
-
- if length%2 != 0 {
- i = length - 1
- }
-
- for ; i-2 > 0; i -= 2 {
- v1 := uint16(in[i-2]) | uint16(in[i-1])<<8
- // Stop at non-null char.
- if v1 != 0 {
- break
- }
- }
-
- win16be := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM)
- utf16bom := unicode.BOMOverride(win16be.NewDecoder())
- unicodeReader := transform.NewReader(bytes.NewReader(in[:i]), utf16bom)
- decoded, err := io.ReadAll(unicodeReader)
- return decoded, err
-}
-
-func UTF16ToUTF8BytesForWindowsEventBuffer(in []byte, length uint32) ([]byte, error) {
- // Since Windows server 2022, the returned value of used buffer represents for double bytes char count,
- // which is half of the actual buffer used by byte(what older Windows OS returns), checking if the length
- //land on the end of used buffer, if no, double it.
- if NumberOfBytesPerCharacter == UnknownBytesPerCharacter {
- if isTheEndOfContent(in, length) {
- log.Printf("I! Buffer used: %d is returning as single byte character count", length)
- NumberOfBytesPerCharacter = 1
+ //EventID filtering
+ var filterEventIDs string
+ for i, eventID := range eventIDs {
+ if i == 0 {
+ filterEventIDs = fmt.Sprintf(eventLogeventIDFilter, eventID)
} else {
- log.Printf("I! Buffer used: %d is returning as double byte character count, doubling it to get the whole buffer content.", length)
- NumberOfBytesPerCharacter = 2
- }
- }
-
- i := int(length) * NumberOfBytesPerCharacter
-
- if i > cap(in) {
- i = cap(in)
- }
-
- return utf16ToUTF8Bytes(in, uint32(i))
-}
-
-func isTheEndOfContent(in []byte, length uint32) bool {
- // scan next (emptySpaceScanLength) bytes, if any of them is none '0', return false
- i := int(length)
-
- if i%2 != 0 {
- i -= 1
- }
- max := len(in)
- if i+emptySpaceScanLength < max {
- max = i + emptySpaceScanLength
- }
-
- for ; i < max-2; i += 2 {
- v1 := uint16(in[i+2]) | uint16(in[i+1])<<8
- // Stop at non-null char.
- if v1 != 0 {
- return false
+ filterEventIDs = filterEventIDs + " or " + fmt.Sprintf(eventLogeventIDFilter, eventID)
}
}
- return true
-}
-func WindowsEventLogLevelName(levelId int32) string {
- switch levelId {
- case 1:
- return CRITICAL
- case 2:
- return ERROR
- case 3:
- return WARNING
- case 0, 4:
- return INFORMATION
- case 5:
- return VERBOSE
- default:
- return UNKNOWN
+ //query results
+ var query string
+ if filterLevels != "" && filterEventIDs != "" {
+ query = "(" + filterLevels + ") and (" + filterEventIDs + ")"
+ } else if filterLevels != "" && filterEventIDs == "" {
+ query = "(" + filterLevels + ")"
+ } else if filterLevels == "" && filterEventIDs != "" {
+ query = "(" + filterEventIDs + ")"
}
-}
-
-// insertPlaceholderValues formats the message with the correct values if we see those data
-// in evtDataValues.
-//
-// In some cases wevtapi does not insert values when formatting the message. The message
-// will contain insertion string placeholders, of the form %n, where %1 indicates the first
-// insertion string, and so on. Noted that wevtapi start the index with 1.
-// https://learn.microsoft.com/en-us/windows/win32/eventlog/event-identifiers#insertion-strings
-func insertPlaceholderValues(rawMessage string, evtDataValues []Datum) string {
- if len(evtDataValues) == 0 || len(rawMessage) == 0 {
- return rawMessage
- }
- var sb strings.Builder
- prevIndex := 0
- searchingIndex := false
- for i, c := range rawMessage {
- // found `%` previously. Determine the index number from the following character(s)
- if searchingIndex && (c > '9' || c < '0') {
- // Convert the Slice since the last `%` and see if it's a valid number.
- ind, err := strconv.Atoi(rawMessage[prevIndex+1 : i])
- // If the index is in [1 - len(evtDataValues)], get it from evtDataValues.
- if err == nil && ind <= len(evtDataValues) && ind > 0 {
- sb.WriteString(evtDataValues[ind-1].Value)
- } else {
- sb.WriteString(rawMessage[prevIndex:i])
- }
- prevIndex = i
- // In case of consecutive `%`, continue searching for the next index
- if c != '%' {
- searchingIndex = false
- }
- } else {
- if c == '%' {
- sb.WriteString(rawMessage[prevIndex:i])
- searchingIndex = true
- prevIndex = i
- }
- }
- }
- // handle the slice since the last `%` to the end of rawMessage
- ind, err := strconv.Atoi(rawMessage[prevIndex+1:])
- if searchingIndex && err == nil && ind <= len(evtDataValues) && ind > 0 {
- sb.WriteString(evtDataValues[ind-1].Value)
+ //Ignore events older than 2 weeks
+ cutOffPeriod := (time.Hour * 24 * 14).Nanoseconds()
+ ignoreOlderThanTwoWeeksFilter := fmt.Sprintf(eventIgnoreOldFilter, cutOffPeriod/int64(time.Millisecond))
+ if query != "" {
+ query = "*[System[" + query + " and " + ignoreOlderThanTwoWeeksFilter + "]]"
} else {
- sb.WriteString(rawMessage[prevIndex:])
+ query = "*[System[" + ignoreOlderThanTwoWeeksFilter + "]]"
}
- return sb.String()
+
+ return query
}
diff --git a/plugins/inputs/windows_event_log/wineventlog/utils_test.go b/plugins/inputs/windows_event_log/wineventlog/utils_test.go
index 40586504d3..89cb25de82 100644
--- a/plugins/inputs/windows_event_log/wineventlog/utils_test.go
+++ b/plugins/inputs/windows_event_log/wineventlog/utils_test.go
@@ -1,134 +1,51 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT
-//go:build windows
-// +build windows
-
package wineventlog
import (
- "encoding/hex"
"testing"
"github.com/stretchr/testify/assert"
)
-func TestPayload_Value(t *testing.T) {
- // one null test
- resetState()
- originalHexStr := "3c004500760065006e007400200078006d006c006e0073003d00270068007400740070003a002f002f0073006300680065006d00610073002e006d006900630072006f0073006f00660074002e0063006f006d002f00770069006e002f0032003000300034002f00300038002f006500760065006e00740073002f006500760065006e00740027003e003c00530079007300740065006d003e003c00500072006f007600690064006500720020004e0061006d0065003d0027004d006900630072006f0073006f00660074002d00570069006e0064006f00770073002d00530065006300750072006900740079002d004100750064006900740069006e0067002700200047007500690064003d0027007b00350034003800340039003600320035002d0035003400370038002d0034003900390034002d0041003500420041002d003300450033004200300033003200380043003300300044007d0027002f003e003c004500760065006e007400490044003e0034003600320035003c002f004500760065006e007400490044003e003c00560065007200730069006f006e003e0030003c002f00560065007200730069006f006e003e003c004c006500760065006c003e0030003c002f004c006500760065006c003e003c005400610073006b003e00310032003500340034003c002f005400610073006b003e003c004f00700063006f00640065003e0030003c002f004f00700063006f00640065003e003c004b006500790077006f007200640073003e003000780038003000310030003000300030003000300030003000300030003000300030003c002f004b006500790077006f007200640073003e003c00540069006d00650043007200650061007400650064002000530079007300740065006d00540069006d0065003d00270032003000310039002d00300035002d00300035005400320033003a00310032003a00330037002e003300340039003400370036003100300030005a0027002f003e003c004500760065006e0074005200650063006f0072006400490044003e003600390034003600370034003c002f004500760065006e0074005200650063006f0072006400490044003e003c0043006f007200720065006c006100740069006f006e00200041006300740069007600690074007900490044003d0027007b00320035003200320035004600410031002d0044004100420039002d0030003000300031002d0041003600350046002d003200320032003500420039004400410044003400300031007d0027002f003e003c0045007800650063007500740069006f006e002000500072006f006300650073007300490044003d00270038003000340027002000540068007200650061006400490044003d002700310030003800300027002f003e003c004300680061006e006e0065006c003e00530065006300750072006900740079003c002f004300680061006e006e0065006c003e003c0043006f006d00700075007400650072003e0045004300320041004d0041005a002d0035004a00360049004600530046003c002f0043006f006d00700075007400650072003e003c00530065006300750072006900740079002f003e003c002f00530079007300740065006d003e003c004500760065006e00740044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a00650063007400550073006500720053006900640027003e0053002d0031002d0030002d0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a0065006300740055007300650072004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a0065006300740044006f006d00610069006e004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a006500630074004c006f0067006f006e004900640027003e003000780030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700540061007200670065007400550073006500720053006900640027003e0053002d0031002d0030002d0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270054006100720067006500740055007300650072004e0061006d00650027003e00410044004d0049004e004900530054005200410054004f0052003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270054006100720067006500740044006f006d00610069006e004e0061006d00650027003e003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270053007400610074007500730027003e0030007800630030003000300030003000360064003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004600610069006c0075007200650052006500610073006f006e0027003e002500250032003300310033003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270053007500620053007400610074007500730027003e0030007800630030003000300030003000360061003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006f0067006f006e00540079007000650027003e0033003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006f0067006f006e00500072006f0063006500730073004e0061006d00650027003e004e0074004c006d0053007300700020003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700410075007400680065006e007400690063006100740069006f006e005000610063006b006100670065004e0061006d00650027003e004e0054004c004d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270057006f0072006b00730074006100740069006f006e004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005400720061006e0073006d00690074007400650064005300650072007600690063006500730027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006d005000610063006b006100670065004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004b00650079004c0065006e0067007400680027003e0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700500072006f0063006500730073004900640027003e003000780030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700500072006f0063006500730073004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270049007000410064006400720065007300730027003e003100340036002e00350036002e0036002e003100360036003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004900700050006f007200740027003e0030003c002f0044006100740061003e003c002f004500760065006e00740044006100740061003e003c002f004500760065006e0074003e000000"
- data, _ := hex.DecodeString(originalHexStr)
- bufferUsed := len(data)
- bytes, _ := UTF16ToUTF8BytesForWindowsEventBuffer(data, uint32(bufferUsed))
- str := string(bytes[:])
- assert.Equal(t, "4625001254400x8010000000000000694674SecurityEC2AMAZ-5J6IFSFS-1-0-0--0x0S-1-0-0ADMINISTRATOR0xc000006d%%23130xc000006a3NtLmSsp NTLM---00x0-146.56.6.1660", str)
-
- // odd bytes test
- originalHexStr = "3c004500760065006e007400200078006d006c006e0073003d00270068007400740070003a002f002f0073006300680065006d00610073002e006d006900630072006f0073006f00660074002e0063006f006d002f00770069006e002f0032003000300034002f00300038002f006500760065006e00740073002f006500760065006e00740027003e003c00530079007300740065006d003e003c00500072006f007600690064006500720020004e0061006d0065003d0027004d006900630072006f0073006f00660074002d00570069006e0064006f00770073002d00530065006300750072006900740079002d004100750064006900740069006e0067002700200047007500690064003d0027007b00350034003800340039003600320035002d0035003400370038002d0034003900390034002d0041003500420041002d003300450033004200300033003200380043003300300044007d0027002f003e003c004500760065006e007400490044003e0034003600320035003c002f004500760065006e007400490044003e003c00560065007200730069006f006e003e0030003c002f00560065007200730069006f006e003e003c004c006500760065006c003e0030003c002f004c006500760065006c003e003c005400610073006b003e00310032003500340034003c002f005400610073006b003e003c004f00700063006f00640065003e0030003c002f004f00700063006f00640065003e003c004b006500790077006f007200640073003e003000780038003000310030003000300030003000300030003000300030003000300030003c002f004b006500790077006f007200640073003e003c00540069006d00650043007200650061007400650064002000530079007300740065006d00540069006d0065003d00270032003000310039002d00300035002d00300035005400320033003a00310032003a00330037002e003300340039003400370036003100300030005a0027002f003e003c004500760065006e0074005200650063006f0072006400490044003e003600390034003600370034003c002f004500760065006e0074005200650063006f0072006400490044003e003c0043006f007200720065006c006100740069006f006e00200041006300740069007600690074007900490044003d0027007b00320035003200320035004600410031002d0044004100420039002d0030003000300031002d0041003600350046002d003200320032003500420039004400410044003400300031007d0027002f003e003c0045007800650063007500740069006f006e002000500072006f006300650073007300490044003d00270038003000340027002000540068007200650061006400490044003d002700310030003800300027002f003e003c004300680061006e006e0065006c003e00530065006300750072006900740079003c002f004300680061006e006e0065006c003e003c0043006f006d00700075007400650072003e0045004300320041004d0041005a002d0035004a00360049004600530046003c002f0043006f006d00700075007400650072003e003c00530065006300750072006900740079002f003e003c002f00530079007300740065006d003e003c004500760065006e00740044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a00650063007400550073006500720053006900640027003e0053002d0031002d0030002d0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a0065006300740055007300650072004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a0065006300740044006f006d00610069006e004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a006500630074004c006f0067006f006e004900640027003e003000780030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700540061007200670065007400550073006500720053006900640027003e0053002d0031002d0030002d0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270054006100720067006500740055007300650072004e0061006d00650027003e00410044004d0049004e004900530054005200410054004f0052003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270054006100720067006500740044006f006d00610069006e004e0061006d00650027003e003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270053007400610074007500730027003e0030007800630030003000300030003000360064003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004600610069006c0075007200650052006500610073006f006e0027003e002500250032003300310033003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270053007500620053007400610074007500730027003e0030007800630030003000300030003000360061003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006f0067006f006e00540079007000650027003e0033003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006f0067006f006e00500072006f0063006500730073004e0061006d00650027003e004e0074004c006d0053007300700020003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700410075007400680065006e007400690063006100740069006f006e005000610063006b006100670065004e0061006d00650027003e004e0054004c004d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270057006f0072006b00730074006100740069006f006e004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005400720061006e0073006d00690074007400650064005300650072007600690063006500730027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006d005000610063006b006100670065004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004b00650079004c0065006e0067007400680027003e0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700500072006f0063006500730073004900640027003e003000780030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700500072006f0063006500730073004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270049007000410064006400720065007300730027003e003100340036002e00350036002e0036002e003100360036003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004900700050006f007200740027003e0030003c002f0044006100740061003e003c002f004500760065006e00740044006100740061003e003c002f004500760065006e0074003e00000000"
- data, _ = hex.DecodeString(originalHexStr)
- bufferUsed = len(data)
- bytes, _ = UTF16ToUTF8BytesForWindowsEventBuffer(data, uint32(bufferUsed))
- str = string(bytes[:])
- assert.Equal(t, "4625001254400x8010000000000000694674SecurityEC2AMAZ-5J6IFSFS-1-0-0--0x0S-1-0-0ADMINISTRATOR0xc000006d%%23130xc000006a3NtLmSsp NTLM---00x0-146.56.6.1660", str)
-
- // two nulls test
- originalHexStr = "3c004500760065006e007400200078006d006c006e0073003d00270068007400740070003a002f002f0073006300680065006d00610073002e006d006900630072006f0073006f00660074002e0063006f006d002f00770069006e002f0032003000300034002f00300038002f006500760065006e00740073002f006500760065006e00740027003e003c00530079007300740065006d003e003c00500072006f007600690064006500720020004e0061006d0065003d0027004d006900630072006f0073006f00660074002d00570069006e0064006f00770073002d00530065006300750072006900740079002d004100750064006900740069006e0067002700200047007500690064003d0027007b00350034003800340039003600320035002d0035003400370038002d0034003900390034002d0041003500420041002d003300450033004200300033003200380043003300300044007d0027002f003e003c004500760065006e007400490044003e0034003600320035003c002f004500760065006e007400490044003e003c00560065007200730069006f006e003e0030003c002f00560065007200730069006f006e003e003c004c006500760065006c003e0030003c002f004c006500760065006c003e003c005400610073006b003e00310032003500340034003c002f005400610073006b003e003c004f00700063006f00640065003e0030003c002f004f00700063006f00640065003e003c004b006500790077006f007200640073003e003000780038003000310030003000300030003000300030003000300030003000300030003c002f004b006500790077006f007200640073003e003c00540069006d00650043007200650061007400650064002000530079007300740065006d00540069006d0065003d00270032003000310039002d00300035002d00300035005400320033003a00310032003a00330037002e003300340039003400370036003100300030005a0027002f003e003c004500760065006e0074005200650063006f0072006400490044003e003600390034003600370034003c002f004500760065006e0074005200650063006f0072006400490044003e003c0043006f007200720065006c006100740069006f006e00200041006300740069007600690074007900490044003d0027007b00320035003200320035004600410031002d0044004100420039002d0030003000300031002d0041003600350046002d003200320032003500420039004400410044003400300031007d0027002f003e003c0045007800650063007500740069006f006e002000500072006f006300650073007300490044003d00270038003000340027002000540068007200650061006400490044003d002700310030003800300027002f003e003c004300680061006e006e0065006c003e00530065006300750072006900740079003c002f004300680061006e006e0065006c003e003c0043006f006d00700075007400650072003e0045004300320041004d0041005a002d0035004a00360049004600530046003c002f0043006f006d00700075007400650072003e003c00530065006300750072006900740079002f003e003c002f00530079007300740065006d003e003c004500760065006e00740044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a00650063007400550073006500720053006900640027003e0053002d0031002d0030002d0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a0065006300740055007300650072004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a0065006300740044006f006d00610069006e004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a006500630074004c006f0067006f006e004900640027003e003000780030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700540061007200670065007400550073006500720053006900640027003e0053002d0031002d0030002d0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270054006100720067006500740055007300650072004e0061006d00650027003e00410044004d0049004e004900530054005200410054004f0052003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270054006100720067006500740044006f006d00610069006e004e0061006d00650027003e003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270053007400610074007500730027003e0030007800630030003000300030003000360064003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004600610069006c0075007200650052006500610073006f006e0027003e002500250032003300310033003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270053007500620053007400610074007500730027003e0030007800630030003000300030003000360061003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006f0067006f006e00540079007000650027003e0033003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006f0067006f006e00500072006f0063006500730073004e0061006d00650027003e004e0074004c006d0053007300700020003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700410075007400680065006e007400690063006100740069006f006e005000610063006b006100670065004e0061006d00650027003e004e0054004c004d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270057006f0072006b00730074006100740069006f006e004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005400720061006e0073006d00690074007400650064005300650072007600690063006500730027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006d005000610063006b006100670065004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004b00650079004c0065006e0067007400680027003e0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700500072006f0063006500730073004900640027003e003000780030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700500072006f0063006500730073004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270049007000410064006400720065007300730027003e003100340036002e00350036002e0036002e003100360036003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004900700050006f007200740027003e0030003c002f0044006100740061003e003c002f004500760065006e00740044006100740061003e003c002f004500760065006e0074003e000000000000"
- data, _ = hex.DecodeString(originalHexStr)
- bufferUsed = len(data)
- bytes, _ = UTF16ToUTF8BytesForWindowsEventBuffer(data, uint32(bufferUsed))
- str = string(bytes[:])
- assert.Equal(t, "4625001254400x8010000000000000694674SecurityEC2AMAZ-5J6IFSFS-1-0-0--0x0S-1-0-0ADMINISTRATOR0xc000006d%%23130xc000006a3NtLmSsp NTLM---00x0-146.56.6.1660", str)
-
-}
-
-func TestDecodingWithDifferentBufferUsedReturned(t *testing.T) {
- // one null test
- resetState()
- originalHexStr := "3c004500760065006e007400200078006d006c006e0073003d00270068007400740070003a002f002f0073006300680065006d00610073002e006d006900630072006f0073006f00660074002e0063006f006d002f00770069006e002f0032003000300034002f00300038002f006500760065006e00740073002f006500760065006e00740027003e003c00530079007300740065006d003e003c00500072006f007600690064006500720020004e0061006d0065003d0027004d006900630072006f0073006f00660074002d00570069006e0064006f00770073002d00530065006300750072006900740079002d004100750064006900740069006e0067002700200047007500690064003d0027007b00350034003800340039003600320035002d0035003400370038002d0034003900390034002d0041003500420041002d003300450033004200300033003200380043003300300044007d0027002f003e003c004500760065006e007400490044003e0034003600320035003c002f004500760065006e007400490044003e003c00560065007200730069006f006e003e0030003c002f00560065007200730069006f006e003e003c004c006500760065006c003e0030003c002f004c006500760065006c003e003c005400610073006b003e00310032003500340034003c002f005400610073006b003e003c004f00700063006f00640065003e0030003c002f004f00700063006f00640065003e003c004b006500790077006f007200640073003e003000780038003000310030003000300030003000300030003000300030003000300030003c002f004b006500790077006f007200640073003e003c00540069006d00650043007200650061007400650064002000530079007300740065006d00540069006d0065003d00270032003000310039002d00300035002d00300035005400320033003a00310032003a00330037002e003300340039003400370036003100300030005a0027002f003e003c004500760065006e0074005200650063006f0072006400490044003e003600390034003600370034003c002f004500760065006e0074005200650063006f0072006400490044003e003c0043006f007200720065006c006100740069006f006e00200041006300740069007600690074007900490044003d0027007b00320035003200320035004600410031002d0044004100420039002d0030003000300031002d0041003600350046002d003200320032003500420039004400410044003400300031007d0027002f003e003c0045007800650063007500740069006f006e002000500072006f006300650073007300490044003d00270038003000340027002000540068007200650061006400490044003d002700310030003800300027002f003e003c004300680061006e006e0065006c003e00530065006300750072006900740079003c002f004300680061006e006e0065006c003e003c0043006f006d00700075007400650072003e0045004300320041004d0041005a002d0035004a00360049004600530046003c002f0043006f006d00700075007400650072003e003c00530065006300750072006900740079002f003e003c002f00530079007300740065006d003e003c004500760065006e00740044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a00650063007400550073006500720053006900640027003e0053002d0031002d0030002d0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a0065006300740055007300650072004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a0065006300740044006f006d00610069006e004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a006500630074004c006f0067006f006e004900640027003e003000780030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700540061007200670065007400550073006500720053006900640027003e0053002d0031002d0030002d0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270054006100720067006500740055007300650072004e0061006d00650027003e00410044004d0049004e004900530054005200410054004f0052003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270054006100720067006500740044006f006d00610069006e004e0061006d00650027003e003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270053007400610074007500730027003e0030007800630030003000300030003000360064003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004600610069006c0075007200650052006500610073006f006e0027003e002500250032003300310033003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270053007500620053007400610074007500730027003e0030007800630030003000300030003000360061003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006f0067006f006e00540079007000650027003e0033003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006f0067006f006e00500072006f0063006500730073004e0061006d00650027003e004e0074004c006d0053007300700020003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700410075007400680065006e007400690063006100740069006f006e005000610063006b006100670065004e0061006d00650027003e004e0054004c004d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270057006f0072006b00730074006100740069006f006e004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005400720061006e0073006d00690074007400650064005300650072007600690063006500730027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006d005000610063006b006100670065004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004b00650079004c0065006e0067007400680027003e0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700500072006f0063006500730073004900640027003e003000780030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700500072006f0063006500730073004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270049007000410064006400720065007300730027003e003100340036002e00350036002e0036002e003100360036003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004900700050006f007200740027003e0030003c002f0044006100740061003e003c002f004500760065006e00740044006100740061003e003c002f004500760065006e0074003e000000"
- data, _ := hex.DecodeString(originalHexStr)
- bufferUsed := len(data) / 2
- bytes, _ := UTF16ToUTF8BytesForWindowsEventBuffer(data, uint32(bufferUsed))
- str := string(bytes[:])
- assert.Equal(t, "4625001254400x8010000000000000694674SecurityEC2AMAZ-5J6IFSFS-1-0-0--0x0S-1-0-0ADMINISTRATOR0xc000006d%%23130xc000006a3NtLmSsp NTLM---00x0-146.56.6.1660", str)
-
- // odd bytes test
- originalHexStr = "3c004500760065006e007400200078006d006c006e0073003d00270068007400740070003a002f002f0073006300680065006d00610073002e006d006900630072006f0073006f00660074002e0063006f006d002f00770069006e002f0032003000300034002f00300038002f006500760065006e00740073002f006500760065006e00740027003e003c00530079007300740065006d003e003c00500072006f007600690064006500720020004e0061006d0065003d0027004d006900630072006f0073006f00660074002d00570069006e0064006f00770073002d00530065006300750072006900740079002d004100750064006900740069006e0067002700200047007500690064003d0027007b00350034003800340039003600320035002d0035003400370038002d0034003900390034002d0041003500420041002d003300450033004200300033003200380043003300300044007d0027002f003e003c004500760065006e007400490044003e0034003600320035003c002f004500760065006e007400490044003e003c00560065007200730069006f006e003e0030003c002f00560065007200730069006f006e003e003c004c006500760065006c003e0030003c002f004c006500760065006c003e003c005400610073006b003e00310032003500340034003c002f005400610073006b003e003c004f00700063006f00640065003e0030003c002f004f00700063006f00640065003e003c004b006500790077006f007200640073003e003000780038003000310030003000300030003000300030003000300030003000300030003c002f004b006500790077006f007200640073003e003c00540069006d00650043007200650061007400650064002000530079007300740065006d00540069006d0065003d00270032003000310039002d00300035002d00300035005400320033003a00310032003a00330037002e003300340039003400370036003100300030005a0027002f003e003c004500760065006e0074005200650063006f0072006400490044003e003600390034003600370034003c002f004500760065006e0074005200650063006f0072006400490044003e003c0043006f007200720065006c006100740069006f006e00200041006300740069007600690074007900490044003d0027007b00320035003200320035004600410031002d0044004100420039002d0030003000300031002d0041003600350046002d003200320032003500420039004400410044003400300031007d0027002f003e003c0045007800650063007500740069006f006e002000500072006f006300650073007300490044003d00270038003000340027002000540068007200650061006400490044003d002700310030003800300027002f003e003c004300680061006e006e0065006c003e00530065006300750072006900740079003c002f004300680061006e006e0065006c003e003c0043006f006d00700075007400650072003e0045004300320041004d0041005a002d0035004a00360049004600530046003c002f0043006f006d00700075007400650072003e003c00530065006300750072006900740079002f003e003c002f00530079007300740065006d003e003c004500760065006e00740044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a00650063007400550073006500720053006900640027003e0053002d0031002d0030002d0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a0065006300740055007300650072004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a0065006300740044006f006d00610069006e004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a006500630074004c006f0067006f006e004900640027003e003000780030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700540061007200670065007400550073006500720053006900640027003e0053002d0031002d0030002d0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270054006100720067006500740055007300650072004e0061006d00650027003e00410044004d0049004e004900530054005200410054004f0052003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270054006100720067006500740044006f006d00610069006e004e0061006d00650027003e003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270053007400610074007500730027003e0030007800630030003000300030003000360064003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004600610069006c0075007200650052006500610073006f006e0027003e002500250032003300310033003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270053007500620053007400610074007500730027003e0030007800630030003000300030003000360061003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006f0067006f006e00540079007000650027003e0033003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006f0067006f006e00500072006f0063006500730073004e0061006d00650027003e004e0074004c006d0053007300700020003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700410075007400680065006e007400690063006100740069006f006e005000610063006b006100670065004e0061006d00650027003e004e0054004c004d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270057006f0072006b00730074006100740069006f006e004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005400720061006e0073006d00690074007400650064005300650072007600690063006500730027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006d005000610063006b006100670065004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004b00650079004c0065006e0067007400680027003e0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700500072006f0063006500730073004900640027003e003000780030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700500072006f0063006500730073004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270049007000410064006400720065007300730027003e003100340036002e00350036002e0036002e003100360036003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004900700050006f007200740027003e0030003c002f0044006100740061003e003c002f004500760065006e00740044006100740061003e003c002f004500760065006e0074003e00000000"
- data, _ = hex.DecodeString(originalHexStr)
- bufferUsed = len(data) / 2
- bytes, _ = UTF16ToUTF8BytesForWindowsEventBuffer(data, uint32(bufferUsed))
- str = string(bytes[:])
- assert.Equal(t, "4625001254400x8010000000000000694674SecurityEC2AMAZ-5J6IFSFS-1-0-0--0x0S-1-0-0ADMINISTRATOR0xc000006d%%23130xc000006a3NtLmSsp NTLM---00x0-146.56.6.1660", str)
-
-}
-
-func TestFullBufferUsedWithHalfUsedSizeReturned(t *testing.T) {
- resetState()
- cap := 1 << 10
- data := make([]byte, cap)
- data[0] = 'a'
- for i := 2; i < cap; i *= 2 {
- copy(data[i:], data[:i])
- }
- bufferUsed := cap / 2
-
- bytes, _ := UTF16ToUTF8BytesForWindowsEventBuffer(data, uint32(bufferUsed))
- str := string(bytes[:])
- assert.Equal(t, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", str)
- assert.Equal(t, bufferUsed, len(str))
-}
-
-func TestInsertPlaceholderValues(t *testing.T) {
- evtDataValues := []Datum{
- {"value_1"}, {"value_2"}, {"value_3"}, {"value_4"},
- }
+func TestCreateFilterQuery(t *testing.T) {
tests := []struct {
name string
- message string
- expected string
+ levels []string
+ eventIDs []int
+ want string
}{
{
- "Placeholders %{number} should be replaced by insertion strings",
- "Service %1 in region %3 stop at %2",
- "Service value_1 in region value_3 stop at value_2",
- },
- {
- "String without a placeholder should remain the same after insertion",
- "This is a sentence without placeholders",
- "This is a sentence without placeholders",
- },
- {
- "Empty string should remain the same",
- "",
- "",
- },
- {
- "Index should start from 1 and less than or equal to the amount of values in event data",
- "%0 %3 %5",
- "%0 value_3 %5",
+ name: "levels_Test",
+ levels: []string{"Error", "Critical"},
+ eventIDs: []int{},
+ want: "*[System[(Level='Error' or Level='Critical') and TimeCreated[timediff(@SystemTime) <= 1209600000]]]",
},
{
- "Handle consecutive % characters",
- "%1 %%3% %2",
- "value_1 %value_3% value_2",
+ name: "EventID_Test",
+ levels: []string{},
+ eventIDs: []int{1001, 1002},
+ want: "*[System[(EventID='1001' or EventID='1002') and TimeCreated[timediff(@SystemTime) <= 1209600000]]]",
},
{
- "Handle % character at the end of message",
- "%3 %2%",
- "value_3 value_2%",
+ name: "levels_EventID_Test",
+ levels: []string{"Error", "Critical"},
+ eventIDs: []int{4625, 4624},
+ want: "*[System[(Level='Error' or Level='Critical') and (EventID='4625' or EventID='4624') and TimeCreated[timediff(@SystemTime) <= 1209600000]]]",
},
{
- "Characters after a % other than numbers should be ignored",
- "%foo, %foo1, %#$%^&1",
- "%foo, %foo1, %#$%^&1",
+ name: "no_Input",
+ levels: []string{},
+ eventIDs: []int{},
+ want: "*[System[TimeCreated[timediff(@SystemTime) <= 1209600000]]]",
},
}
- for _, tc := range tests {
- t.Run(tc.name, func(t *testing.T) {
- assert.Equal(t, tc.expected, insertPlaceholderValues(tc.message, evtDataValues))
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ got := createFilterQuery(tt.levels, tt.eventIDs)
+ assert.Equal(t, tt.want, got)
+
})
}
}
-
-func resetState() {
- NumberOfBytesPerCharacter = 0
-}
diff --git a/plugins/inputs/windows_event_log/wineventlog/utils_windows.go b/plugins/inputs/windows_event_log/wineventlog/utils_windows.go
new file mode 100644
index 0000000000..4f02167de2
--- /dev/null
+++ b/plugins/inputs/windows_event_log/wineventlog/utils_windows.go
@@ -0,0 +1,189 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: MIT
+
+//go:build windows
+// +build windows
+
+package wineventlog
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "log"
+ "strconv"
+ "strings"
+ "syscall"
+
+ "golang.org/x/text/encoding/unicode"
+ "golang.org/x/text/transform"
+)
+
+var NumberOfBytesPerCharacter = UnknownBytesPerCharacter
+
+func RenderEventXML(eventHandle EvtHandle, renderBuf []byte) ([]byte, error) {
+ var bufferUsed, propertyCount uint32
+
+ if err := EvtRender(0, eventHandle, EvtRenderEventXml, uint32(len(renderBuf)), &renderBuf[0], &bufferUsed, &propertyCount); err != nil {
+ return nil, fmt.Errorf("error when rendering events. Details: %v", err)
+ }
+
+ // Per MSDN as of Mar 14th 2022(https://docs.microsoft.com/en-us/windows/win32/api/winevt/nf-winevt-evtrender)
+ // EvtRender function is still returning buffer used as BYTES, not characters. So keep using utf16ToUTF8Bytes()
+ return utf16ToUTF8Bytes(renderBuf, bufferUsed)
+}
+
+func CreateBookmark(channel string, recordID uint64) (h EvtHandle, err error) {
+ xml := fmt.Sprintf(bookmarkTemplate, channel, recordID)
+ p, err := syscall.UTF16PtrFromString(xml)
+ if err != nil {
+ return 0, err
+ }
+ h, err = EvtCreateBookmark(p)
+ if err != nil {
+ return 0, fmt.Errorf("error when creating a bookmark. Details: %v", err)
+ }
+ return h, nil
+}
+
+func CreateQuery(path string, levels []string, eventIDs []int) (*uint16, error) {
+
+ query := createFilterQuery(levels, eventIDs)
+
+ xml := fmt.Sprintf(eventLogQueryTemplate, path, query)
+ return syscall.UTF16PtrFromString(xml)
+}
+
+func utf16ToUTF8Bytes(in []byte, length uint32) ([]byte, error) {
+
+ i := length
+
+ if length%2 != 0 {
+ i = length - 1
+ }
+
+ for ; i-2 > 0; i -= 2 {
+ v1 := uint16(in[i-2]) | uint16(in[i-1])<<8
+ // Stop at non-null char.
+ if v1 != 0 {
+ break
+ }
+ }
+
+ win16be := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM)
+ utf16bom := unicode.BOMOverride(win16be.NewDecoder())
+ unicodeReader := transform.NewReader(bytes.NewReader(in[:i]), utf16bom)
+ decoded, err := io.ReadAll(unicodeReader)
+ return decoded, err
+}
+
+func UTF16ToUTF8BytesForWindowsEventBuffer(in []byte, length uint32) ([]byte, error) {
+ // Since Windows server 2022, the returned value of used buffer represents for double bytes char count,
+ // which is half of the actual buffer used by byte(what older Windows OS returns), checking if the length
+ //land on the end of used buffer, if no, double it.
+ if NumberOfBytesPerCharacter == UnknownBytesPerCharacter {
+ if isTheEndOfContent(in, length) {
+ log.Printf("I! Buffer used: %d is returning as single byte character count", length)
+ NumberOfBytesPerCharacter = 1
+ } else {
+ log.Printf("I! Buffer used: %d is returning as double byte character count, doubling it to get the whole buffer content.", length)
+ NumberOfBytesPerCharacter = 2
+ }
+ }
+
+ i := int(length) * NumberOfBytesPerCharacter
+
+ if i > cap(in) {
+ i = cap(in)
+ }
+
+ return utf16ToUTF8Bytes(in, uint32(i))
+}
+
+func isTheEndOfContent(in []byte, length uint32) bool {
+ // scan next (emptySpaceScanLength) bytes, if any of them is none '0', return false
+ i := int(length)
+
+ if i%2 != 0 {
+ i -= 1
+ }
+ max := len(in)
+ if i+emptySpaceScanLength < max {
+ max = i + emptySpaceScanLength
+ }
+
+ for ; i < max-2; i += 2 {
+ v1 := uint16(in[i+2]) | uint16(in[i+1])<<8
+ // Stop at non-null char.
+ if v1 != 0 {
+ return false
+ }
+ }
+ return true
+}
+
+func WindowsEventLogLevelName(levelId int32) string {
+ switch levelId {
+ case 1:
+ return CRITICAL
+ case 2:
+ return ERROR
+ case 3:
+ return WARNING
+ case 0, 4:
+ return INFORMATION
+ case 5:
+ return VERBOSE
+ default:
+ return UNKNOWN
+ }
+}
+
+// insertPlaceholderValues formats the message with the correct values if we see those data
+// in evtDataValues.
+//
+// In some cases wevtapi does not insert values when formatting the message. The message
+// will contain insertion string placeholders, of the form %n, where %1 indicates the first
+// insertion string, and so on. Noted that wevtapi start the index with 1.
+// https://learn.microsoft.com/en-us/windows/win32/eventlog/event-identifiers#insertion-strings
+func insertPlaceholderValues(rawMessage string, evtDataValues []Datum) string {
+ if len(evtDataValues) == 0 || len(rawMessage) == 0 {
+ return rawMessage
+ }
+ var sb strings.Builder
+ prevIndex := 0
+ searchingIndex := false
+ for i, c := range rawMessage {
+ // found `%` previously. Determine the index number from the following character(s)
+ if searchingIndex && (c > '9' || c < '0') {
+ // Convert the Slice since the last `%` and see if it's a valid number.
+ ind, err := strconv.Atoi(rawMessage[prevIndex+1 : i])
+ // If the index is in [1 - len(evtDataValues)], get it from evtDataValues.
+ if err == nil && ind <= len(evtDataValues) && ind > 0 {
+ sb.WriteString(evtDataValues[ind-1].Value)
+ } else {
+ sb.WriteString(rawMessage[prevIndex:i])
+ }
+ prevIndex = i
+ // In case of consecutive `%`, continue searching for the next index
+ if c != '%' {
+ searchingIndex = false
+ }
+ } else {
+ if c == '%' {
+ sb.WriteString(rawMessage[prevIndex:i])
+ searchingIndex = true
+ prevIndex = i
+ }
+
+ }
+ }
+ // handle the slice since the last `%` to the end of rawMessage
+ ind, err := strconv.Atoi(rawMessage[prevIndex+1:])
+ if searchingIndex && err == nil && ind <= len(evtDataValues) && ind > 0 {
+ sb.WriteString(evtDataValues[ind-1].Value)
+ } else {
+ sb.WriteString(rawMessage[prevIndex:])
+ }
+ return sb.String()
+}
diff --git a/plugins/inputs/windows_event_log/wineventlog/utils_windows_test.go b/plugins/inputs/windows_event_log/wineventlog/utils_windows_test.go
new file mode 100644
index 0000000000..40586504d3
--- /dev/null
+++ b/plugins/inputs/windows_event_log/wineventlog/utils_windows_test.go
@@ -0,0 +1,134 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: MIT
+
+//go:build windows
+// +build windows
+
+package wineventlog
+
+import (
+ "encoding/hex"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestPayload_Value(t *testing.T) {
+ // one null test
+ resetState()
+ originalHexStr := "3c004500760065006e007400200078006d006c006e0073003d00270068007400740070003a002f002f0073006300680065006d00610073002e006d006900630072006f0073006f00660074002e0063006f006d002f00770069006e002f0032003000300034002f00300038002f006500760065006e00740073002f006500760065006e00740027003e003c00530079007300740065006d003e003c00500072006f007600690064006500720020004e0061006d0065003d0027004d006900630072006f0073006f00660074002d00570069006e0064006f00770073002d00530065006300750072006900740079002d004100750064006900740069006e0067002700200047007500690064003d0027007b00350034003800340039003600320035002d0035003400370038002d0034003900390034002d0041003500420041002d003300450033004200300033003200380043003300300044007d0027002f003e003c004500760065006e007400490044003e0034003600320035003c002f004500760065006e007400490044003e003c00560065007200730069006f006e003e0030003c002f00560065007200730069006f006e003e003c004c006500760065006c003e0030003c002f004c006500760065006c003e003c005400610073006b003e00310032003500340034003c002f005400610073006b003e003c004f00700063006f00640065003e0030003c002f004f00700063006f00640065003e003c004b006500790077006f007200640073003e003000780038003000310030003000300030003000300030003000300030003000300030003c002f004b006500790077006f007200640073003e003c00540069006d00650043007200650061007400650064002000530079007300740065006d00540069006d0065003d00270032003000310039002d00300035002d00300035005400320033003a00310032003a00330037002e003300340039003400370036003100300030005a0027002f003e003c004500760065006e0074005200650063006f0072006400490044003e003600390034003600370034003c002f004500760065006e0074005200650063006f0072006400490044003e003c0043006f007200720065006c006100740069006f006e00200041006300740069007600690074007900490044003d0027007b00320035003200320035004600410031002d0044004100420039002d0030003000300031002d0041003600350046002d003200320032003500420039004400410044003400300031007d0027002f003e003c0045007800650063007500740069006f006e002000500072006f006300650073007300490044003d00270038003000340027002000540068007200650061006400490044003d002700310030003800300027002f003e003c004300680061006e006e0065006c003e00530065006300750072006900740079003c002f004300680061006e006e0065006c003e003c0043006f006d00700075007400650072003e0045004300320041004d0041005a002d0035004a00360049004600530046003c002f0043006f006d00700075007400650072003e003c00530065006300750072006900740079002f003e003c002f00530079007300740065006d003e003c004500760065006e00740044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a00650063007400550073006500720053006900640027003e0053002d0031002d0030002d0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a0065006300740055007300650072004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a0065006300740044006f006d00610069006e004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a006500630074004c006f0067006f006e004900640027003e003000780030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700540061007200670065007400550073006500720053006900640027003e0053002d0031002d0030002d0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270054006100720067006500740055007300650072004e0061006d00650027003e00410044004d0049004e004900530054005200410054004f0052003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270054006100720067006500740044006f006d00610069006e004e0061006d00650027003e003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270053007400610074007500730027003e0030007800630030003000300030003000360064003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004600610069006c0075007200650052006500610073006f006e0027003e002500250032003300310033003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270053007500620053007400610074007500730027003e0030007800630030003000300030003000360061003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006f0067006f006e00540079007000650027003e0033003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006f0067006f006e00500072006f0063006500730073004e0061006d00650027003e004e0074004c006d0053007300700020003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700410075007400680065006e007400690063006100740069006f006e005000610063006b006100670065004e0061006d00650027003e004e0054004c004d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270057006f0072006b00730074006100740069006f006e004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005400720061006e0073006d00690074007400650064005300650072007600690063006500730027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006d005000610063006b006100670065004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004b00650079004c0065006e0067007400680027003e0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700500072006f0063006500730073004900640027003e003000780030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700500072006f0063006500730073004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270049007000410064006400720065007300730027003e003100340036002e00350036002e0036002e003100360036003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004900700050006f007200740027003e0030003c002f0044006100740061003e003c002f004500760065006e00740044006100740061003e003c002f004500760065006e0074003e000000"
+ data, _ := hex.DecodeString(originalHexStr)
+ bufferUsed := len(data)
+ bytes, _ := UTF16ToUTF8BytesForWindowsEventBuffer(data, uint32(bufferUsed))
+ str := string(bytes[:])
+ assert.Equal(t, "4625001254400x8010000000000000694674SecurityEC2AMAZ-5J6IFSFS-1-0-0--0x0S-1-0-0ADMINISTRATOR0xc000006d%%23130xc000006a3NtLmSsp NTLM---00x0-146.56.6.1660", str)
+
+ // odd bytes test
+ originalHexStr = "3c004500760065006e007400200078006d006c006e0073003d00270068007400740070003a002f002f0073006300680065006d00610073002e006d006900630072006f0073006f00660074002e0063006f006d002f00770069006e002f0032003000300034002f00300038002f006500760065006e00740073002f006500760065006e00740027003e003c00530079007300740065006d003e003c00500072006f007600690064006500720020004e0061006d0065003d0027004d006900630072006f0073006f00660074002d00570069006e0064006f00770073002d00530065006300750072006900740079002d004100750064006900740069006e0067002700200047007500690064003d0027007b00350034003800340039003600320035002d0035003400370038002d0034003900390034002d0041003500420041002d003300450033004200300033003200380043003300300044007d0027002f003e003c004500760065006e007400490044003e0034003600320035003c002f004500760065006e007400490044003e003c00560065007200730069006f006e003e0030003c002f00560065007200730069006f006e003e003c004c006500760065006c003e0030003c002f004c006500760065006c003e003c005400610073006b003e00310032003500340034003c002f005400610073006b003e003c004f00700063006f00640065003e0030003c002f004f00700063006f00640065003e003c004b006500790077006f007200640073003e003000780038003000310030003000300030003000300030003000300030003000300030003c002f004b006500790077006f007200640073003e003c00540069006d00650043007200650061007400650064002000530079007300740065006d00540069006d0065003d00270032003000310039002d00300035002d00300035005400320033003a00310032003a00330037002e003300340039003400370036003100300030005a0027002f003e003c004500760065006e0074005200650063006f0072006400490044003e003600390034003600370034003c002f004500760065006e0074005200650063006f0072006400490044003e003c0043006f007200720065006c006100740069006f006e00200041006300740069007600690074007900490044003d0027007b00320035003200320035004600410031002d0044004100420039002d0030003000300031002d0041003600350046002d003200320032003500420039004400410044003400300031007d0027002f003e003c0045007800650063007500740069006f006e002000500072006f006300650073007300490044003d00270038003000340027002000540068007200650061006400490044003d002700310030003800300027002f003e003c004300680061006e006e0065006c003e00530065006300750072006900740079003c002f004300680061006e006e0065006c003e003c0043006f006d00700075007400650072003e0045004300320041004d0041005a002d0035004a00360049004600530046003c002f0043006f006d00700075007400650072003e003c00530065006300750072006900740079002f003e003c002f00530079007300740065006d003e003c004500760065006e00740044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a00650063007400550073006500720053006900640027003e0053002d0031002d0030002d0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a0065006300740055007300650072004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a0065006300740044006f006d00610069006e004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a006500630074004c006f0067006f006e004900640027003e003000780030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700540061007200670065007400550073006500720053006900640027003e0053002d0031002d0030002d0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270054006100720067006500740055007300650072004e0061006d00650027003e00410044004d0049004e004900530054005200410054004f0052003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270054006100720067006500740044006f006d00610069006e004e0061006d00650027003e003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270053007400610074007500730027003e0030007800630030003000300030003000360064003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004600610069006c0075007200650052006500610073006f006e0027003e002500250032003300310033003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270053007500620053007400610074007500730027003e0030007800630030003000300030003000360061003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006f0067006f006e00540079007000650027003e0033003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006f0067006f006e00500072006f0063006500730073004e0061006d00650027003e004e0074004c006d0053007300700020003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700410075007400680065006e007400690063006100740069006f006e005000610063006b006100670065004e0061006d00650027003e004e0054004c004d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270057006f0072006b00730074006100740069006f006e004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005400720061006e0073006d00690074007400650064005300650072007600690063006500730027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006d005000610063006b006100670065004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004b00650079004c0065006e0067007400680027003e0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700500072006f0063006500730073004900640027003e003000780030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700500072006f0063006500730073004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270049007000410064006400720065007300730027003e003100340036002e00350036002e0036002e003100360036003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004900700050006f007200740027003e0030003c002f0044006100740061003e003c002f004500760065006e00740044006100740061003e003c002f004500760065006e0074003e00000000"
+ data, _ = hex.DecodeString(originalHexStr)
+ bufferUsed = len(data)
+ bytes, _ = UTF16ToUTF8BytesForWindowsEventBuffer(data, uint32(bufferUsed))
+ str = string(bytes[:])
+ assert.Equal(t, "4625001254400x8010000000000000694674SecurityEC2AMAZ-5J6IFSFS-1-0-0--0x0S-1-0-0ADMINISTRATOR0xc000006d%%23130xc000006a3NtLmSsp NTLM---00x0-146.56.6.1660", str)
+
+ // two nulls test
+ originalHexStr = "3c004500760065006e007400200078006d006c006e0073003d00270068007400740070003a002f002f0073006300680065006d00610073002e006d006900630072006f0073006f00660074002e0063006f006d002f00770069006e002f0032003000300034002f00300038002f006500760065006e00740073002f006500760065006e00740027003e003c00530079007300740065006d003e003c00500072006f007600690064006500720020004e0061006d0065003d0027004d006900630072006f0073006f00660074002d00570069006e0064006f00770073002d00530065006300750072006900740079002d004100750064006900740069006e0067002700200047007500690064003d0027007b00350034003800340039003600320035002d0035003400370038002d0034003900390034002d0041003500420041002d003300450033004200300033003200380043003300300044007d0027002f003e003c004500760065006e007400490044003e0034003600320035003c002f004500760065006e007400490044003e003c00560065007200730069006f006e003e0030003c002f00560065007200730069006f006e003e003c004c006500760065006c003e0030003c002f004c006500760065006c003e003c005400610073006b003e00310032003500340034003c002f005400610073006b003e003c004f00700063006f00640065003e0030003c002f004f00700063006f00640065003e003c004b006500790077006f007200640073003e003000780038003000310030003000300030003000300030003000300030003000300030003c002f004b006500790077006f007200640073003e003c00540069006d00650043007200650061007400650064002000530079007300740065006d00540069006d0065003d00270032003000310039002d00300035002d00300035005400320033003a00310032003a00330037002e003300340039003400370036003100300030005a0027002f003e003c004500760065006e0074005200650063006f0072006400490044003e003600390034003600370034003c002f004500760065006e0074005200650063006f0072006400490044003e003c0043006f007200720065006c006100740069006f006e00200041006300740069007600690074007900490044003d0027007b00320035003200320035004600410031002d0044004100420039002d0030003000300031002d0041003600350046002d003200320032003500420039004400410044003400300031007d0027002f003e003c0045007800650063007500740069006f006e002000500072006f006300650073007300490044003d00270038003000340027002000540068007200650061006400490044003d002700310030003800300027002f003e003c004300680061006e006e0065006c003e00530065006300750072006900740079003c002f004300680061006e006e0065006c003e003c0043006f006d00700075007400650072003e0045004300320041004d0041005a002d0035004a00360049004600530046003c002f0043006f006d00700075007400650072003e003c00530065006300750072006900740079002f003e003c002f00530079007300740065006d003e003c004500760065006e00740044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a00650063007400550073006500720053006900640027003e0053002d0031002d0030002d0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a0065006300740055007300650072004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a0065006300740044006f006d00610069006e004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a006500630074004c006f0067006f006e004900640027003e003000780030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700540061007200670065007400550073006500720053006900640027003e0053002d0031002d0030002d0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270054006100720067006500740055007300650072004e0061006d00650027003e00410044004d0049004e004900530054005200410054004f0052003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270054006100720067006500740044006f006d00610069006e004e0061006d00650027003e003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270053007400610074007500730027003e0030007800630030003000300030003000360064003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004600610069006c0075007200650052006500610073006f006e0027003e002500250032003300310033003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270053007500620053007400610074007500730027003e0030007800630030003000300030003000360061003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006f0067006f006e00540079007000650027003e0033003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006f0067006f006e00500072006f0063006500730073004e0061006d00650027003e004e0074004c006d0053007300700020003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700410075007400680065006e007400690063006100740069006f006e005000610063006b006100670065004e0061006d00650027003e004e0054004c004d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270057006f0072006b00730074006100740069006f006e004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005400720061006e0073006d00690074007400650064005300650072007600690063006500730027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006d005000610063006b006100670065004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004b00650079004c0065006e0067007400680027003e0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700500072006f0063006500730073004900640027003e003000780030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700500072006f0063006500730073004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270049007000410064006400720065007300730027003e003100340036002e00350036002e0036002e003100360036003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004900700050006f007200740027003e0030003c002f0044006100740061003e003c002f004500760065006e00740044006100740061003e003c002f004500760065006e0074003e000000000000"
+ data, _ = hex.DecodeString(originalHexStr)
+ bufferUsed = len(data)
+ bytes, _ = UTF16ToUTF8BytesForWindowsEventBuffer(data, uint32(bufferUsed))
+ str = string(bytes[:])
+ assert.Equal(t, "4625001254400x8010000000000000694674SecurityEC2AMAZ-5J6IFSFS-1-0-0--0x0S-1-0-0ADMINISTRATOR0xc000006d%%23130xc000006a3NtLmSsp NTLM---00x0-146.56.6.1660", str)
+
+}
+
+func TestDecodingWithDifferentBufferUsedReturned(t *testing.T) {
+ // one null test
+ resetState()
+ originalHexStr := "3c004500760065006e007400200078006d006c006e0073003d00270068007400740070003a002f002f0073006300680065006d00610073002e006d006900630072006f0073006f00660074002e0063006f006d002f00770069006e002f0032003000300034002f00300038002f006500760065006e00740073002f006500760065006e00740027003e003c00530079007300740065006d003e003c00500072006f007600690064006500720020004e0061006d0065003d0027004d006900630072006f0073006f00660074002d00570069006e0064006f00770073002d00530065006300750072006900740079002d004100750064006900740069006e0067002700200047007500690064003d0027007b00350034003800340039003600320035002d0035003400370038002d0034003900390034002d0041003500420041002d003300450033004200300033003200380043003300300044007d0027002f003e003c004500760065006e007400490044003e0034003600320035003c002f004500760065006e007400490044003e003c00560065007200730069006f006e003e0030003c002f00560065007200730069006f006e003e003c004c006500760065006c003e0030003c002f004c006500760065006c003e003c005400610073006b003e00310032003500340034003c002f005400610073006b003e003c004f00700063006f00640065003e0030003c002f004f00700063006f00640065003e003c004b006500790077006f007200640073003e003000780038003000310030003000300030003000300030003000300030003000300030003c002f004b006500790077006f007200640073003e003c00540069006d00650043007200650061007400650064002000530079007300740065006d00540069006d0065003d00270032003000310039002d00300035002d00300035005400320033003a00310032003a00330037002e003300340039003400370036003100300030005a0027002f003e003c004500760065006e0074005200650063006f0072006400490044003e003600390034003600370034003c002f004500760065006e0074005200650063006f0072006400490044003e003c0043006f007200720065006c006100740069006f006e00200041006300740069007600690074007900490044003d0027007b00320035003200320035004600410031002d0044004100420039002d0030003000300031002d0041003600350046002d003200320032003500420039004400410044003400300031007d0027002f003e003c0045007800650063007500740069006f006e002000500072006f006300650073007300490044003d00270038003000340027002000540068007200650061006400490044003d002700310030003800300027002f003e003c004300680061006e006e0065006c003e00530065006300750072006900740079003c002f004300680061006e006e0065006c003e003c0043006f006d00700075007400650072003e0045004300320041004d0041005a002d0035004a00360049004600530046003c002f0043006f006d00700075007400650072003e003c00530065006300750072006900740079002f003e003c002f00530079007300740065006d003e003c004500760065006e00740044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a00650063007400550073006500720053006900640027003e0053002d0031002d0030002d0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a0065006300740055007300650072004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a0065006300740044006f006d00610069006e004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a006500630074004c006f0067006f006e004900640027003e003000780030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700540061007200670065007400550073006500720053006900640027003e0053002d0031002d0030002d0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270054006100720067006500740055007300650072004e0061006d00650027003e00410044004d0049004e004900530054005200410054004f0052003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270054006100720067006500740044006f006d00610069006e004e0061006d00650027003e003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270053007400610074007500730027003e0030007800630030003000300030003000360064003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004600610069006c0075007200650052006500610073006f006e0027003e002500250032003300310033003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270053007500620053007400610074007500730027003e0030007800630030003000300030003000360061003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006f0067006f006e00540079007000650027003e0033003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006f0067006f006e00500072006f0063006500730073004e0061006d00650027003e004e0074004c006d0053007300700020003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700410075007400680065006e007400690063006100740069006f006e005000610063006b006100670065004e0061006d00650027003e004e0054004c004d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270057006f0072006b00730074006100740069006f006e004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005400720061006e0073006d00690074007400650064005300650072007600690063006500730027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006d005000610063006b006100670065004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004b00650079004c0065006e0067007400680027003e0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700500072006f0063006500730073004900640027003e003000780030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700500072006f0063006500730073004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270049007000410064006400720065007300730027003e003100340036002e00350036002e0036002e003100360036003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004900700050006f007200740027003e0030003c002f0044006100740061003e003c002f004500760065006e00740044006100740061003e003c002f004500760065006e0074003e000000"
+ data, _ := hex.DecodeString(originalHexStr)
+ bufferUsed := len(data) / 2
+ bytes, _ := UTF16ToUTF8BytesForWindowsEventBuffer(data, uint32(bufferUsed))
+ str := string(bytes[:])
+ assert.Equal(t, "4625001254400x8010000000000000694674SecurityEC2AMAZ-5J6IFSFS-1-0-0--0x0S-1-0-0ADMINISTRATOR0xc000006d%%23130xc000006a3NtLmSsp NTLM---00x0-146.56.6.1660", str)
+
+ // odd bytes test
+ originalHexStr = "3c004500760065006e007400200078006d006c006e0073003d00270068007400740070003a002f002f0073006300680065006d00610073002e006d006900630072006f0073006f00660074002e0063006f006d002f00770069006e002f0032003000300034002f00300038002f006500760065006e00740073002f006500760065006e00740027003e003c00530079007300740065006d003e003c00500072006f007600690064006500720020004e0061006d0065003d0027004d006900630072006f0073006f00660074002d00570069006e0064006f00770073002d00530065006300750072006900740079002d004100750064006900740069006e0067002700200047007500690064003d0027007b00350034003800340039003600320035002d0035003400370038002d0034003900390034002d0041003500420041002d003300450033004200300033003200380043003300300044007d0027002f003e003c004500760065006e007400490044003e0034003600320035003c002f004500760065006e007400490044003e003c00560065007200730069006f006e003e0030003c002f00560065007200730069006f006e003e003c004c006500760065006c003e0030003c002f004c006500760065006c003e003c005400610073006b003e00310032003500340034003c002f005400610073006b003e003c004f00700063006f00640065003e0030003c002f004f00700063006f00640065003e003c004b006500790077006f007200640073003e003000780038003000310030003000300030003000300030003000300030003000300030003c002f004b006500790077006f007200640073003e003c00540069006d00650043007200650061007400650064002000530079007300740065006d00540069006d0065003d00270032003000310039002d00300035002d00300035005400320033003a00310032003a00330037002e003300340039003400370036003100300030005a0027002f003e003c004500760065006e0074005200650063006f0072006400490044003e003600390034003600370034003c002f004500760065006e0074005200650063006f0072006400490044003e003c0043006f007200720065006c006100740069006f006e00200041006300740069007600690074007900490044003d0027007b00320035003200320035004600410031002d0044004100420039002d0030003000300031002d0041003600350046002d003200320032003500420039004400410044003400300031007d0027002f003e003c0045007800650063007500740069006f006e002000500072006f006300650073007300490044003d00270038003000340027002000540068007200650061006400490044003d002700310030003800300027002f003e003c004300680061006e006e0065006c003e00530065006300750072006900740079003c002f004300680061006e006e0065006c003e003c0043006f006d00700075007400650072003e0045004300320041004d0041005a002d0035004a00360049004600530046003c002f0043006f006d00700075007400650072003e003c00530065006300750072006900740079002f003e003c002f00530079007300740065006d003e003c004500760065006e00740044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a00650063007400550073006500720053006900640027003e0053002d0031002d0030002d0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a0065006300740055007300650072004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a0065006300740044006f006d00610069006e004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005300750062006a006500630074004c006f0067006f006e004900640027003e003000780030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700540061007200670065007400550073006500720053006900640027003e0053002d0031002d0030002d0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270054006100720067006500740055007300650072004e0061006d00650027003e00410044004d0049004e004900530054005200410054004f0052003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270054006100720067006500740044006f006d00610069006e004e0061006d00650027003e003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270053007400610074007500730027003e0030007800630030003000300030003000360064003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004600610069006c0075007200650052006500610073006f006e0027003e002500250032003300310033003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270053007500620053007400610074007500730027003e0030007800630030003000300030003000360061003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006f0067006f006e00540079007000650027003e0033003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006f0067006f006e00500072006f0063006500730073004e0061006d00650027003e004e0074004c006d0053007300700020003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700410075007400680065006e007400690063006100740069006f006e005000610063006b006100670065004e0061006d00650027003e004e0054004c004d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270057006f0072006b00730074006100740069006f006e004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027005400720061006e0073006d00690074007400650064005300650072007600690063006500730027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004c006d005000610063006b006100670065004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004b00650079004c0065006e0067007400680027003e0030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700500072006f0063006500730073004900640027003e003000780030003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d002700500072006f0063006500730073004e0061006d00650027003e002d003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d00270049007000410064006400720065007300730027003e003100340036002e00350036002e0036002e003100360036003c002f0044006100740061003e003c00440061007400610020004e0061006d0065003d0027004900700050006f007200740027003e0030003c002f0044006100740061003e003c002f004500760065006e00740044006100740061003e003c002f004500760065006e0074003e00000000"
+ data, _ = hex.DecodeString(originalHexStr)
+ bufferUsed = len(data) / 2
+ bytes, _ = UTF16ToUTF8BytesForWindowsEventBuffer(data, uint32(bufferUsed))
+ str = string(bytes[:])
+ assert.Equal(t, "4625001254400x8010000000000000694674SecurityEC2AMAZ-5J6IFSFS-1-0-0--0x0S-1-0-0ADMINISTRATOR0xc000006d%%23130xc000006a3NtLmSsp NTLM---00x0-146.56.6.1660", str)
+
+}
+
+func TestFullBufferUsedWithHalfUsedSizeReturned(t *testing.T) {
+ resetState()
+ cap := 1 << 10
+ data := make([]byte, cap)
+ data[0] = 'a'
+ for i := 2; i < cap; i *= 2 {
+ copy(data[i:], data[:i])
+ }
+ bufferUsed := cap / 2
+
+ bytes, _ := UTF16ToUTF8BytesForWindowsEventBuffer(data, uint32(bufferUsed))
+ str := string(bytes[:])
+ assert.Equal(t, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", str)
+ assert.Equal(t, bufferUsed, len(str))
+}
+
+func TestInsertPlaceholderValues(t *testing.T) {
+ evtDataValues := []Datum{
+ {"value_1"}, {"value_2"}, {"value_3"}, {"value_4"},
+ }
+ tests := []struct {
+ name string
+ message string
+ expected string
+ }{
+ {
+ "Placeholders %{number} should be replaced by insertion strings",
+ "Service %1 in region %3 stop at %2",
+ "Service value_1 in region value_3 stop at value_2",
+ },
+ {
+ "String without a placeholder should remain the same after insertion",
+ "This is a sentence without placeholders",
+ "This is a sentence without placeholders",
+ },
+ {
+ "Empty string should remain the same",
+ "",
+ "",
+ },
+ {
+ "Index should start from 1 and less than or equal to the amount of values in event data",
+ "%0 %3 %5",
+ "%0 value_3 %5",
+ },
+ {
+ "Handle consecutive % characters",
+ "%1 %%3% %2",
+ "value_1 %value_3% value_2",
+ },
+ {
+ "Handle % character at the end of message",
+ "%3 %2%",
+ "value_3 value_2%",
+ },
+ {
+ "Characters after a % other than numbers should be ignored",
+ "%foo, %foo1, %#$%^&1",
+ "%foo, %foo1, %#$%^&1",
+ },
+ }
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ assert.Equal(t, tc.expected, insertPlaceholderValues(tc.message, evtDataValues))
+ })
+ }
+}
+
+func resetState() {
+ NumberOfBytesPerCharacter = 0
+}
diff --git a/plugins/inputs/windows_event_log/wineventlog/wineventlog.go b/plugins/inputs/windows_event_log/wineventlog/wineventlog.go
index 1ed6d12b78..39f1e7f122 100644
--- a/plugins/inputs/windows_event_log/wineventlog/wineventlog.go
+++ b/plugins/inputs/windows_event_log/wineventlog/wineventlog.go
@@ -49,6 +49,7 @@ func (e *wevtAPIError) Error() string {
type windowsEventLog struct {
name string
levels []string
+ eventIDs []int
logGroupName string
logStreamName string
logGroupClass string
@@ -66,10 +67,11 @@ type windowsEventLog struct {
resubscribeCh chan struct{}
}
-func NewEventLog(name string, levels []string, logGroupName, logStreamName, renderFormat, destination string, stateManager state.FileRangeManager, maximumToRead int, retention int, logGroupClass string) *windowsEventLog {
+func NewEventLog(name string, levels []string, eventIDs []int, logGroupName, logStreamName, renderFormat, destination string, stateManager state.FileRangeManager, maximumToRead int, retention int, logGroupClass string) *windowsEventLog {
eventLog := &windowsEventLog{
name: name,
levels: levels,
+ eventIDs: eventIDs,
logGroupName: logGroupName,
logStreamName: logStreamName,
logGroupClass: logGroupClass,
@@ -210,7 +212,7 @@ func (w *windowsEventLog) open() error {
if err != nil {
return err
}
- query, err := CreateQuery(w.name, w.levels)
+ query, err := CreateQuery(w.name, w.levels, w.eventIDs)
if err != nil {
return err
}
diff --git a/plugins/inputs/windows_event_log/wineventlog/wineventlog_test.go b/plugins/inputs/windows_event_log/wineventlog/wineventlog_test.go
index 047bba571c..42c9a731c7 100644
--- a/plugins/inputs/windows_event_log/wineventlog/wineventlog_test.go
+++ b/plugins/inputs/windows_event_log/wineventlog/wineventlog_test.go
@@ -24,6 +24,7 @@ var (
NAME = "Application"
// 2 is ERROR
LEVELS = []string{"2"}
+ EVENTIDS = []int{777}
GROUP_NAME = "fake"
STREAM_NAME = "fake"
RENDER_FMT = FormatPlainText
@@ -36,7 +37,7 @@ var (
// TestNewEventLog verifies constructor's default values.
func TestNewEventLog(t *testing.T) {
- elog := newTestEventLog(t, NAME, LEVELS)
+ elog := newTestEventLog(t, NAME, LEVELS, EVENTIDS)
assert.Equal(t, NAME, elog.name)
assert.Equal(t, uint64(0), elog.eventOffset)
assert.Zero(t, elog.eventHandle)
@@ -46,23 +47,27 @@ func TestNewEventLog(t *testing.T) {
// And fails with invalid inputs.
func TestOpen(t *testing.T) {
// Happy path.
- elog := newTestEventLog(t, NAME, LEVELS)
+ elog := newTestEventLog(t, NAME, LEVELS, EVENTIDS)
assert.NoError(t, elog.Open())
assert.NotZero(t, elog.eventHandle)
assert.NoError(t, elog.Close())
// Bad event log source name does not cause Open() to fail.
// But eventHandle will be 0 and Close() will fail because of it.
- elog = newTestEventLog(t, "FakeBadElogName", LEVELS)
+ elog = newTestEventLog(t, "FakeBadElogName", LEVELS, EVENTIDS)
assert.NoError(t, elog.Open())
assert.Zero(t, elog.eventHandle)
assert.Error(t, elog.Close())
// bad LEVELS does not cause Open() to fail.
- elog = newTestEventLog(t, NAME, []string{"498"})
+ elog = newTestEventLog(t, NAME, []string{"498"}, EVENTIDS)
+ assert.NoError(t, elog.Open())
+ assert.NotZero(t, elog.eventHandle)
+ assert.NoError(t, elog.Close())
+ elog = newTestEventLog(t, NAME, LEVELS, []int{98698})
assert.NoError(t, elog.Open())
assert.NotZero(t, elog.eventHandle)
assert.NoError(t, elog.Close())
// bad wlog.eventOffset does not cause Open() to fail.
- elog = newTestEventLog(t, NAME, []string{"498"})
+ elog = newTestEventLog(t, NAME, []string{"498"}, EVENTIDS)
elog.eventOffset = 9987
assert.NoError(t, elog.Open())
assert.NotZero(t, elog.eventHandle)
@@ -72,7 +77,7 @@ func TestOpen(t *testing.T) {
// TestReadGoodSource will verify we can read events written by a registered
// event log source.
func TestReadGoodSource(t *testing.T) {
- elog := newTestEventLog(t, NAME, LEVELS)
+ elog := newTestEventLog(t, NAME, LEVELS, EVENTIDS)
assert.NoError(t, elog.Open())
seekToEnd(t, elog)
writeEvents(t, 10, true, "CWA_UnitTest111", 777)
@@ -84,7 +89,7 @@ func TestReadGoodSource(t *testing.T) {
// TestReadBadSource will verify that we cannot read events written by an
// unregistered event log source.
func TestReadBadSource(t *testing.T) {
- elog := newTestEventLog(t, NAME, LEVELS)
+ elog := newTestEventLog(t, NAME, LEVELS, EVENTIDS)
assert.NoError(t, elog.Open())
seekToEnd(t, elog)
writeEvents(t, 10, false, "CWA_UnitTest222", 888)
@@ -97,7 +102,7 @@ func TestReadBadSource(t *testing.T) {
// registered event log source, even if the batch contains events from an
// unregistered source too.
func TestReadWithBothSources(t *testing.T) {
- elog := newTestEventLog(t, NAME, LEVELS)
+ elog := newTestEventLog(t, NAME, LEVELS, EVENTIDS)
assert.NoError(t, elog.Open())
seekToEnd(t, elog)
writeEvents(t, 10, true, "CWA_UnitTest111", 777)
@@ -135,12 +140,13 @@ func writeEvents(t *testing.T, msgCount int, doRegister bool, logSrc string, eve
wlog, err := eventlog.Open(logSrc)
assert.NoError(t, err)
for i := 0; i < msgCount; i++ {
- wlog.Error(eventId, fmt.Sprintf("CWA_UnitTest event msg %v", i))
+ err = wlog.Error(eventId, fmt.Sprintf("CWA_UnitTest event msg %v", i))
+ assert.NoError(t, err)
}
err = wlog.Close()
assert.NoError(t, err)
// Must sleep after wlog.Error() otherwise elog.read() will not see results.
- time.Sleep(1 * time.Second)
+ time.Sleep(3 * time.Second)
}
// readHelper reads all events (since last read).
@@ -171,13 +177,13 @@ func checkEvents(t *testing.T, records []*windowsEventLogRecord, substring strin
assert.Equal(t, count, found, "expected %v, %v, actual %v", substring, count, found)
}
-func newTestEventLog(t *testing.T, name string, levels []string) *windowsEventLog {
+func newTestEventLog(t *testing.T, name string, levels []string, eventids []int) *windowsEventLog {
t.Helper()
manager := state.NewFileRangeManager(state.ManagerConfig{
StateFileDir: t.TempDir(),
StateFilePrefix: logscommon.WindowsEventLogPrefix,
Name: GROUP_NAME + "_" + STREAM_NAME + "_" + name,
})
- return NewEventLog(name, levels, GROUP_NAME, STREAM_NAME, RENDER_FMT, DEST,
+ return NewEventLog(name, levels, eventids, GROUP_NAME, STREAM_NAME, RENDER_FMT, DEST,
manager, BATCH_SIZE, RETENTION, LOG_GROUP_CLASS)
}
diff --git a/translator/config/sampleSchema/invalidLogWindowsEventsWithInvalidEventIdsType.json b/translator/config/sampleSchema/invalidLogWindowsEventsWithInvalidEventIdsType.json
new file mode 100644
index 0000000000..10413f58a5
--- /dev/null
+++ b/translator/config/sampleSchema/invalidLogWindowsEventsWithInvalidEventIdsType.json
@@ -0,0 +1,17 @@
+{
+ "logs": {
+ "logs_collected": {
+ "windows_events": {
+ "collect_list": [
+ {
+ "event_name": "System",
+ "event_ids": "4562",
+ "log_group_name": "System",
+ "log_stream_name": "System"
+ }
+ ]
+ }
+ },
+ "log_stream_name": "LOG_STREAM_NAME"
+ }
+}
\ No newline at end of file
diff --git a/translator/config/sampleSchema/invalidLogWindowsEventsWithMissingEventIdsAndEventLevels.json b/translator/config/sampleSchema/invalidLogWindowsEventsWithMissingEventIdsAndEventLevels.json
new file mode 100644
index 0000000000..be0ccd9e02
--- /dev/null
+++ b/translator/config/sampleSchema/invalidLogWindowsEventsWithMissingEventIdsAndEventLevels.json
@@ -0,0 +1,16 @@
+{
+ "logs": {
+ "logs_collected": {
+ "windows_events": {
+ "collect_list": [
+ {
+ "event_name": "System",
+ "log_group_name": "System",
+ "log_stream_name": "System"
+ }
+ ]
+ }
+ },
+ "log_stream_name": "LOG_STREAM_NAME"
+ }
+}
\ No newline at end of file
diff --git a/translator/config/schema.json b/translator/config/schema.json
index 0279bf2c9d..e6eed15db0 100644
--- a/translator/config/schema.json
+++ b/translator/config/schema.json
@@ -1058,6 +1058,16 @@
"uniqueItems": true
}
},
+ "event_ids":{
+ "type": "array",
+ "items": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 65535
+ },
+ "minItems": 1,
+ "uniqueItems": true
+ },
"log_stream_name": {
"$ref": "#/definitions/logsDefinition/definitions/logStreamNameDefinition"
},
@@ -1079,8 +1089,15 @@
}
},
"required": [
- "event_name",
- "event_levels"
+ "event_name"
+ ],
+ "anyOf": [
+ {
+ "required": ["event_levels"]
+ },
+ {
+ "required": ["event_ids"]
+ }
],
"additionalProperties": false
},
diff --git a/translator/defaultKeyCase.go b/translator/defaultKeyCase.go
index 87f358a816..de7e582aed 100644
--- a/translator/defaultKeyCase.go
+++ b/translator/defaultKeyCase.go
@@ -74,6 +74,25 @@ func DefaultStringArrayCase(key string, defaultVal, input interface{}) (returnKe
return
}
+func DefaultIntegralArrayCase(key string, defaultVal, input interface{}) (string, interface{}) {
+ returnKey, returnVal := DefaultCase(key, defaultVal, input)
+ if arrayVal, ok := returnVal.([]interface{}); ok {
+ intArrayVal := []int{}
+ for _, v := range arrayVal {
+ if floatVal, ok := v.(float64); ok {
+ intVal := int(floatVal)
+ intArrayVal = append(intArrayVal, intVal)
+ }
+ }
+ returnVal = intArrayVal
+ } else {
+ AddErrorMessages(
+ fmt.Sprintf("int array key: %s", key),
+ fmt.Sprintf("%s value (%v) in json is not valid as an array of integers.", key, returnVal))
+ }
+ return returnKey, returnVal
+}
+
func DefaultRetentionInDaysCase(key string, defaultVal, input interface{}) (returnKey string, returnVal interface{}) {
returnKey, returnVal = DefaultIntegralCase(key, defaultVal, input)
if intVal, ok := returnVal.(int); ok && IsValidRetentionDays(intVal) {
diff --git a/translator/tocwconfig/sampleConfig/windows_eventids.conf b/translator/tocwconfig/sampleConfig/windows_eventids.conf
new file mode 100644
index 0000000000..5d0c21526d
--- /dev/null
+++ b/translator/tocwconfig/sampleConfig/windows_eventids.conf
@@ -0,0 +1,48 @@
+[agent]
+ collection_jitter = "0s"
+ debug = false
+ flush_interval = "1s"
+ flush_jitter = "0s"
+ hostname = ""
+ interval = "60s"
+ logfile = "c:\\ProgramData\\Amazon\\AmazonCloudWatchAgent\\Logs\\amazon-cloudwatch-agent.log"
+ logtarget = "lumberjack"
+ metric_batch_size = 1000
+ metric_buffer_limit = 10000
+ omit_hostname = false
+ precision = ""
+ quiet = false
+ round_interval = false
+
+[inputs]
+
+ [[inputs.windows_event_log]]
+ destination = "cloudwatchlogs"
+ file_state_folder = "c:\\ProgramData\\Amazon\\AmazonCloudWatchAgent\\Logs\\state"
+
+ [[inputs.windows_event_log.event_config]]
+ batch_read_size = 170
+ event_ids = [4562, 4589]
+ event_name = "System"
+ log_group_class = ""
+ log_group_name = "System"
+ log_stream_name = "System"
+ retention_in_days = -1
+
+ [[inputs.windows_event_log.event_config]]
+ batch_read_size = 170
+ event_ids = [1452, 9687]
+ event_name = "Application"
+ log_group_class = ""
+ log_group_name = "Application"
+ log_stream_name = "Application"
+ retention_in_days = -1
+
+[outputs]
+
+ [[outputs.cloudwatchlogs]]
+ force_flush_interval = "5s"
+ log_stream_name = "log_stream_name"
+ mode = ""
+ region = "us-west-2"
+ region_type = "ACJ"
diff --git a/translator/tocwconfig/sampleConfig/windows_eventids.json b/translator/tocwconfig/sampleConfig/windows_eventids.json
new file mode 100644
index 0000000000..1f2b7c0037
--- /dev/null
+++ b/translator/tocwconfig/sampleConfig/windows_eventids.json
@@ -0,0 +1,29 @@
+{
+ "logs": {
+ "logs_collected": {
+ "windows_events": {
+ "collect_list": [
+ {
+ "event_name": "System",
+ "event_ids": [
+ 4562,
+ 4589
+ ],
+ "log_group_name": "System",
+ "log_stream_name": "System"
+ },
+ {
+ "event_name": "Application",
+ "event_ids": [
+ 1452,
+ 9687
+ ],
+ "log_group_name": "Application",
+ "log_stream_name": "Application"
+ }
+ ]
+ }
+ },
+ "log_stream_name": "log_stream_name"
+ }
+}
diff --git a/translator/tocwconfig/sampleConfig/windows_eventids.yaml b/translator/tocwconfig/sampleConfig/windows_eventids.yaml
new file mode 100644
index 0000000000..5647ec5a92
--- /dev/null
+++ b/translator/tocwconfig/sampleConfig/windows_eventids.yaml
@@ -0,0 +1,33 @@
+exporters:
+ nop: {}
+extensions:
+ entitystore:
+ mode: ec2
+ region: us-west-2
+receivers:
+ nop: {}
+service:
+ extensions:
+ - entitystore
+ pipelines:
+ metrics/nop:
+ exporters:
+ - nop
+ processors: []
+ receivers:
+ - nop
+ telemetry:
+ logs:
+ encoding: console
+ level: info
+ output_paths:
+ - c:\ProgramData\Amazon\AmazonCloudWatchAgent\Logs\amazon-cloudwatch-agent.log
+ sampling:
+ enabled: true
+ initial: 2
+ thereafter: 500
+ tick: 10s
+ metrics:
+ level: None
+ traces:
+ level: None
diff --git a/translator/tocwconfig/sampleConfig/windows_eventids_and_levels.conf b/translator/tocwconfig/sampleConfig/windows_eventids_and_levels.conf
new file mode 100644
index 0000000000..9da3a55bfc
--- /dev/null
+++ b/translator/tocwconfig/sampleConfig/windows_eventids_and_levels.conf
@@ -0,0 +1,50 @@
+[agent]
+ collection_jitter = "0s"
+ debug = false
+ flush_interval = "1s"
+ flush_jitter = "0s"
+ hostname = ""
+ interval = "60s"
+ logfile = "c:\\ProgramData\\Amazon\\AmazonCloudWatchAgent\\Logs\\amazon-cloudwatch-agent.log"
+ logtarget = "lumberjack"
+ metric_batch_size = 1000
+ metric_buffer_limit = 10000
+ omit_hostname = false
+ precision = ""
+ quiet = false
+ round_interval = false
+
+[inputs]
+
+ [[inputs.windows_event_log]]
+ destination = "cloudwatchlogs"
+ file_state_folder = "c:\\ProgramData\\Amazon\\AmazonCloudWatchAgent\\Logs\\state"
+
+ [[inputs.windows_event_log.event_config]]
+ batch_read_size = 170
+ event_ids = [4562, 4589]
+ event_levels = ["4", "0", "2"]
+ event_name = "System"
+ log_group_class = ""
+ log_group_name = "System"
+ log_stream_name = "System"
+ retention_in_days = -1
+
+ [[inputs.windows_event_log.event_config]]
+ batch_read_size = 170
+ event_ids = [1104, 3215]
+ event_levels = ["4", "0", "2"]
+ event_name = "Application"
+ log_group_class = ""
+ log_group_name = "Application"
+ log_stream_name = "Application"
+ retention_in_days = -1
+
+[outputs]
+
+ [[outputs.cloudwatchlogs]]
+ force_flush_interval = "5s"
+ log_stream_name = "log_stream_name"
+ mode = ""
+ region = "us-west-2"
+ region_type = "ACJ"
diff --git a/translator/tocwconfig/sampleConfig/windows_eventids_and_levels.json b/translator/tocwconfig/sampleConfig/windows_eventids_and_levels.json
new file mode 100644
index 0000000000..5a8d52b1d3
--- /dev/null
+++ b/translator/tocwconfig/sampleConfig/windows_eventids_and_levels.json
@@ -0,0 +1,37 @@
+{
+ "logs": {
+ "logs_collected": {
+ "windows_events": {
+ "collect_list": [
+ {
+ "event_name": "System",
+ "event_levels": [
+ "INFORMATION",
+ "ERROR"
+ ],
+ "event_ids": [
+ 4562,
+ 4589
+ ],
+ "log_group_name": "System",
+ "log_stream_name": "System"
+ },
+ {
+ "event_name": "Application",
+ "event_levels": [
+ "INFORMATION",
+ "ERROR"
+ ],
+ "event_ids": [
+ 1104,
+ 3215
+ ],
+ "log_group_name": "Application",
+ "log_stream_name": "Application"
+ }
+ ]
+ }
+ },
+ "log_stream_name": "log_stream_name"
+ }
+}
\ No newline at end of file
diff --git a/translator/tocwconfig/sampleConfig/windows_eventids_and_levels.yaml b/translator/tocwconfig/sampleConfig/windows_eventids_and_levels.yaml
new file mode 100644
index 0000000000..5647ec5a92
--- /dev/null
+++ b/translator/tocwconfig/sampleConfig/windows_eventids_and_levels.yaml
@@ -0,0 +1,33 @@
+exporters:
+ nop: {}
+extensions:
+ entitystore:
+ mode: ec2
+ region: us-west-2
+receivers:
+ nop: {}
+service:
+ extensions:
+ - entitystore
+ pipelines:
+ metrics/nop:
+ exporters:
+ - nop
+ processors: []
+ receivers:
+ - nop
+ telemetry:
+ logs:
+ encoding: console
+ level: info
+ output_paths:
+ - c:\ProgramData\Amazon\AmazonCloudWatchAgent\Logs\amazon-cloudwatch-agent.log
+ sampling:
+ enabled: true
+ initial: 2
+ thereafter: 500
+ tick: 10s
+ metrics:
+ level: None
+ traces:
+ level: None
diff --git a/translator/tocwconfig/sampleConfig/windows_eventlog_only_config.conf b/translator/tocwconfig/sampleConfig/windows_eventlog_only_config.conf
index 662eb7f1d1..a91e4918b7 100755
--- a/translator/tocwconfig/sampleConfig/windows_eventlog_only_config.conf
+++ b/translator/tocwconfig/sampleConfig/windows_eventlog_only_config.conf
@@ -24,6 +24,7 @@
batch_read_size = 170
event_levels = ["4", "0", "2"]
event_name = "System"
+ log_group_class = ""
log_group_name = "System"
log_stream_name = "System"
retention_in_days = -1
@@ -32,6 +33,7 @@
batch_read_size = 170
event_levels = ["4", "0", "2"]
event_name = "Application"
+ log_group_class = ""
log_group_name = "Application"
log_stream_name = "Application"
retention_in_days = -1
@@ -41,4 +43,6 @@
[[outputs.cloudwatchlogs]]
force_flush_interval = "5s"
log_stream_name = "log_stream_name"
+ mode = ""
region = "us-west-2"
+ region_type = "ACJ"
diff --git a/translator/tocwconfig/tocwconfig_test.go b/translator/tocwconfig/tocwconfig_test.go
index 23923b4ae7..2992ed6358 100644
--- a/translator/tocwconfig/tocwconfig_test.go
+++ b/translator/tocwconfig/tocwconfig_test.go
@@ -340,6 +340,18 @@ func TestWindowsEventOnlyConfig(t *testing.T) {
checkTranslation(t, "windows_eventlog_only_config", "windows", expectedEnvVars, "")
}
+func TestWindowsEventIDOnly(t *testing.T) {
+ resetContext(t)
+ expectedEnvVars := map[string]string{}
+ checkTranslation(t, "windows_eventids", "windows", expectedEnvVars, "")
+}
+
+// test both event_ids and levels
+func TestWindowsEventIdsAndLevels(t *testing.T) {
+ resetContext(t)
+ expectedEnvVars := map[string]string{}
+ checkTranslation(t, "windows_eventids_and_levels", "windows", expectedEnvVars, "")
+}
func TestStatsDConfig(t *testing.T) {
testCases := map[string]testCase{
"linux": {
@@ -923,11 +935,10 @@ func verifyToYamlTranslation(t *testing.T, input interface{}, expectedYamlFilePa
require.NoError(t, yaml.Unmarshal([]byte(yamlStr), &actual))
//assert.NoError(t, os.WriteFile(expectedYamlFilePath, []byte(yamlStr), 0644)) // useful for regenerating YAML
-
opt := cmpopts.SortSlices(func(x, y interface{}) bool {
return pretty.Sprint(x) < pretty.Sprint(y)
})
- // assert.Equal(t, expected, actual) // this is useful for debugging differences between the YAML
+ //assert.Equal(t, expected, actual) // this is useful for debugging differences between the YAML
require.True(t, cmp.Equal(expected, actual, opt), "D! YAML diff: %s", cmp.Diff(expected, actual))
}
diff --git a/translator/tocwconfig/totomlconfig/tomlConfigTemplate/tomlConfig.go b/translator/tocwconfig/totomlconfig/tomlConfigTemplate/tomlConfig.go
index 49f071999b..eb4a511199 100644
--- a/translator/tocwconfig/totomlconfig/tomlConfigTemplate/tomlConfig.go
+++ b/translator/tocwconfig/totomlconfig/tomlConfigTemplate/tomlConfig.go
@@ -105,6 +105,7 @@ type (
eventConfig struct {
BatchReadSize int `toml:"batch_read_size"`
EventLevels []string `toml:"event_levels"`
+ EventIDs []int `toml:"event_ids"`
EventName string `toml:"event_name"`
LogGroupName string `toml:"log_group_name"`
LogStreamName string `toml:"log_stream_name"`
diff --git a/translator/translate/logs/logs_collected/windows_events/collect_list/collectlist.go b/translator/translate/logs/logs_collected/windows_events/collect_list/collectlist.go
index d795271be7..ef4a22dbfd 100644
--- a/translator/translate/logs/logs_collected/windows_events/collect_list/collectlist.go
+++ b/translator/translate/logs/logs_collected/windows_events/collect_list/collectlist.go
@@ -34,7 +34,7 @@ func RegisterRule(fieldname string, r Rule) {
type CollectList struct {
}
-var customizedJsonConfigKeys = []string{"event_name", EventLevelsKey}
+var customizedJSONConfigKeys = []string{"event_name", EventLevelsKey}
var eventLevelMapping = map[string]string{
"VERBOSE": "5",
"INFORMATION": "4",
@@ -77,7 +77,7 @@ func init() {
func getTransformedConfig(input interface{}) interface{} {
result := map[string]interface{}{}
// Extract customer specified config
- util.SetWithSameKeyIfFound(input, customizedJsonConfigKeys, result)
+ util.SetWithSameKeyIfFound(input, customizedJSONConfigKeys, result)
// Set Fixed config
addFixedJsonConfig(result)
@@ -95,27 +95,25 @@ func addFixedJsonConfig(result map[string]interface{}) {
result[BatchReadSizeKey] = BatchReadSizeValue
var inputEventLevels []interface{}
- if eventLevels, ok := result[EventLevelsKey]; !ok {
- return
- } else {
+ if eventLevels, ok := result[EventLevelsKey]; ok {
inputEventLevels = eventLevels.([]interface{})
- }
- resultEventLevels := []interface{}{}
- for _, eventLevel := range inputEventLevels {
- switch eventLevel.(string) {
- case "CRITICAL":
- resultEventLevels = append(resultEventLevels, "1")
- case "ERROR":
- resultEventLevels = append(resultEventLevels, "2")
- case "WARNING":
- resultEventLevels = append(resultEventLevels, "3")
- case "INFORMATION":
- resultEventLevels = append(resultEventLevels, "4", "0")
- case "VERBOSE":
- resultEventLevels = append(resultEventLevels, "5")
- default:
- translator.AddErrorMessages(GetCurPath(), fmt.Sprintf("Cannot find the mapping for Windows event level %v.", eventLevel))
+ resultEventLevels := []interface{}{}
+ for _, eventLevel := range inputEventLevels {
+ switch eventLevel.(string) {
+ case "CRITICAL":
+ resultEventLevels = append(resultEventLevels, "1")
+ case "ERROR":
+ resultEventLevels = append(resultEventLevels, "2")
+ case "WARNING":
+ resultEventLevels = append(resultEventLevels, "3")
+ case "INFORMATION":
+ resultEventLevels = append(resultEventLevels, "4", "0")
+ case "VERBOSE":
+ resultEventLevels = append(resultEventLevels, "5")
+ default:
+ translator.AddErrorMessages(GetCurPath(), fmt.Sprintf("Cannot find the mapping for Windows event level %v.", eventLevel))
+ }
}
+ result[EventLevelsKey] = resultEventLevels
}
- result[EventLevelsKey] = resultEventLevels
}
diff --git a/translator/translate/logs/logs_collected/windows_events/collect_list/collectlist_test.go b/translator/translate/logs/logs_collected/windows_events/collect_list/collectlist_test.go
index 0c7409dfe3..5ed9006131 100644
--- a/translator/translate/logs/logs_collected/windows_events/collect_list/collectlist_test.go
+++ b/translator/translate/logs/logs_collected/windows_events/collect_list/collectlist_test.go
@@ -15,7 +15,7 @@ import (
func TestApplyRule(t *testing.T) {
c := new(CollectList)
- var rawJsonString = `
+ var rawJSONString = `
{
"collect_list": [
{
@@ -24,8 +24,13 @@ func TestApplyRule(t *testing.T) {
"INFORMATION",
"CRITICAL"
],
+ "event_ids": [
+ 100,
+ 120,
+ 300
+ ],
"log_group_name": "System",
- "log_group_class": "STANDARD"
+ "log_group_class": "STANDARD"
},
{
"event_name": "Application",
@@ -34,6 +39,10 @@ func TestApplyRule(t *testing.T) {
"VERBOSE",
"ERROR"
],
+ "event_ids": [
+ 4625,
+ 3568
+ ],
"event_format": "xml",
"log_group_name": "Application",
"retention_in_days": 1
@@ -47,6 +56,7 @@ func TestApplyRule(t *testing.T) {
map[string]interface{}{
"event_name": "System",
"event_levels": []interface{}{"4", "0", "1"},
+ "event_ids": []int{100, 120, 300},
"log_group_name": "System",
"batch_read_size": BatchReadSizeValue,
"retention_in_days": -1,
@@ -55,6 +65,7 @@ func TestApplyRule(t *testing.T) {
map[string]interface{}{
"event_name": "Application",
"event_levels": []interface{}{"4", "0", "5", "2"},
+ "event_ids": []int{4625, 3568},
"event_format": "xml",
"log_group_name": "Application",
"batch_read_size": BatchReadSizeValue,
@@ -65,7 +76,7 @@ func TestApplyRule(t *testing.T) {
var actual interface{}
- err := json.Unmarshal([]byte(rawJsonString), &input)
+ err := json.Unmarshal([]byte(rawJSONString), &input)
if err == nil {
_, actual = c.ApplyRule(input)
assert.Equal(t, expected, actual)
@@ -76,7 +87,7 @@ func TestApplyRule(t *testing.T) {
func TestDuplicateRetention(t *testing.T) {
c := new(CollectList)
- var rawJsonString = `
+ var rawJSONString = `
{
"collect_list": [
{
@@ -85,6 +96,10 @@ func TestDuplicateRetention(t *testing.T) {
"INFORMATION",
"CRITICAL"
],
+ "event_ids": [
+ 100,
+ 120
+ ],
"log_group_name": "System",
"retention_in_days": 3,
"log_group_class": "INFREQUENT_ACCESS"
@@ -96,6 +111,10 @@ func TestDuplicateRetention(t *testing.T) {
"VERBOSE",
"ERROR"
],
+ "event_ids": [
+ 100,
+ 120
+ ],
"event_format": "xml",
"log_group_name": "System",
"retention_in_days": 3,
@@ -108,6 +127,10 @@ func TestDuplicateRetention(t *testing.T) {
"VERBOSE",
"ERROR"
],
+ "event_ids": [
+ 100,
+ 120
+ ],
"event_format": "xml",
"log_group_name": "System",
"retention_in_days": 3,
@@ -122,6 +145,7 @@ func TestDuplicateRetention(t *testing.T) {
map[string]interface{}{
"event_name": "System",
"event_levels": []interface{}{"4", "0", "1"},
+ "event_ids": []int{100, 120},
"log_group_name": "System",
"batch_read_size": BatchReadSizeValue,
"retention_in_days": 3,
@@ -130,6 +154,7 @@ func TestDuplicateRetention(t *testing.T) {
map[string]interface{}{
"event_name": "Application",
"event_levels": []interface{}{"4", "0", "5", "2"},
+ "event_ids": []int{100, 120},
"event_format": "xml",
"log_group_name": "System",
"batch_read_size": BatchReadSizeValue,
@@ -139,6 +164,7 @@ func TestDuplicateRetention(t *testing.T) {
map[string]interface{}{
"event_name": "Application",
"event_levels": []interface{}{"4", "0", "5", "2"},
+ "event_ids": []int{100, 120},
"event_format": "xml",
"log_group_name": "System",
"batch_read_size": BatchReadSizeValue,
@@ -149,19 +175,19 @@ func TestDuplicateRetention(t *testing.T) {
var actual interface{}
- error := json.Unmarshal([]byte(rawJsonString), &input)
- if error == nil {
+ err := json.Unmarshal([]byte(rawJSONString), &input)
+ if err == nil {
_, actual = c.ApplyRule(input)
assert.Equal(t, 0, len(translator.ErrorMessages))
assert.Equal(t, expected, actual)
} else {
- assert.Fail(t, error.Error())
+ assert.Fail(t, err.Error())
}
}
func TestConflictingRetention(t *testing.T) {
c := new(CollectList)
- var rawJsonString = `
+ var rawJSONString = `
{
"collect_list": [
{
@@ -170,8 +196,12 @@ func TestConflictingRetention(t *testing.T) {
"INFORMATION",
"CRITICAL"
],
+ "event_ids": [
+ 100,
+ 120
+ ],
"log_group_name": "System",
- "retention_in_days": 3
+ "retention_in_days": 3
},
{
"event_name": "Application",
@@ -180,9 +210,13 @@ func TestConflictingRetention(t *testing.T) {
"VERBOSE",
"ERROR"
],
+ "event_ids": [
+ 100,
+ 120
+ ],
"event_format": "xml",
"log_group_name": "System",
- "retention_in_days": 1
+ "retention_in_days": 1
}
]
}
@@ -193,6 +227,7 @@ func TestConflictingRetention(t *testing.T) {
map[string]interface{}{
"event_name": "System",
"event_levels": []interface{}{"4", "0", "1"},
+ "event_ids": []int{100, 120},
"log_group_name": "System",
"batch_read_size": BatchReadSizeValue,
"retention_in_days": 3,
@@ -201,6 +236,7 @@ func TestConflictingRetention(t *testing.T) {
map[string]interface{}{
"event_name": "Application",
"event_levels": []interface{}{"4", "0", "5", "2"},
+ "event_ids": []int{100, 120},
"event_format": "xml",
"log_group_name": "System",
"batch_read_size": BatchReadSizeValue,
@@ -211,13 +247,40 @@ func TestConflictingRetention(t *testing.T) {
var actual interface{}
- error := json.Unmarshal([]byte(rawJsonString), &input)
- if error == nil {
+ err := json.Unmarshal([]byte(rawJSONString), &input)
+ if err == nil {
_, actual = c.ApplyRule(input)
assert.GreaterOrEqual(t, 1, len(translator.ErrorMessages))
assert.Equal(t, "Under path : /logs/logs_collected/windows_events/collect_list/ | Error : Different retention_in_days values can't be set for the same log group: system", translator.ErrorMessages[len(translator.ErrorMessages)-1])
assert.Equal(t, expected, actual)
} else {
- assert.Fail(t, error.Error())
+ assert.Fail(t, err.Error())
}
}
+
+func TestEventID(t *testing.T) {
+ //Inputs
+ rawJSONString := `{
+ "collect_list": [{
+ "event_name": "System",
+ "event_ids": [100, 101, 102],
+ "event_levels": ["ERROR", "CRITICAL"]
+ }]
+ }`
+
+ var config interface{}
+ err := json.Unmarshal([]byte(rawJSONString), &config)
+ assert.NoError(t, err)
+
+ //process new configutation
+ c := new(CollectList)
+ _, val := c.ApplyRule(config)
+
+ // Verify event_ids in final configuration
+ result := val.([]interface{})[0].(map[string]interface{})
+
+ eventIDs, exists := result["event_ids"]
+ assert.True(t, exists, "event_ids should exist in final configuration")
+ assert.Equal(t, []int{100, 101, 102}, eventIDs)
+
+}
diff --git a/translator/translate/logs/logs_collected/windows_events/collect_list/ruleEventIDs.go b/translator/translate/logs/logs_collected/windows_events/collect_list/ruleEventIDs.go
new file mode 100644
index 0000000000..b168640417
--- /dev/null
+++ b/translator/translate/logs/logs_collected/windows_events/collect_list/ruleEventIDs.go
@@ -0,0 +1,53 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: MIT
+
+package collectlist
+
+import (
+ "fmt"
+
+ "github.com/aws/amazon-cloudwatch-agent/translator"
+)
+
+const EventIDsSectionKey = "event_ids"
+
+type EventIDs struct {
+}
+
+func isValidEventID(eventID int) bool {
+
+ // Reference: https://learn.microsoft.com/en-us/windows/win32/winauto/allocation-of-winevent-ids
+ // Documentation for Windows Event Log identifiers and ranges
+ const (
+ minEventID = 0
+ maxEventID = 65535
+ )
+ return eventID >= minEventID && eventID <= maxEventID
+}
+
+func (f *EventIDs) ApplyRule(input interface{}) (string, interface{}) {
+ m, ok := input.(map[string]interface{})
+ if !ok {
+ return "", nil
+ }
+
+ if _, exists := m[EventIDsSectionKey]; exists {
+ _, eventIDs := translator.DefaultIntegralArrayCase(EventIDsSectionKey, []interface{}{}, input)
+
+ // Validate each event ID
+ if eventIDsArray, ok := eventIDs.([]int); ok {
+ for i, eventID := range eventIDsArray {
+ if !isValidEventID(eventID) {
+ translator.AddErrorMessages(GetCurPath(), fmt.Sprintf("Invalid event ID %d at index %d. Event IDs must be between 0 and 65535.", eventID, i))
+ }
+ }
+ }
+ return EventIDsSectionKey, eventIDs
+ }
+ return EventIDsSectionKey, nil
+}
+
+func init() {
+ e := new(EventIDs)
+ RegisterRule(EventIDsSectionKey, e)
+}
diff --git a/translator/translate/logs/logs_collected/windows_events/windows_event_test.go b/translator/translate/logs/logs_collected/windows_events/windows_event_test.go
index 9aa6944e69..d6ca4352d7 100644
--- a/translator/translate/logs/logs_collected/windows_events/windows_event_test.go
+++ b/translator/translate/logs/logs_collected/windows_events/windows_event_test.go
@@ -25,6 +25,10 @@ func TestApplyRule(t *testing.T) {
"INFORMATION",
"SUCCESS"
],
+ "event_ids": [
+ 456,
+ 300
+ ],
"log_group_name": "System",
"log_stream_name": "System"
}