//PerformanceDataIterator returns an iterator to loop over generated perf data. func (w *NagiosSpoolfileWorker) PerformanceDataIterator(input map[string]string) <-chan PerformanceData { ch := make(chan PerformanceData) typ := findType(input) if typ == "" { if len(input) > 1 { logging.GetLogger().Info("Line does not match the scheme", input) } close(ch) return ch } currentCommand := w.searchAltCommand(input[typ+"PERFDATA"], input[typ+checkcommand]) currentTime := helper.CastStringTimeFromSToMs(input[timet]) currentService := "" if typ != hostType { currentService = input[servicedesc] } go func() { perfSlice := regexPerformancelable.FindAllStringSubmatch(input[typ+"PERFDATA"], -1) currentCheckMultiLabel := "" //try to find a check_multi prefix if len(perfSlice) > 0 && len(perfSlice[0]) > 1 { currentCheckMultiLabel = getCheckMultiRegexMatch(perfSlice[0][1]) } item: for _, value := range perfSlice { // Allows to add tags and fields to spoolfileentries tag := map[string]string{} if tagString, ok := input[nagfluxTags]; ok { tag = helper.StringToMap(tagString, " ", "=") } field := map[string]string{} if tagString, ok := input[nagfluxField]; ok { field = helper.StringToMap(tagString, " ", "=") } perf := PerformanceData{ hostname: input[hostname], service: currentService, command: currentCommand, time: currentTime, performanceLabel: value[1], unit: value[3], tags: tag, fields: field, } if currentCheckMultiLabel != "" { //if an check_multi prefix was found last time //test if the current one has also one if potentialNextOne := getCheckMultiRegexMatch(perf.performanceLabel); potentialNextOne == "" { // if not put the last one in front the current perf.performanceLabel = currentCheckMultiLabel + perf.performanceLabel } else { // else remember the current prefix for the next one currentCheckMultiLabel = potentialNextOne } } for i, data := range value { if i > 1 && i != 3 && data != "" { performanceType, err := indexToperformanceType(i) if err != nil { logging.GetLogger().Warn(err, value) continue } //Add downtime tag if needed if performanceType == "value" && w.livestatusCacheBuilder.IsServiceInDowntime(perf.hostname, perf.service, input[timet]) { perf.tags["downtime"] = "true" } if performanceType == "warn" || performanceType == "crit" { //Range handling fillLabel := performanceType + "-fill" rangeHits := rangeRegex.FindAllStringSubmatch(data, -1) if len(rangeHits) == 1 { perf.tags[fillLabel] = "none" perf.fields[performanceType] = helper.StringIntToStringFloat(rangeHits[0][0]) } else if len(rangeHits) == 2 { //If there is a range with no infinity as border, create two points if strings.Contains(data, "@") { perf.tags[fillLabel] = "inner" } else { perf.tags[fillLabel] = "outer" } for i, tag := range []string{"min", "max"} { tagKey := fmt.Sprintf("%s-%s", performanceType, tag) perf.fields[tagKey] = helper.StringIntToStringFloat(rangeHits[i][0]) } } else { logging.GetLogger().Warn("Regexmatching went wrong", rangeHits, data, value) } } else { if !helper.IsStringANumber(data) { continue item } perf.fields[performanceType] = helper.StringIntToStringFloat(data) } } } ch <- perf } close(ch) }() return ch }
//Iterator to loop over generated perf data. func (w *NagiosSpoolfileWorker) old_performanceDataIterator(input map[string]string) <-chan PerformanceData { ch := make(chan PerformanceData) var typ string if isHostPerformanceData(input) { typ = hostType } else if isServicePerformanceData(input) { typ = serviceType } else { if len(input) > 1 { logging.GetLogger().Info("Line does not match the scheme", input) } close(ch) return ch } //logging.GetLogger().Info("XX INPUT XX", input) currentHostname := helper.SanitizeInfluxInput(input[hostname]) currentCommand := w.searchAltCommand(input[typ+"PERFDATA"], input[typ+checkcommand]) currentTime := helper.CastStringTimeFromSToMs(input[timet]) currentService := "" if typ != hostType { currentService = helper.SanitizeInfluxInput(input[servicedesc]) } // logging.GetLogger().Info("XX currentHostname XX ", currentHostname) // logging.GetLogger().Info("XX currentCommand XX ", currentCommand) // logging.GetLogger().Info("XX currentTime XX ", currentTime) // logging.GetLogger().Info("XX currentService XX ", currentService) //currentCommand = strings.Replace(currentCommand, "check_mk-", "", -1) go func() { for _, value := range w.regexPerformancelable.FindAllStringSubmatch(input[typ+"PERFDATA"], -1) { perf := PerformanceData{ hostname: currentHostname, service: currentService, command: currentCommand, time: currentTime, performanceLabel: helper.SanitizeInfluxInput(value[1]), unit: helper.SanitizeInfluxInput(value[3]), fieldseperator: w.fieldseperator, tags: map[string]string{}, } for i, data := range value { if i > 1 && i != 3 && data != "" { performanceType, err := indexToperformanceType(i) if err != nil { logging.GetLogger().Warn(err, value) continue } //Add downtime tag if needed if performanceType == "value" && w.livestatusCacheBuilder.IsServiceInDowntime(perf.hostname, perf.service, input[timet]) { perf.tags["downtime"] = "1" } //logging.GetLogger().Info("XX hostname: ",perf.hostname) //logging.GetLogger().Info("XX service: ",perf.service) //logging.GetLogger().Info("XX command: ",perf.command) //logging.GetLogger().Info("XX time: ",perf.time) //logging.GetLogger().Info("XX performanceLabel: ",perf.performanceLabel) //logging.GetLogger().Info("XX performanceType: ",perf.performanceType) //logging.GetLogger().Info("XX unit: ",perf.unit) ////logging.GetLogger().Info("XX tags: ",perf.tags) //for key, value := range perf.tags { //logging.GetLogger().Info("XX tag - ",key , " ",value) ////fmt.Println("Key:", key, "Value:", value) //} if performanceType == "warn" || performanceType == "crit" { //Range handling rangeRegex := regexp.MustCompile(`[\d\.\-]+`) rangeHits := rangeRegex.FindAllStringSubmatch(data, -1) if len(rangeHits) == 1 { perf.tags["fill"] = "none" perf.tags["type"] = performanceType perf.value = helper.StringIntToStringFloat(rangeHits[0][0]) perf.performanceType = performanceType ch <- perf } else if len(rangeHits) == 2 { //If there is a range with no infinity as border, create two points perf.performanceType = performanceType if strings.Contains(data, "@") { perf.tags["fill"] = "inner" } else { perf.tags["fill"] = "outer" } for i, tag := range []string{"min", "max"} { tmpPerf := perf tmpPerf.tags = helper.CopyMap(perf.tags) tmpPerf.tags["type"] = tag tmpPerf.value = helper.StringIntToStringFloat(rangeHits[i][0]) ch <- tmpPerf } } else { logging.GetLogger().Warn("Regexmatching went wrong", rangeHits) } } else { perf.tags["fill"] = "none" perf.tags["type"] = "value" perf.value = helper.StringIntToStringFloat(data) perf.performanceType = performanceType ch <- perf } } } } close(ch) }() return ch }