Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Perfmon - Fix regular expressions to comply to multiple parentheses in instance name and object #22146

Merged
merged 41 commits into from
Oct 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
938e66c
mofidy doc
narph Jul 23, 2020
4daef08
Merge branch 'master' of github.com:elastic/beats
narph Aug 3, 2020
b613178
Merge branch 'master' of github.com:elastic/beats
narph Aug 4, 2020
05364cf
Merge branch 'master' of github.com:elastic/beats
narph Aug 4, 2020
f147c4d
Merge branch 'master' of github.com:elastic/beats
narph Aug 4, 2020
4574718
Merge branch 'master' of github.com:elastic/beats
narph Aug 17, 2020
1e43077
Merge branch 'master' of github.com:elastic/beats
narph Aug 19, 2020
807cf06
Merge branch 'master' of github.com:elastic/beats
narph Aug 24, 2020
2096668
Merge branch 'master' of github.com:elastic/beats
narph Aug 27, 2020
da8ac1f
Merge branch 'master' of github.com:elastic/beats
narph Aug 27, 2020
c2d8930
Merge branch 'master' of github.com:elastic/beats
narph Aug 27, 2020
7bd9e73
Merge branch 'master' of github.com:elastic/beats
narph Aug 31, 2020
6e89a84
Merge branch 'master' of github.com:elastic/beats
narph Aug 31, 2020
bdf21e9
Merge branch 'master' of github.com:elastic/beats
narph Sep 2, 2020
7833687
Merge branch 'master' of github.com:elastic/beats
narph Sep 3, 2020
bbf6178
Merge branch 'master' of github.com:elastic/beats
narph Sep 4, 2020
4ba8817
Merge branch 'master' of github.com:elastic/beats
narph Sep 7, 2020
0cba5dc
Merge branch 'master' of github.com:elastic/beats
narph Sep 8, 2020
b2625ca
Merge branch 'master' of github.com:elastic/beats
narph Sep 8, 2020
5100e6a
Merge branch 'master' of github.com:elastic/beats
narph Sep 9, 2020
a302d31
Merge branch 'master' of github.com:elastic/beats
narph Sep 14, 2020
631d667
Merge branch 'master' of github.com:elastic/beats
narph Sep 15, 2020
35072a5
Merge branch 'master' of github.com:elastic/beats
narph Sep 17, 2020
4b2f87a
Merge branch 'master' of github.com:elastic/beats
narph Sep 22, 2020
f26b533
Merge branch 'master' of github.com:elastic/beats
narph Sep 28, 2020
c61620d
Merge branch 'master' of github.com:elastic/beats
narph Sep 28, 2020
43f90c4
Merge branch 'master' of github.com:elastic/beats
narph Sep 30, 2020
2d28f07
Merge branch 'master' of github.com:elastic/beats
narph Oct 1, 2020
0a42bbe
Merge branch 'master' of github.com:elastic/beats
narph Oct 2, 2020
0bedffe
Merge branch 'master' of github.com:elastic/beats
narph Oct 5, 2020
2eb7142
Merge branch 'master' of github.com:elastic/beats
narph Oct 5, 2020
f9e4522
Merge branch 'master' of github.com:elastic/beats
narph Oct 12, 2020
227bd50
Merge branch 'master' of github.com:elastic/beats
narph Oct 15, 2020
6e39971
Merge branch 'master' of github.com:elastic/beats
narph Oct 19, 2020
0e85625
Merge branch 'master' of github.com:elastic/beats
narph Oct 19, 2020
6770f2d
Merge branch 'master' of github.com:elastic/beats
narph Oct 20, 2020
f0a0a7b
work on instance
narph Oct 26, 2020
c50d6bf
changelog
narph Oct 26, 2020
63ab6a7
Merge branch 'master' of github.com:elastic/beats
narph Oct 26, 2020
6727146
Merge branch 'master' into perfmon-name
narph Oct 26, 2020
e87ee2d
fix tests
narph Oct 26, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d
- Fix retrieving resources by ID for the azure module. {pull}21711[21711] {issue}21707[21707]
- Use timestamp from CloudWatch API when creating events. {pull}21498[21498]
- Report the correct windows events for system/filesystem {pull}21758[21758]
- Fix regular expression in windows/permfon. {pull}22146[22146] {issue}21125[21125]
- Fix azure storage event format. {pull}21845[21845]
- Fix panic in kubernetes autodiscover related to keystores {issue}21843[21843] {pull}21880[21880]
- [Kubernetes] Remove redundant dockersock volume mount {pull}22009[22009]
Expand Down
44 changes: 38 additions & 6 deletions metricbeat/helper/windows/pdh/pdh_query_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import (
)

var (
instanceNameRegexp = regexp.MustCompile(`.*?\((.*?)\).*`)
instanceNameRegexp = regexp.MustCompile(`(\(.+\))\\`)
objectNameRegexp = regexp.MustCompile(`(?:^\\\\[^\\]+\\|^\\)([^\\]+)`)
)

Expand Down Expand Up @@ -86,7 +86,7 @@ func (q *Query) AddCounter(counterPath string, instance string, format string, w
var instanceName string
// Extract the instance name from the counterPath.
if instance == "" || wildcard {
instanceName, err = MatchInstanceName(counterPath)
instanceName, err = matchInstanceName(counterPath)
if err != nil {
return err
}
Expand Down Expand Up @@ -233,18 +233,50 @@ func (q *Query) Close() error {
return PdhCloseQuery(q.Handle)
}

// MatchInstanceName will check first for instance and then for any objects names.
func MatchInstanceName(counterPath string) (string, error) {
// matchInstanceName will check first for instance and then for any objects names.
func matchInstanceName(counterPath string) (string, error) {
matches := instanceNameRegexp.FindStringSubmatch(counterPath)
if len(matches) != 2 {
matches = objectNameRegexp.FindStringSubmatch(counterPath)
if len(matches) == 2 {
return returnLastInstance(matches[1]), nil
}
matches = objectNameRegexp.FindStringSubmatch(counterPath)
if len(matches) == 2 {
return matches[1], nil
}
return "", errors.New("query doesn't contain an instance name. In this case you have to define 'instance_name'")
}

// returnLastInstance will return the content from the last parentheses, this covers cases as `\WF (System.Workflow) 4.0.0.0(*)\Workflows Created`.
func returnLastInstance(match string) string {
var openedParanth int
var innerMatch string
var matches []string
runeMatch := []rune(match)
for i := 0; i < len(runeMatch); i++ {
char := string(runeMatch[i])

// check if string ends between parentheses
if char == ")" {
openedParanth -= 1
}
if openedParanth > 0 {
innerMatch += char
}
if openedParanth == 0 && innerMatch != "" {
matches = append(matches, innerMatch)
innerMatch = ""
}
// check if string starts between parentheses
if char == "(" {
openedParanth += 1
}
}
if len(matches) > 0 {
return matches[len(matches)-1]
}
return match
}

// getCounterValue will retrieve the counter value based on the format applied in the config options
func getCounterValue(counter *Counter) CounterValue {
counterValue := CounterValue{Instance: counter.instanceName, Err: CounterValueError{CStatus: 0}}
Expand Down
66 changes: 65 additions & 1 deletion metricbeat/helper/windows/pdh/pdh_query_windows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,56 @@ func TestSuccessfulQuery(t *testing.T) {
assert.NotNil(t, list)
}

func TestMatchInstanceName(t *testing.T) {
query := "\\SQLServer:Databases(*)\\Log File(s) Used Size (KB)"
match, err := matchInstanceName(query)
assert.NoError(t, err)
assert.Equal(t, match, "*")

query = " \\\\desktop-rfooe09\\per processor network interface card activity(3, microsoft wi-fi directvirtual (gyfyg) adapter #2)\\dpcs queued/sec"
match, err = matchInstanceName(query)
assert.NoError(t, err)
assert.Equal(t, match, "3, microsoft wi-fi directvirtual (gyfyg) adapter #2")

query = " \\\\desktop-rfooe09\\ (test this scenario) per processor network interface card activity(3, microsoft wi-fi directvirtual (gyfyg) adapter #2)\\dpcs queued/sec"
match, err = matchInstanceName(query)
assert.NoError(t, err)
assert.Equal(t, match, "3, microsoft wi-fi directvirtual (gyfyg) adapter #2")

query = "\\RAS\\Bytes Received By Disconnected Clients"
match, err = matchInstanceName(query)
assert.NoError(t, err)
assert.Equal(t, match, "RAS")

query = `\\Process (chrome.exe#4)\\Bytes Received By Disconnected Clients`
match, err = matchInstanceName(query)
assert.NoError(t, err)
assert.Equal(t, match, "chrome.exe#4")

query = "\\BranchCache\\Local Cache: Cache complete file segments"
match, err = matchInstanceName(query)
assert.NoError(t, err)
assert.Equal(t, match, "BranchCache")

query = `\Synchronization(*)\Exec. Resource no-Waits AcqShrdStarveExcl/sec`
match, err = matchInstanceName(query)
assert.NoError(t, err)
assert.Equal(t, match, "*")

query = `\.NET CLR Exceptions(test hellp (dsdsd) #rfsfs #3)\# of Finallys / sec`
match, err = matchInstanceName(query)
assert.NoError(t, err)
assert.Equal(t, match, "test hellp (dsdsd) #rfsfs #3")
}

// TestInstanceNameRegexp tests regular expression for instance.
func TestInstanceNameRegexp(t *testing.T) {
queryPaths := []string{`\SQLServer:Databases(*)\Log File(s) Used Size (KB)`, `\Search Indexer(*)\L0 Indexes (Wordlists)`,
`\Search Indexer(*)\L0 Merges (flushes) Now.`, `\NUMA Node Memory(*)\Free & Zero Page List MBytes`}
for _, path := range queryPaths {
matches := instanceNameRegexp.FindStringSubmatch(path)
if assert.Len(t, matches, 2, "regular expression did not return any matches") {
assert.Equal(t, matches[1], "*")
assert.Equal(t, matches[1], "(*)")
}
}
}
Expand All @@ -114,6 +156,28 @@ func TestObjectNameRegexp(t *testing.T) {
}
}

func TestReturnLastInstance(t *testing.T) {
query := "(*)"
match := returnLastInstance(query)
assert.Equal(t, match, "*")

query = "(3, microsoft wi-fi directvirtual (gyfyg) adapter #2)"
match = returnLastInstance(query)
assert.Equal(t, match, "3, microsoft wi-fi directvirtual (gyfyg) adapter #2")

query = "(test this scenario) per processor network interface card activity(3, microsoft wi-fi directvirtual (gyfyg) adapter #2)"
match = returnLastInstance(query)
assert.Equal(t, match, "3, microsoft wi-fi directvirtual (gyfyg) adapter #2")

query = `(chrome.exe#4)`
match = returnLastInstance(query)
assert.Equal(t, match, "chrome.exe#4")

query = `(test hellp (dsdsd) #rfsfs #3)`
match = returnLastInstance(query)
assert.Equal(t, match, "test hellp (dsdsd) #rfsfs #3")
}

func TestUTF16ToStringArray(t *testing.T) {
var array = []string{"\\\\DESKTOP-RFOOE09\\Physikalischer Datenträger(0 C:)\\Schreibvorgänge/s", "\\\\DESKTOP-RFOOE09\\Physikalischer Datenträger(_Total)\\Schreibvorgänge/s", ""}
var unicode []uint16
Expand Down
4 changes: 2 additions & 2 deletions metricbeat/module/windows/perfmon/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import (
"github.com/elastic/beats/v7/metricbeat/mb"
)

var processRegexp = regexp.MustCompile(`(.+?)#[1-9]+`)
var processRegexp = regexp.MustCompile(`(.+?[^\s])(?:#\d+|$)`)

func (re *Reader) groupToEvents(counters map[string][]pdh.CounterValue) []mb.Event {
eventMap := make(map[string]*mb.Event)
Expand Down Expand Up @@ -73,7 +73,7 @@ func (re *Reader) groupToEvents(counters map[string][]pdh.CounterValue) []mb.Eve
Error: errors.Wrapf(val.Err.Error, "failed on query=%v", counterPath),
}
if val.Instance != "" {
//will ignore instance counter
//will ignore instance index
if ok, match := matchesParentProcess(val.Instance); ok {
eventMap[eventKey].MetricSetFields.Put(counter.InstanceField, match)
} else {
Expand Down
6 changes: 5 additions & 1 deletion metricbeat/module/windows/perfmon/data_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,13 @@ func TestGroupToSingleEvent(t *testing.T) {

func TestMatchesParentProcess(t *testing.T) {
ok, val := matchesParentProcess("svchost")
assert.False(t, ok)
assert.True(t, ok)
assert.Equal(t, val, "svchost")
ok, val = matchesParentProcess("svchost#54")
assert.True(t, ok)
assert.Equal(t, val, "svchost")

ok, val = matchesParentProcess("svchost (test) another #54")
assert.True(t, ok)
assert.Equal(t, val, "svchost (test) another #54")
}