Skip to content

Commit 2f4d72e

Browse files
Ahmet OeztuerkAhmet Oeztuerk
authored andcommitted
WIP: check if reconstructed perfdata from regex matches is same as the original string
still wip, might fail in real deployments. Add test for it, detects if textual data written at the end of a perfstring is discarded.
1 parent cfc0eb3 commit 2f4d72e

2 files changed

Lines changed: 39 additions & 3 deletions

File tree

pkg/nagflux/collector/spoolfile/nagiosSpoolfileWorker.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ var (
8888
// Same as 6th capture group, but it is for the maximum value this time.
8989
// '\s' matches any whitespace character, infinite times.
9090
// Idea: It seperates different perf data values as this must be matched new capture group can be captured
91+
// Overall this script will detect a perfdata in Nagios syntax
9192
regexPerformancelable = regexp.MustCompile(`([^=]+)=(U|[\d\.\,\-]+)([\pL\/\%]*);?([\d\.\,\-\:\~\@]*)?;?([\d\.\,\-\:\~\@]*)?;?([\d\.\,\-]*)?;?([\d\.\,\-]*)?;?\s*`)
9293

9394
// The perfdata part might have some alternative check at the end, recognize it by it being at the end and only containing letters, '_', '-'
@@ -254,8 +255,8 @@ func (w *NagiosSpoolfileWorker) PerformanceDataIterator(input map[string]string)
254255

255256
// anonymous closure, starts immediately after definition in another goroutine without blocking
256257
go func() {
257-
perdataString := input[dataType+"PERFDATA"]
258-
cleaned := regexStripErrors.ReplaceAllString(perdataString, "")
258+
perfdataString := input[dataType+"PERFDATA"]
259+
perfdataStringErrorsRemoved := regexStripErrors.ReplaceAllString(perfdataString, "")
259260

260261
// Slices up the string into a form like this
261262
// Each match is put into an array with their capture groups
@@ -269,14 +270,27 @@ func (w *NagiosSpoolfileWorker) PerformanceDataIterator(input map[string]string)
269270
["pl=0%;80;100;0;100","pl","0","%","80","100","0","100"]
270271
]
271272
*/
272-
perfdataStringMatches := regexPerformancelable.FindAllStringSubmatch(cleaned, -1)
273+
perfdataStringMatches := regexPerformancelable.FindAllStringSubmatch(perfdataStringErrorsRemoved, -1)
273274
currentCheckMultiLabel := ""
274275

275276
// try to find a check_multi prefix
276277
if len(perfdataStringMatches) > 0 && len(perfdataStringMatches[0]) > 1 {
277278
currentCheckMultiLabel = getCheckMultiRegexMatch(perfdataStringMatches[0][1])
278279
}
279280

281+
// check if concataneting matches makes up the original string
282+
matchesConcatenated := ""
283+
for _, matchAndCaptureGroups := range perfdataStringMatches {
284+
match := matchAndCaptureGroups[0]
285+
matchesConcatenated += match
286+
}
287+
288+
if len(matchesConcatenated) > 0 && strings.TrimSpace(matchesConcatenated) != strings.TrimSpace(perfdataString) {
289+
log.Warnf("Perfdata matches: '%v' when concatanted come up to be: '%s', and original perfdata string is: '%s' . They are not equal after stripping whitespace from both", perfdataStringMatches, matchesConcatenated, perfdataString)
290+
close(ch)
291+
return
292+
}
293+
280294
for _, perfdataStringMatch := range perfdataStringMatches {
281295
// Allows to add tags and fields to spoolfileentries
282296
tags := map[string]string{}

pkg/nagflux/collector/spoolfile/nagiosSpoolfileWorker_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,28 @@ func TestPerformanceDataParser_LongMaxValue(t *testing.T) {
583583
assert.Emptyf(t, collectedPerfData, "Item should not be taken into the performance data due to long length of maximum value, splittedPerformanceData: %v", splittedPerformanceData)
584584
}
585585

586+
func TestPerformanceDataParser_GarbageStringAfterPerfdata(t *testing.T) {
587+
t.Helper()
588+
589+
config.InitConfigFromString(configFileContent)
590+
591+
w := NewNagiosSpoolfileWorker(0, nil, nil, nil, 4096, collector.AllFilterable, PerfdataLabelMaxLengthDefault, PerfdataUOMMaxLengthDefault, PerfdataNumericValuesMaxLengthDefault, PerfdataThresholdsMaxLengthDefault)
592+
593+
// If you use underscores in the uom, it gets split out and only the first part is taken.
594+
// UOM is deliberately written without underscores here
595+
splittedPerformanceData := helper.StringToMap(
596+
"DATATYPE::SERVICEPERFDATA TIMET::1441791000 HOSTNAME::xxx SERVICEDESC::range SERVICEPERFDATA::passme=1 failme=1;1:2;3:4;5;6-hello-i-am-garbage-string-that-should-be-detected-as-i-am-not-whitespace SERVICECHECKCOMMAND::check_dummy SERVICESTATE::0 SERVICESTATETYPE::1",
597+
"\t", "::")
598+
599+
//nolint:prealloc // do not know the size of the iterable
600+
collectedPerfData := []PerformanceData{}
601+
for singlePerfdata := range w.PerformanceDataIterator(splittedPerformanceData) {
602+
collectedPerfData = append(collectedPerfData, *singlePerfdata)
603+
}
604+
605+
assert.Emptyf(t, collectedPerfData, "Item should not be taken into the performance data due to long length of maximum value, splittedPerformanceData: %v", splittedPerformanceData)
606+
}
607+
586608
func testPerformanceDataParser(t *testing.T, input string, expect []PerformanceData) {
587609
t.Helper()
588610

0 commit comments

Comments
 (0)