From 4c045281f304504befe9aaa1bd79353e5ea229d4 Mon Sep 17 00:00:00 2001 From: Pierre Tessier Date: Wed, 14 Nov 2018 15:35:35 -0500 Subject: [PATCH 01/12] Initial checkin for sampling processor --- plugins/processors/sampling/sampling.go | 72 +++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 plugins/processors/sampling/sampling.go diff --git a/plugins/processors/sampling/sampling.go b/plugins/processors/sampling/sampling.go new file mode 100644 index 0000000000000..38630baf4a375 --- /dev/null +++ b/plugins/processors/sampling/sampling.go @@ -0,0 +1,72 @@ +package sampling + +import ( + "time" + + "bytes" + "github.com/influxdata/telegraf" + "github.com/influxdata/telegraf/internal" + "github.com/influxdata/telegraf/plugins/processors" +) + +type Sampling struct { + Period internal.Duration + FieldKeys bool + + sampled map[string]struct{} + samplingEnd time.Time +} + +var empty struct{} + +var sampleConfig = ` +` + +func (s *Sampling) SampleConfig() string { + return sampleConfig +} + +func (s *Sampling) Description() string { + return "Samples all metrics based on a specified time period." +} + +func (s *Sampling) Apply(in ...telegraf.Metric) []telegraf.Metric { + if s.samplingEnd.Before(time.Now()) { + s.samplingEnd = time.Now().Add(s.Period.Duration) + s.sampled = make(map[string]struct{}) + } + + out := []telegraf.Metric{} + + for _, metric := range in { + key := s.metricKey(metric) + if _, ok := s.sampled[key]; !ok { + out = append(out, metric) + s.sampled[key] = empty + } + } + + return out +} + +func (s *Sampling) metricKey(metric telegraf.Metric) string { + key := bytes.NewBufferString("") + + key.WriteString(metric.Name()) + key.WriteString(":") + for k, v := range metric.Tags() { + key.WriteString(k) + key.WriteString("=") + key.WriteString(v) + } + + return key.String() +} + +func init() { + processors.Add("sampling", func() telegraf.Processor { + return &Sampling{ + sampled: make(map[string]struct{}), + } + }) +} From be2128c8fee37c2b0f43407c4f991828ca22af37 Mon Sep 17 00:00:00 2001 From: Pierre Tessier Date: Mon, 19 Nov 2018 16:42:28 -0500 Subject: [PATCH 02/12] New connection framework using wavefront-go-sdk --- Gopkg.toml | 5 + plugins/outputs/wavefront/README.md | 13 +- plugins/outputs/wavefront/wavefront.go | 137 ++++++++++++++------ plugins/outputs/wavefront/wavefront_test.go | 9 +- 4 files changed, 123 insertions(+), 41 deletions(-) diff --git a/Gopkg.toml b/Gopkg.toml index 23b8444fe6523..6502f4c12b3b3 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -245,3 +245,8 @@ [[override]] name = "github.com/vishvananda/netlink" revision = "b2de5d10e38ecce8607e6b438b6d174f389a004e" + +[[constraint]] + name = "github.com/wavefronthq/wavefront-sdk-go" + version = "v0.9.0" + diff --git a/plugins/outputs/wavefront/README.md b/plugins/outputs/wavefront/README.md index be8fcd7dcdba4..5f034cc525987 100644 --- a/plugins/outputs/wavefront/README.md +++ b/plugins/outputs/wavefront/README.md @@ -8,10 +8,17 @@ This plugin writes to a [Wavefront](https://www.wavefront.com) proxy, in Wavefro ```toml # Configuration for Wavefront output [[outputs.wavefront]] - ## DNS name of the wavefront proxy server + ## Url for Wavefront Direct Ingestion or using HTTP with Wavefront Proxy + ## If using Wavefront Proxy, also specify port. example: http://proxyserver:2878 + url = "https://metrics.wavefront.com" + + ## Authentication Token for Wavefront. Only required if using Direct Ingestion + #token = "DUMMY_TOKEN" + + ## DNS name of the wavefront proxy server. Do not use if url is specified host = "wavefront.example.com" - ## Port that the Wavefront proxy server listens on + ## Port that the Wavefront proxy server listens on. Do not use if url is specified port = 2878 ## prefix for metrics keys @@ -32,7 +39,7 @@ This plugin writes to a [Wavefront](https://www.wavefront.com) proxy, in Wavefro #use_regex = false ## point tags to use as the source name for Wavefront (if none found, host will be used) - #source_override = ["hostname", "agent_host", "node_host"] + #source_override = ["hostname", "address", "agent_host", "node_host"] ## whether to convert boolean values to numeric values, with false -> 0.0 and true -> 1.0. default is true #convert_bool = true diff --git a/plugins/outputs/wavefront/wavefront.go b/plugins/outputs/wavefront/wavefront.go index ef36d1804045f..66e354b253006 100644 --- a/plugins/outputs/wavefront/wavefront.go +++ b/plugins/outputs/wavefront/wavefront.go @@ -1,24 +1,22 @@ package wavefront import ( - "bytes" "fmt" "log" - "net" "regexp" - "strconv" "strings" - "time" - "github.com/influxdata/telegraf" "github.com/influxdata/telegraf/plugins/outputs" + wavefront "github.com/wavefronthq/wavefront-sdk-go/senders" ) type Wavefront struct { - Prefix string + Url string + Token string Host string Port int + Prefix string SimpleFields bool MetricSeparator string ConvertPaths bool @@ -26,6 +24,8 @@ type Wavefront struct { UseRegex bool SourceOverride []string StringToNumber map[string][]map[string]float64 + + sender wavefront.Sender } // catch many of the invalid chars that could appear in a metric or tag name @@ -40,16 +40,27 @@ var sanitizedChars = strings.NewReplacer( // instead of Replacer which may miss some special characters we can use a regex pattern, but this is significantly slower than Replacer var sanitizedRegex = regexp.MustCompile("[^a-zA-Z\\d_.-]") +var tagValueReplacer = strings.NewReplacer("*", "-") + +/* var tagValueReplacer = strings.NewReplacer("\"", "\\\"", "*", "-") +*/ var pathReplacer = strings.NewReplacer("_", "_") var sampleConfig = ` - ## DNS name of the wavefront proxy server - host = "wavefront.example.com" + ## Url for Wavefront Direct Ingestion or using HTTP with Wavefront Proxy + ## If using Wavefront Proxy, also specify port. example: http://proxyserver:2878 + url = "https://metrics.wavefront.com" + + ## Authentication Token for Wavefront. Only required if using Direct Ingestion + #token = "DUMMY_TOKEN" + + ## DNS name of the wavefront proxy server. Do not use if url is specified + #host = "wavefront.example.com" - ## Port that the Wavefront proxy server listens on - port = 2878 + ## Port that the Wavefront proxy server listens on. Do not use if url is specified + #port = 2878 ## prefix for metrics keys #prefix = "my.specific.prefix." @@ -69,7 +80,7 @@ var sampleConfig = ` #use_regex = false ## point tags to use as the source name for Wavefront (if none found, host will be used) - #source_override = ["hostname", "agent_host", "node_host"] + #source_override = ["hostname", "address", agent_host", "node_host"] ## whether to convert boolean values to numeric values, with false -> 0.0 and true -> 1.0. default true #convert_bool = true @@ -92,44 +103,77 @@ type MetricPoint struct { } func (w *Wavefront) Connect() error { + + if w.Url != "" { + log.Printf("D! Output [wavefront] connecting over http/https using Url: %s", w.Url) + sender, err := wavefront.NewDirectSender(&wavefront.DirectConfiguration{ + Server: w.Url, + Token: w.Token, + FlushIntervalSeconds: 5, + }) + if err != nil { + return fmt.Errorf("Wavefront: Could not create Wavefront Sender for Url: %s", w.Url) + } + w.sender = sender + } else { + log.Printf("D! Output [wavefront] connecting over tcp using Host: %s and Port: %d", w.Host, w.Port) + sender, err := wavefront.NewProxySender(&wavefront.ProxyConfiguration{ + Host: w.Host, + MetricsPort: w.Port, + FlushIntervalSeconds: 5, + }) + if err != nil { + return fmt.Errorf("Wavefront: Could not create Wavefront Sender for Host: %s and Port: %d", w.Host, w.Port) + } + w.sender = sender + } + /* + // Test Connection to Wavefront proxy Server + uri := fmt.Sprintf("%s:%d", w.Host, w.Port) + _, err := net.ResolveTCPAddr("tcp", uri) + if err != nil { + return fmt.Errorf("Wavefront: TCP address cannot be resolved %s", err.Error()) + } + connection, err := net.Dial("tcp", uri) + if err != nil { + return fmt.Errorf("Wavefront: TCP connect fail %s", err.Error()) + } + defer connection.Close() + */ + if w.ConvertPaths && w.MetricSeparator == "_" { w.ConvertPaths = false } if w.ConvertPaths { pathReplacer = strings.NewReplacer("_", w.MetricSeparator) } - - // Test Connection to Wavefront proxy Server - uri := fmt.Sprintf("%s:%d", w.Host, w.Port) - _, err := net.ResolveTCPAddr("tcp", uri) - if err != nil { - return fmt.Errorf("Wavefront: TCP address cannot be resolved %s", err.Error()) - } - connection, err := net.Dial("tcp", uri) - if err != nil { - return fmt.Errorf("Wavefront: TCP connect fail %s", err.Error()) - } - defer connection.Close() return nil } func (w *Wavefront) Write(metrics []telegraf.Metric) error { - // Send Data to Wavefront proxy Server - uri := fmt.Sprintf("%s:%d", w.Host, w.Port) - connection, err := net.Dial("tcp", uri) - if err != nil { - return fmt.Errorf("Wavefront: TCP connect fail %s", err.Error()) - } - defer connection.Close() - connection.SetWriteDeadline(time.Now().Add(5 * time.Second)) + /* + // Send Data to Wavefront proxy Server + uri := fmt.Sprintf("%s:%d", w.Host, w.Port) + connection, err := net.Dial("tcp", uri) + if err != nil { + return fmt.Errorf("Wavefront: TCP connect fail %s", err.Error()) + } + defer connection.Close() + connection.SetWriteDeadline(time.Now().Add(5 * time.Second)) + */ + + // defer w.sender.Flush() for _, m := range metrics { - for _, metricPoint := range buildMetrics(m, w) { - metricLine := formatMetricPoint(metricPoint, w) - _, err := connection.Write([]byte(metricLine)) + for _, point := range buildMetrics(m, w) { + /* + metricLine := formatMetricPoint(point, w) + _, err := connection.Write([]byte(metricLine)) + */ + err := w.sender.SendMetric(point.Metric, point.Value, point.Timestamp, point.Source, point.Tags) if err != nil { - return fmt.Errorf("Wavefront: TCP writing error %s", err.Error()) + return fmt.Errorf("Wavefront sending error: %s", err.Error()) } } } @@ -188,8 +232,8 @@ func buildTags(mTags map[string]string, w *Wavefront) (string, map[string]string } } + // find source, use source_override property if needed var source string - if s, ok := mTags["source"]; ok { source = s delete(mTags, "source") @@ -214,10 +258,25 @@ func buildTags(mTags map[string]string, w *Wavefront) (string, map[string]string source = mTags["host"] } } + source = tagValueReplacer.Replace(source) + // remove default host tag delete(mTags, "host") - return tagValueReplacer.Replace(source), mTags + // sanitize tag keys and values + tags := make(map[string]string) + for k, v := range mTags { + var key string + if w.UseRegex { + key = sanitizedRegex.ReplaceAllLiteralString(k, "-") + } else { + key = sanitizedChars.Replace(k) + } + val := tagValueReplacer.Replace(v) + tags[key] = val + } + + return source, tags } func buildValue(v interface{}, name string, w *Wavefront) (float64, error) { @@ -255,6 +314,7 @@ func buildValue(v interface{}, name string, w *Wavefront) (float64, error) { return 0, fmt.Errorf("unexpected type: %T, with value: %v, for: %s", v, v, name) } +/* func formatMetricPoint(metricPoint *MetricPoint, w *Wavefront) string { buffer := bytes.NewBufferString("") buffer.WriteString(metricPoint.Metric) @@ -282,6 +342,7 @@ func formatMetricPoint(metricPoint *MetricPoint, w *Wavefront) string { return buffer.String() } +*/ func (w *Wavefront) SampleConfig() string { return sampleConfig @@ -292,12 +353,14 @@ func (w *Wavefront) Description() string { } func (w *Wavefront) Close() error { + w.sender.Close() return nil } func init() { outputs.Add("wavefront", func() telegraf.Output { return &Wavefront{ + Token: "DUMMY_TOKEN", MetricSeparator: ".", ConvertPaths: true, ConvertBool: true, diff --git a/plugins/outputs/wavefront/wavefront_test.go b/plugins/outputs/wavefront/wavefront_test.go index f1722e6688e51..0c967c15f5660 100644 --- a/plugins/outputs/wavefront/wavefront_test.go +++ b/plugins/outputs/wavefront/wavefront_test.go @@ -140,6 +140,11 @@ func TestBuildTags(t *testing.T) { "aaa", map[string]string{"dc": "bbb"}, }, + { + map[string]string{"host": "aaa", "dc": "a*$a\\abbb\"som/et|hing else", "bad#k%e/y that*sho\\uld work": "value1"}, + "aaa", + map[string]string{"dc": "a-$a\\abbb\"som/et|hing else", "bad-k-e-y-that-sho-uld-work": "value1"}, + }, } for _, tt := range tagtests { @@ -189,7 +194,7 @@ func TestBuildTagsWithSource(t *testing.T) { }, { map[string]string{"something": "abc", "host": "r*@l\"Ho/st"}, - "r-@l\\\"Ho/st", + "r-@l\"Ho/st", map[string]string{"something": "abc"}, }, } @@ -264,6 +269,7 @@ func TestBuildValueString(t *testing.T) { } +/* func TestFormatMetricPoint(t *testing.T) { w := defaultWavefront() @@ -284,6 +290,7 @@ func TestFormatMetricPoint(t *testing.T) { } } +*/ // Benchmarks to test performance of string replacement via Regex and Replacer var testString = "this_is*my!test/string\\for=replacement" From 2250da761102cacc501aa38883d7fb008bf2768e Mon Sep 17 00:00:00 2001 From: Pierre Tessier Date: Tue, 18 Dec 2018 16:27:00 -0500 Subject: [PATCH 03/12] Deprecated string_to_number and readme --- plugins/outputs/wavefront/README.md | 37 +++++-------- plugins/outputs/wavefront/wavefront.go | 75 ++++---------------------- 2 files changed, 22 insertions(+), 90 deletions(-) diff --git a/plugins/outputs/wavefront/README.md b/plugins/outputs/wavefront/README.md index 5f034cc525987..0cd833e678be9 100644 --- a/plugins/outputs/wavefront/README.md +++ b/plugins/outputs/wavefront/README.md @@ -6,51 +6,41 @@ This plugin writes to a [Wavefront](https://www.wavefront.com) proxy, in Wavefro ### Configuration: ```toml -# Configuration for Wavefront output -[[outputs.wavefront]] - ## Url for Wavefront Direct Ingestion or using HTTP with Wavefront Proxy - ## If using Wavefront Proxy, also specify port. example: http://proxyserver:2878 + ## Url for Wavefront Direct Ingestion or using HTTP with Wavefront Proxy + ## If using Wavefront Proxy, also specify port. example: http://proxyserver:2878 url = "https://metrics.wavefront.com" ## Authentication Token for Wavefront. Only required if using Direct Ingestion #token = "DUMMY_TOKEN" ## DNS name of the wavefront proxy server. Do not use if url is specified - host = "wavefront.example.com" + #host = "wavefront.example.com" ## Port that the Wavefront proxy server listens on. Do not use if url is specified - port = 2878 + #port = 2878 ## prefix for metrics keys #prefix = "my.specific.prefix." - ## wether to use "value" for name of simple fields. default is false + ## whether to use "value" for name of simple fields #simple_fields = false - ## character to use between metric and field name. default is . (dot) + ## character to use between metric and field name. defaults to . (dot) #metric_separator = "." - ## Convert metric name paths to use metricSeperator character - ## When true will convert all _ (underscore) chartacters in final metric name. default is true + ## Convert metric name paths to use metricSeparator character + ## When true (default) will convert all _ (underscore) characters in final metric name #convert_paths = true ## Use Regex to sanitize metric and tag names from invalid characters - ## Regex is more thorough, but significantly slower. default is false + ## Regex is more thorough, but significantly slower #use_regex = false ## point tags to use as the source name for Wavefront (if none found, host will be used) - #source_override = ["hostname", "address", "agent_host", "node_host"] + #source_override = ["hostname", "address", agent_host", "node_host"] - ## whether to convert boolean values to numeric values, with false -> 0.0 and true -> 1.0. default is true + ## whether to convert boolean values to numeric values, with false -> 0.0 and true -> 1.0. default true #convert_bool = true - - ## Define a mapping, namespaced by metric prefix, from string values to numeric values - ## The example below maps "green" -> 1.0, "yellow" -> 0.5, "red" -> 0.0 for - ## any metrics beginning with "elasticsearch" - #[[outputs.wavefront.string_to_number.elasticsearch]] - # green = 1.0 - # yellow = 0.5 - # red = 0.0 ``` @@ -83,6 +73,5 @@ More information about the Wavefront data format is available [here](https://com ### Allowed values for metrics -Wavefront allows `integers` and `floats` as input values. It will ignore most `strings`, but when configured -will map certain `strings` to numeric values. By default it also maps `bool` values to numeric, false -> 0.0, -true -> 1.0 \ No newline at end of file +Wavefront allows `integers` and `floats` as input values. By default it also maps `bool` values to numeric, false -> 0.0, +true -> 1.0. To map `strings` use the [enum](../processor/enum) processor plugin. \ No newline at end of file diff --git a/plugins/outputs/wavefront/wavefront.go b/plugins/outputs/wavefront/wavefront.go index 66e354b253006..64207c2c7d13d 100644 --- a/plugins/outputs/wavefront/wavefront.go +++ b/plugins/outputs/wavefront/wavefront.go @@ -42,10 +42,6 @@ var sanitizedRegex = regexp.MustCompile("[^a-zA-Z\\d_.-]") var tagValueReplacer = strings.NewReplacer("*", "-") -/* -var tagValueReplacer = strings.NewReplacer("\"", "\\\"", "*", "-") -*/ - var pathReplacer = strings.NewReplacer("_", "_") var sampleConfig = ` @@ -71,8 +67,8 @@ var sampleConfig = ` ## character to use between metric and field name. defaults to . (dot) #metric_separator = "." - ## Convert metric name paths to use metricSeperator character - ## When true (default) will convert all _ (underscore) chartacters in final metric name + ## Convert metric name paths to use metricSeparator character + ## When true (default) will convert all _ (underscore) characters in final metric name #convert_paths = true ## Use Regex to sanitize metric and tag names from invalid characters @@ -86,8 +82,7 @@ var sampleConfig = ` #convert_bool = true ## Define a mapping, namespaced by metric prefix, from string values to numeric values - ## The example below maps "green" -> 1.0, "yellow" -> 0.5, "red" -> 0.0 for - ## any metrics beginning with "elasticsearch" + ## deprecated in 1.9; use the enum processor plugin #[[outputs.wavefront.string_to_number.elasticsearch]] # green = 1.0 # yellow = 0.5 @@ -104,8 +99,12 @@ type MetricPoint struct { func (w *Wavefront) Connect() error { + if len(w.StringToNumber) > 0 { + log.Print("W! [outputs.wavefront] The string_to_number option is deprecated; please use the enum processor instead") + } + if w.Url != "" { - log.Printf("D! Output [wavefront] connecting over http/https using Url: %s", w.Url) + log.Printf("D! [outputs.wavefront] connecting over http/https using Url: %s", w.Url) sender, err := wavefront.NewDirectSender(&wavefront.DirectConfiguration{ Server: w.Url, Token: w.Token, @@ -127,19 +126,6 @@ func (w *Wavefront) Connect() error { } w.sender = sender } - /* - // Test Connection to Wavefront proxy Server - uri := fmt.Sprintf("%s:%d", w.Host, w.Port) - _, err := net.ResolveTCPAddr("tcp", uri) - if err != nil { - return fmt.Errorf("Wavefront: TCP address cannot be resolved %s", err.Error()) - } - connection, err := net.Dial("tcp", uri) - if err != nil { - return fmt.Errorf("Wavefront: TCP connect fail %s", err.Error()) - } - defer connection.Close() - */ if w.ConvertPaths && w.MetricSeparator == "_" { w.ConvertPaths = false @@ -152,19 +138,6 @@ func (w *Wavefront) Connect() error { func (w *Wavefront) Write(metrics []telegraf.Metric) error { - /* - // Send Data to Wavefront proxy Server - uri := fmt.Sprintf("%s:%d", w.Host, w.Port) - connection, err := net.Dial("tcp", uri) - if err != nil { - return fmt.Errorf("Wavefront: TCP connect fail %s", err.Error()) - } - defer connection.Close() - connection.SetWriteDeadline(time.Now().Add(5 * time.Second)) - */ - - // defer w.sender.Flush() - for _, m := range metrics { for _, point := range buildMetrics(m, w) { /* @@ -209,7 +182,7 @@ func buildMetrics(m telegraf.Metric, w *Wavefront) []*MetricPoint { metricValue, buildError := buildValue(value, metric.Metric, w) if buildError != nil { - log.Printf("D! Output [wavefront] %s\n", buildError.Error()) + log.Printf("D! [outputs.wavefront] %s\n", buildError.Error()) continue } metric.Value = metricValue @@ -314,36 +287,6 @@ func buildValue(v interface{}, name string, w *Wavefront) (float64, error) { return 0, fmt.Errorf("unexpected type: %T, with value: %v, for: %s", v, v, name) } -/* -func formatMetricPoint(metricPoint *MetricPoint, w *Wavefront) string { - buffer := bytes.NewBufferString("") - buffer.WriteString(metricPoint.Metric) - buffer.WriteString(" ") - buffer.WriteString(strconv.FormatFloat(metricPoint.Value, 'f', 6, 64)) - buffer.WriteString(" ") - buffer.WriteString(strconv.FormatInt(metricPoint.Timestamp, 10)) - buffer.WriteString(" source=\"") - buffer.WriteString(metricPoint.Source) - buffer.WriteString("\"") - - for k, v := range metricPoint.Tags { - buffer.WriteString(" ") - if w.UseRegex { - buffer.WriteString(sanitizedRegex.ReplaceAllLiteralString(k, "-")) - } else { - buffer.WriteString(sanitizedChars.Replace(k)) - } - buffer.WriteString("=\"") - buffer.WriteString(tagValueReplacer.Replace(v)) - buffer.WriteString("\"") - } - - buffer.WriteString("\n") - - return buffer.String() -} -*/ - func (w *Wavefront) SampleConfig() string { return sampleConfig } From 6a66c82e30256694763c5eac37649df41dc28766 Mon Sep 17 00:00:00 2001 From: Pierre Tessier Date: Tue, 18 Dec 2018 16:29:11 -0500 Subject: [PATCH 04/12] fixed url --- plugins/outputs/wavefront/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/outputs/wavefront/README.md b/plugins/outputs/wavefront/README.md index 0cd833e678be9..dc6aa08970c52 100644 --- a/plugins/outputs/wavefront/README.md +++ b/plugins/outputs/wavefront/README.md @@ -74,4 +74,4 @@ More information about the Wavefront data format is available [here](https://com ### Allowed values for metrics Wavefront allows `integers` and `floats` as input values. By default it also maps `bool` values to numeric, false -> 0.0, -true -> 1.0. To map `strings` use the [enum](../processor/enum) processor plugin. \ No newline at end of file +true -> 1.0. To map `strings` use the [enum](../../processors/enum) processor plugin. From db8bd689541d69cdc5036a50a648988f9a7d5720 Mon Sep 17 00:00:00 2001 From: Pierre Tessier Date: Tue, 18 Dec 2018 16:44:38 -0500 Subject: [PATCH 05/12] cleaned up default in sample config --- plugins/outputs/wavefront/README.md | 10 +++++----- plugins/outputs/wavefront/wavefront.go | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/plugins/outputs/wavefront/README.md b/plugins/outputs/wavefront/README.md index dc6aa08970c52..bb5169a746977 100644 --- a/plugins/outputs/wavefront/README.md +++ b/plugins/outputs/wavefront/README.md @@ -22,24 +22,24 @@ This plugin writes to a [Wavefront](https://www.wavefront.com) proxy, in Wavefro ## prefix for metrics keys #prefix = "my.specific.prefix." - ## whether to use "value" for name of simple fields + ## whether to use "value" for name of simple fields. default is false #simple_fields = false - ## character to use between metric and field name. defaults to . (dot) + ## character to use between metric and field name. default is . (dot) #metric_separator = "." ## Convert metric name paths to use metricSeparator character - ## When true (default) will convert all _ (underscore) characters in final metric name + ## When true (default) will convert all _ (underscore) characters in final metric name. default is true #convert_paths = true ## Use Regex to sanitize metric and tag names from invalid characters - ## Regex is more thorough, but significantly slower + ## Regex is more thorough, but significantly slower. default is false #use_regex = false ## point tags to use as the source name for Wavefront (if none found, host will be used) #source_override = ["hostname", "address", agent_host", "node_host"] - ## whether to convert boolean values to numeric values, with false -> 0.0 and true -> 1.0. default true + ## whether to convert boolean values to numeric values, with false -> 0.0 and true -> 1.0. default is true #convert_bool = true ``` diff --git a/plugins/outputs/wavefront/wavefront.go b/plugins/outputs/wavefront/wavefront.go index 64207c2c7d13d..a341ddb6c1cef 100644 --- a/plugins/outputs/wavefront/wavefront.go +++ b/plugins/outputs/wavefront/wavefront.go @@ -61,24 +61,24 @@ var sampleConfig = ` ## prefix for metrics keys #prefix = "my.specific.prefix." - ## whether to use "value" for name of simple fields + ## whether to use "value" for name of simple fields. default is false #simple_fields = false - ## character to use between metric and field name. defaults to . (dot) + ## character to use between metric and field name. default is . (dot) #metric_separator = "." ## Convert metric name paths to use metricSeparator character - ## When true (default) will convert all _ (underscore) characters in final metric name + ## When true (default) will convert all _ (underscore) characters in final metric name. default is true #convert_paths = true ## Use Regex to sanitize metric and tag names from invalid characters - ## Regex is more thorough, but significantly slower + ## Regex is more thorough, but significantly slower. default is false #use_regex = false ## point tags to use as the source name for Wavefront (if none found, host will be used) #source_override = ["hostname", "address", agent_host", "node_host"] - ## whether to convert boolean values to numeric values, with false -> 0.0 and true -> 1.0. default true + ## whether to convert boolean values to numeric values, with false -> 0.0 and true -> 1.0. default is true #convert_bool = true ## Define a mapping, namespaced by metric prefix, from string values to numeric values From 84ae10c40dab76a42c6dd48768f934309a2883e9 Mon Sep 17 00:00:00 2001 From: Pierre Tessier Date: Tue, 18 Dec 2018 21:04:18 -0500 Subject: [PATCH 06/12] cleaned up default in sample config --- plugins/outputs/wavefront/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/outputs/wavefront/README.md b/plugins/outputs/wavefront/README.md index bb5169a746977..e6b14332e0cbb 100644 --- a/plugins/outputs/wavefront/README.md +++ b/plugins/outputs/wavefront/README.md @@ -29,7 +29,7 @@ This plugin writes to a [Wavefront](https://www.wavefront.com) proxy, in Wavefro #metric_separator = "." ## Convert metric name paths to use metricSeparator character - ## When true (default) will convert all _ (underscore) characters in final metric name. default is true + ## When true will convert all _ (underscore) characters in final metric name. default is true #convert_paths = true ## Use Regex to sanitize metric and tag names from invalid characters From 38296837c9e02fbd13ed221598dc21d0cad97082 Mon Sep 17 00:00:00 2001 From: Pierre Tessier Date: Tue, 18 Dec 2018 21:05:57 -0500 Subject: [PATCH 07/12] cleaned up default in sample config --- plugins/outputs/wavefront/wavefront.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/outputs/wavefront/wavefront.go b/plugins/outputs/wavefront/wavefront.go index a341ddb6c1cef..dff58d6736214 100644 --- a/plugins/outputs/wavefront/wavefront.go +++ b/plugins/outputs/wavefront/wavefront.go @@ -68,7 +68,7 @@ var sampleConfig = ` #metric_separator = "." ## Convert metric name paths to use metricSeparator character - ## When true (default) will convert all _ (underscore) characters in final metric name. default is true + ## When true will convert all _ (underscore) characters in final metric name. default is true #convert_paths = true ## Use Regex to sanitize metric and tag names from invalid characters From 3fc7161b7a06376463fe7f2a670a3a95a460495c Mon Sep 17 00:00:00 2001 From: Pierre Tessier Date: Tue, 18 Dec 2018 21:08:05 -0500 Subject: [PATCH 08/12] cleaned up default in sample config --- plugins/processors/sampling/sampling.go | 72 ------------------------- 1 file changed, 72 deletions(-) delete mode 100644 plugins/processors/sampling/sampling.go diff --git a/plugins/processors/sampling/sampling.go b/plugins/processors/sampling/sampling.go deleted file mode 100644 index 38630baf4a375..0000000000000 --- a/plugins/processors/sampling/sampling.go +++ /dev/null @@ -1,72 +0,0 @@ -package sampling - -import ( - "time" - - "bytes" - "github.com/influxdata/telegraf" - "github.com/influxdata/telegraf/internal" - "github.com/influxdata/telegraf/plugins/processors" -) - -type Sampling struct { - Period internal.Duration - FieldKeys bool - - sampled map[string]struct{} - samplingEnd time.Time -} - -var empty struct{} - -var sampleConfig = ` -` - -func (s *Sampling) SampleConfig() string { - return sampleConfig -} - -func (s *Sampling) Description() string { - return "Samples all metrics based on a specified time period." -} - -func (s *Sampling) Apply(in ...telegraf.Metric) []telegraf.Metric { - if s.samplingEnd.Before(time.Now()) { - s.samplingEnd = time.Now().Add(s.Period.Duration) - s.sampled = make(map[string]struct{}) - } - - out := []telegraf.Metric{} - - for _, metric := range in { - key := s.metricKey(metric) - if _, ok := s.sampled[key]; !ok { - out = append(out, metric) - s.sampled[key] = empty - } - } - - return out -} - -func (s *Sampling) metricKey(metric telegraf.Metric) string { - key := bytes.NewBufferString("") - - key.WriteString(metric.Name()) - key.WriteString(":") - for k, v := range metric.Tags() { - key.WriteString(k) - key.WriteString("=") - key.WriteString(v) - } - - return key.String() -} - -func init() { - processors.Add("sampling", func() telegraf.Processor { - return &Sampling{ - sampled: make(map[string]struct{}), - } - }) -} From 6819e36e58ddd32277f6e836291e54973867c3cc Mon Sep 17 00:00:00 2001 From: Pierre Tessier Date: Tue, 18 Dec 2018 21:15:28 -0500 Subject: [PATCH 09/12] fixed a silly syntax error in sample config --- plugins/outputs/wavefront/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/outputs/wavefront/README.md b/plugins/outputs/wavefront/README.md index e6b14332e0cbb..bc2156b13b59a 100644 --- a/plugins/outputs/wavefront/README.md +++ b/plugins/outputs/wavefront/README.md @@ -37,7 +37,7 @@ This plugin writes to a [Wavefront](https://www.wavefront.com) proxy, in Wavefro #use_regex = false ## point tags to use as the source name for Wavefront (if none found, host will be used) - #source_override = ["hostname", "address", agent_host", "node_host"] + #source_override = ["hostname", "address", "agent_host", "node_host"] ## whether to convert boolean values to numeric values, with false -> 0.0 and true -> 1.0. default is true #convert_bool = true From eef7ef8e42e7ae0ae9c08b320280868a8268268c Mon Sep 17 00:00:00 2001 From: Pierre Tessier Date: Tue, 18 Dec 2018 21:16:06 -0500 Subject: [PATCH 10/12] fixed a silly syntax error in sample config --- plugins/outputs/wavefront/wavefront.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/outputs/wavefront/wavefront.go b/plugins/outputs/wavefront/wavefront.go index dff58d6736214..f479db3909053 100644 --- a/plugins/outputs/wavefront/wavefront.go +++ b/plugins/outputs/wavefront/wavefront.go @@ -76,7 +76,7 @@ var sampleConfig = ` #use_regex = false ## point tags to use as the source name for Wavefront (if none found, host will be used) - #source_override = ["hostname", "address", agent_host", "node_host"] + #source_override = ["hostname", "address", "agent_host", "node_host"] ## whether to convert boolean values to numeric values, with false -> 0.0 and true -> 1.0. default is true #convert_bool = true From 28676a1f45cfa7665aefe970e033a835023b58b3 Mon Sep 17 00:00:00 2001 From: Pierre Tessier Date: Thu, 20 Dec 2018 22:33:54 -0500 Subject: [PATCH 11/12] dep ensure --- Gopkg.lock | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Gopkg.lock b/Gopkg.lock index 8fd3e81c499b0..76780511525c3 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -1093,6 +1093,17 @@ revision = "e3a01f9611c32b2362366434bcd671516e78955d" version = "v0.18.0" +[[projects]] + digest = "1:c1855527c165f0224708fbc7d76843b4b20bcb74b328f212f8d0e9c855d4c49d" + name = "github.com/wavefronthq/wavefront-sdk-go" + packages = [ + "internal", + "senders", + ] + pruneopts = "" + revision = "12511c8b82654d412b0334768d94dc080b617fd1" + version = "v0.9.0" + [[projects]] branch = "master" digest = "1:98ed05e9796df287b90c1d96854e3913c8e349dbc546412d3cabb472ecf4b417" @@ -1545,6 +1556,7 @@ "github.com/vmware/govmomi/vim25/mo", "github.com/vmware/govmomi/vim25/soap", "github.com/vmware/govmomi/vim25/types", + "github.com/wavefronthq/wavefront-sdk-go/senders", "github.com/wvanbergen/kafka/consumergroup", "golang.org/x/net/context", "golang.org/x/net/html/charset", From b67c04aa7e3d35e446fe0d6b2371d45e3802c46f Mon Sep 17 00:00:00 2001 From: Pierre Tessier Date: Thu, 20 Dec 2018 22:34:17 -0500 Subject: [PATCH 12/12] removed commented code --- plugins/outputs/wavefront/wavefront.go | 4 ---- plugins/outputs/wavefront/wavefront_test.go | 23 --------------------- 2 files changed, 27 deletions(-) diff --git a/plugins/outputs/wavefront/wavefront.go b/plugins/outputs/wavefront/wavefront.go index f479db3909053..257c5512e8c1b 100644 --- a/plugins/outputs/wavefront/wavefront.go +++ b/plugins/outputs/wavefront/wavefront.go @@ -140,10 +140,6 @@ func (w *Wavefront) Write(metrics []telegraf.Metric) error { for _, m := range metrics { for _, point := range buildMetrics(m, w) { - /* - metricLine := formatMetricPoint(point, w) - _, err := connection.Write([]byte(metricLine)) - */ err := w.sender.SendMetric(point.Metric, point.Value, point.Timestamp, point.Source, point.Tags) if err != nil { return fmt.Errorf("Wavefront sending error: %s", err.Error()) diff --git a/plugins/outputs/wavefront/wavefront_test.go b/plugins/outputs/wavefront/wavefront_test.go index 0c967c15f5660..1fda6c7ae0b73 100644 --- a/plugins/outputs/wavefront/wavefront_test.go +++ b/plugins/outputs/wavefront/wavefront_test.go @@ -269,29 +269,6 @@ func TestBuildValueString(t *testing.T) { } -/* -func TestFormatMetricPoint(t *testing.T) { - w := defaultWavefront() - - testpoint := &MetricPoint{ - Metric: "test.metric.something", - Value: 123.456, - Timestamp: 1257894000, - Source: "testSource", - Tags: map[string]string{"sp*c!@l\"-ch/rs": "sp*c!@l/ val\"ue"}, - } - - expected := "test.metric.something 123.456000 1257894000 source=\"testSource\" sp-c--l--ch-rs=\"sp-c!@l/ val\\\"ue\"\n" - - received := formatMetricPoint(testpoint, w) - - if expected != received { - t.Errorf("\nexpected\t%+v\nreceived\t%+v\n", expected, received) - - } -} -*/ - // Benchmarks to test performance of string replacement via Regex and Replacer var testString = "this_is*my!test/string\\for=replacement"