From 6498453215a4c99e5fc1d925dee518203d6924fb Mon Sep 17 00:00:00 2001 From: Thomas Forrer Date: Thu, 18 Oct 2018 17:06:06 +0200 Subject: [PATCH 1/3] add StorePerformanceLabelAsField and StoreCommandAsField options --- collector/spoolfile/performanceData.go | 24 ++++++++++++++++++++---- config.gcfg.example | 7 +++++++ config/Config.go | 2 ++ helper/influx.go | 17 +++++++++++++++++ 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/collector/spoolfile/performanceData.go b/collector/spoolfile/performanceData.go index 6f3bb12..e1dcfb5 100644 --- a/collector/spoolfile/performanceData.go +++ b/collector/spoolfile/performanceData.go @@ -29,10 +29,25 @@ func (p PerformanceData) PrintForInfluxDB(version string) string { } else { tableName += fmt.Sprintf(`,service=%s`, helper.SanitizeInfluxInput(p.Service)) } - tableName += fmt.Sprintf(`,command=%s,performanceLabel=%s`, - helper.SanitizeInfluxInput(p.Command), - helper.SanitizeInfluxInput(p.PerformanceLabel), - ) + var fieldsString = "" + if config.GetConfig().InfluxDBGlobal.StoreCommandAsField { + fieldsString += fmt.Sprintf(`,command="%s"`, + helper.SanitizeInfluxField(p.Command), + ) + } else { + tableName += fmt.Sprintf(`,command=%s`, + helper.SanitizeInfluxInput(p.Command), + ) + } + if config.GetConfig().InfluxDBGlobal.StorePerformanceLabelAsField { + fieldsString += fmt.Sprintf(`,performanceLabel="%s"`, + helper.SanitizeInfluxField(p.PerformanceLabel), + ) + } else { + tableName += fmt.Sprintf(`,performanceLabel=%s`, + helper.SanitizeInfluxInput(p.PerformanceLabel), + ) + } if len(p.Tags) > 0 { tableName += fmt.Sprintf(`,%s`, helper.PrintMapAsString(helper.SanitizeMap(p.Tags), ",", "=")) } @@ -41,6 +56,7 @@ func (p PerformanceData) PrintForInfluxDB(version string) string { } tableName += fmt.Sprintf(` %s`, helper.PrintMapAsString(helper.SanitizeMap(p.Fields), ",", "=")) + tableName += fieldsString tableName += fmt.Sprintf(" %s\n", p.Time) return tableName } diff --git a/config.gcfg.example b/config.gcfg.example index 8ed00ff..d124544 100644 --- a/config.gcfg.example +++ b/config.gcfg.example @@ -54,6 +54,13 @@ NastyStringToReplace = "" HostcheckAlias = "hostcheck" ClientTimeout = 5 + # on big installations with lot of checks that have device dependend performance labels + # e.g. check_interface_table, the series cardinality in influxdb can explode and therefore + # cause write timeouts. + # In such cases, setting PerformanceLabel as Field value will significantly reduce the series + # cardinality. + StoreCommandAsField = false + StorePerformanceLabelAsField = false [InfluxDB "nagflux"] Enabled = true diff --git a/config/Config.go b/config/Config.go index 496304b..b13c9ad 100644 --- a/config/Config.go +++ b/config/Config.go @@ -35,6 +35,8 @@ type Config struct { NastyStringToReplace string HostcheckAlias string ClientTimeout int + StoreCommandAsField bool + StorePerformanceLabelAsField bool } InfluxDB map[string]*struct { Enabled bool diff --git a/helper/influx.go b/helper/influx.go index a19596e..19042fe 100644 --- a/helper/influx.go +++ b/helper/influx.go @@ -28,6 +28,23 @@ func SanitizeInfluxInput(input string) string { return input } +//SanitizeInfluxField escapes '"' chars only +func SanitizeInfluxField(input string) string { + + if config.GetConfig().InfluxDBGlobal.NastyString != "" { + input = strings.Replace( + input, + config.GetConfig().InfluxDBGlobal.NastyString, + config.GetConfig().InfluxDBGlobal.NastyStringToReplace, + -1, + ) + } + + input = strings.Replace(input, "\"", `\"`, -1) + + return input +} + //SanitizeMap calls SanitizeInfluxInput in key and value func SanitizeMap(input map[string]string) map[string]string { result := map[string]string{} From cf3617f590821b8b5fb8c6ad3dc5026ece5a9e8d Mon Sep 17 00:00:00 2001 From: Gianluca Piccolo Date: Fri, 26 Oct 2018 08:52:28 +0200 Subject: [PATCH 2/3] Add index tag to avoid rows overwrite --- collector/IPrintable.go | 2 +- collector/SimplePrintable.go | 2 +- collector/livestatus/Collector.go | 2 +- collector/livestatus/CommentData.go | 2 +- collector/livestatus/DowntimeData.go | 2 +- collector/livestatus/NotificationData.go | 2 +- collector/nagflux/NagfluxPrintable.go | 2 +- collector/spoolfile/performanceData.go | 7 ++++++- target/influx/Worker.go | 10 +++++----- 9 files changed, 18 insertions(+), 13 deletions(-) diff --git a/collector/IPrintable.go b/collector/IPrintable.go index 5e8ddba..72575cc 100644 --- a/collector/IPrintable.go +++ b/collector/IPrintable.go @@ -2,7 +2,7 @@ package collector //Printable this interface should be used to push data into the queue. type Printable interface { - PrintForInfluxDB(version string) string + PrintForInfluxDB(version string, i int) string PrintForElasticsearch(version, index string) string TestTargetFilter(string) bool } diff --git a/collector/SimplePrintable.go b/collector/SimplePrintable.go index 2d60df5..ca7c89e 100644 --- a/collector/SimplePrintable.go +++ b/collector/SimplePrintable.go @@ -10,7 +10,7 @@ type SimplePrintable struct { } //PrintForInfluxDB generates an String for InfluxDB -func (p SimplePrintable) PrintForInfluxDB(version string) string { +func (p SimplePrintable) PrintForInfluxDB(version string, i int) string { if p.Datatype == data.InfluxDB { return p.Text } diff --git a/collector/livestatus/Collector.go b/collector/livestatus/Collector.go index f553a49..d78aa2d 100644 --- a/collector/livestatus/Collector.go +++ b/collector/livestatus/Collector.go @@ -248,7 +248,7 @@ Loop: for roundsToWait != 0 { select { case versionPrintable := <-printables: - version = versionPrintable.PrintForInfluxDB("0") + version = versionPrintable.PrintForInfluxDB("0", 0) break Loop case <-time.After(oneMinute): if i < roundsToWait { diff --git a/collector/livestatus/CommentData.go b/collector/livestatus/CommentData.go index 6d55a47..a816345 100644 --- a/collector/livestatus/CommentData.go +++ b/collector/livestatus/CommentData.go @@ -19,7 +19,7 @@ func (comment *CommentData) sanitizeValues() { } //PrintForInfluxDB prints the data in influxdb lineformat -func (comment CommentData) PrintForInfluxDB(version string) string { +func (comment CommentData) PrintForInfluxDB(version string, i int) string { comment.sanitizeValues() if helper.VersionOrdinal(version) >= helper.VersionOrdinal("0.9") { var tags string diff --git a/collector/livestatus/DowntimeData.go b/collector/livestatus/DowntimeData.go index 59ccaa8..4f39c24 100644 --- a/collector/livestatus/DowntimeData.go +++ b/collector/livestatus/DowntimeData.go @@ -21,7 +21,7 @@ func (downtime *DowntimeData) sanitizeValues() { } //PrintForInfluxDB prints the data in influxdb lineformat -func (downtime DowntimeData) PrintForInfluxDB(version string) string { +func (downtime DowntimeData) PrintForInfluxDB(version string, i int) string { downtime.sanitizeValues() if helper.VersionOrdinal(version) >= helper.VersionOrdinal("0.9") { tags := ",type=downtime,author=" + downtime.author diff --git a/collector/livestatus/NotificationData.go b/collector/livestatus/NotificationData.go index dbc814f..08e7eb8 100644 --- a/collector/livestatus/NotificationData.go +++ b/collector/livestatus/NotificationData.go @@ -23,7 +23,7 @@ func (notification *NotificationData) sanitizeValues() { } //PrintForInfluxDB prints the data in influxdb lineformat -func (notification NotificationData) PrintForInfluxDB(version string) string { +func (notification NotificationData) PrintForInfluxDB(version string, i int) string { notification.sanitizeValues() if helper.VersionOrdinal(version) >= helper.VersionOrdinal("0.9") { var tags string diff --git a/collector/nagflux/NagfluxPrintable.go b/collector/nagflux/NagfluxPrintable.go index fdab76d..27c8a35 100644 --- a/collector/nagflux/NagfluxPrintable.go +++ b/collector/nagflux/NagfluxPrintable.go @@ -16,7 +16,7 @@ type Printable struct { } //PrintForInfluxDB prints the data in influxdb lineformat -func (p Printable) PrintForInfluxDB(version string) string { +func (p Printable) PrintForInfluxDB(version string, i int) string { if helper.VersionOrdinal(version) >= helper.VersionOrdinal("0.9") { line := p.Table if len(p.tags) > 0 { diff --git a/collector/spoolfile/performanceData.go b/collector/spoolfile/performanceData.go index e1dcfb5..c2e6548 100644 --- a/collector/spoolfile/performanceData.go +++ b/collector/spoolfile/performanceData.go @@ -21,7 +21,7 @@ type PerformanceData struct { } //PrintForInfluxDB prints the data in influxdb lineformat -func (p PerformanceData) PrintForInfluxDB(version string) string { +func (p PerformanceData) PrintForInfluxDB(version string, i int) string { if helper.VersionOrdinal(version) >= helper.VersionOrdinal("0.9") { tableName := fmt.Sprintf(`metrics,host=%s`, helper.SanitizeInfluxInput(p.Hostname)) if p.Service == "" { @@ -30,6 +30,11 @@ func (p PerformanceData) PrintForInfluxDB(version string) string { tableName += fmt.Sprintf(`,service=%s`, helper.SanitizeInfluxInput(p.Service)) } var fieldsString = "" + if config.GetConfig().InfluxDBGlobal.StorePerformanceLabelAsField || config.GetConfig().InfluxDBGlobal.StoreCommandAsField { + tableName += fmt.Sprintf(`,performanceLabelIndex=%d`, + i, + ) + } if config.GetConfig().InfluxDBGlobal.StoreCommandAsField { fieldsString += fmt.Sprintf(`,command="%s"`, helper.SanitizeInfluxField(p.Command), diff --git a/target/influx/Worker.go b/target/influx/Worker.go index 61a5de3..d87fd02 100644 --- a/target/influx/Worker.go +++ b/target/influx/Worker.go @@ -125,8 +125,8 @@ func (worker Worker) sendBuffer(queries []collector.Printable) { } var lineQueries []string - for _, query := range queries { - cast, castErr := worker.castJobToString(query) + for i, query := range queries { + cast, castErr := worker.castJobToString(query, i) if castErr == nil { lineQueries = append(lineQueries, cast) } @@ -192,7 +192,7 @@ func (worker Worker) readQueriesFromQueue() []string { select { case query = <-worker.jobs: if query.TestTargetFilter(worker.target.Name) { - cast, err := worker.castJobToString(query) + cast, err := worker.castJobToString(query, 0) if err == nil { queries = append(queries, cast) } @@ -305,12 +305,12 @@ func (worker Worker) dumpQueries(filename string, queries []string) { } //Converts an collector.Printable to a string. -func (worker Worker) castJobToString(job collector.Printable) (string, error) { +func (worker Worker) castJobToString(job collector.Printable, i int) (string, error) { var result string var err error if helper.VersionOrdinal(worker.version) >= helper.VersionOrdinal("0.9") { - result = job.PrintForInfluxDB(worker.version) + result = job.PrintForInfluxDB(worker.version, i) } else { worker.log.Fatalf("This influxversion [%s] given in the config is not supported", worker.version) err = errors.New("This influxversion given in the config is not supported") From 64fe50fce44bc11a58cdedb932d1b4c40e56379d Mon Sep 17 00:00:00 2001 From: Gianluca Piccolo Date: Fri, 26 Oct 2018 09:26:32 +0200 Subject: [PATCH 3/3] Remove the store command as field feature --- collector/spoolfile/performanceData.go | 15 +++++---------- config.gcfg.example | 1 - config/Config.go | 11 +++++------ 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/collector/spoolfile/performanceData.go b/collector/spoolfile/performanceData.go index c2e6548..5935b7f 100644 --- a/collector/spoolfile/performanceData.go +++ b/collector/spoolfile/performanceData.go @@ -30,20 +30,15 @@ func (p PerformanceData) PrintForInfluxDB(version string, i int) string { tableName += fmt.Sprintf(`,service=%s`, helper.SanitizeInfluxInput(p.Service)) } var fieldsString = "" - if config.GetConfig().InfluxDBGlobal.StorePerformanceLabelAsField || config.GetConfig().InfluxDBGlobal.StoreCommandAsField { + if config.GetConfig().InfluxDBGlobal.StorePerformanceLabelAsField { tableName += fmt.Sprintf(`,performanceLabelIndex=%d`, i, ) } - if config.GetConfig().InfluxDBGlobal.StoreCommandAsField { - fieldsString += fmt.Sprintf(`,command="%s"`, - helper.SanitizeInfluxField(p.Command), - ) - } else { - tableName += fmt.Sprintf(`,command=%s`, - helper.SanitizeInfluxInput(p.Command), - ) - } + + tableName += fmt.Sprintf(`,command=%s`, + helper.SanitizeInfluxInput(p.Command), + ) if config.GetConfig().InfluxDBGlobal.StorePerformanceLabelAsField { fieldsString += fmt.Sprintf(`,performanceLabel="%s"`, helper.SanitizeInfluxField(p.PerformanceLabel), diff --git a/config.gcfg.example b/config.gcfg.example index d124544..b877d6d 100644 --- a/config.gcfg.example +++ b/config.gcfg.example @@ -59,7 +59,6 @@ # cause write timeouts. # In such cases, setting PerformanceLabel as Field value will significantly reduce the series # cardinality. - StoreCommandAsField = false StorePerformanceLabelAsField = false [InfluxDB "nagflux"] diff --git a/config/Config.go b/config/Config.go index b13c9ad..113da27 100644 --- a/config/Config.go +++ b/config/Config.go @@ -30,12 +30,11 @@ type Config struct { PrometheusAddress string } InfluxDBGlobal struct { - CreateDatabaseIfNotExists bool - NastyString string - NastyStringToReplace string - HostcheckAlias string - ClientTimeout int - StoreCommandAsField bool + CreateDatabaseIfNotExists bool + NastyString string + NastyStringToReplace string + HostcheckAlias string + ClientTimeout int StorePerformanceLabelAsField bool } InfluxDB map[string]*struct {