//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
}
示例#2
0
//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
}