From 6d73cb85cc7a96273a7f4708dabdb238598cd81c Mon Sep 17 00:00:00 2001
From: Leszek Charkiewicz <lcharkiewicz@users.noreply.github.com>
Date: Thu, 17 May 2018 23:24:51 +0200
Subject: [PATCH] Add consul service tags to metric (#4155)

---
 Godeps                               |  2 +-
 plugins/inputs/consul/README.md      |  5 ++++
 plugins/inputs/consul/consul.go      | 22 ++++++++++++++++-
 plugins/inputs/consul/consul_test.go | 35 +++++++++++++++++++++++++++-
 4 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/Godeps b/Godeps
index ff845aba..f44100c9 100644
--- a/Godeps
+++ b/Godeps
@@ -31,7 +31,7 @@ github.com/gorilla/mux 53c1911da2b537f792e7cafcb446b05ffe33b996
 github.com/go-redis/redis 73b70592cdaa9e6abdfcfbf97b4a90d80728c836
 github.com/go-sql-driver/mysql 2e00b5cd70399450106cec6431c2e2ce3cae5034
 github.com/hailocab/go-hostpool e80d13ce29ede4452c43dea11e79b9bc8a15b478
-github.com/hashicorp/consul 63d2fc68239b996096a1c55a0d4b400ea4c2583f
+github.com/hashicorp/consul 5174058f0d2bda63fa5198ab96c33d9a909c58ed
 github.com/influxdata/tail c43482518d410361b6c383d7aebce33d0471d7bc
 github.com/influxdata/toml 5d1d907f22ead1cd47adde17ceec5bda9cacaf8f
 github.com/influxdata/wlog 7c63b0a71ef8300adc255344d275e10e5c3a71ec
diff --git a/plugins/inputs/consul/README.md b/plugins/inputs/consul/README.md
index 42e1a133..f7dcdf36 100644
--- a/plugins/inputs/consul/README.md
+++ b/plugins/inputs/consul/README.md
@@ -33,6 +33,11 @@ report those stats already using StatsD protocol if needed.
   # tls_key = "/etc/telegraf/key.pem"
   ## Use TLS but skip chain & host verification
   # insecure_skip_verify = true
+
+  ## Consul checks' tag splitting
+  # When tags are formatted like "key:value" with ":" as a delimiter then
+  # they will be splitted and reported as proper key:value in Telegraf
+  # tag_delimiter = ":"
 ```
 
 ### Metrics:
diff --git a/plugins/inputs/consul/consul.go b/plugins/inputs/consul/consul.go
index fe9bde1d..8649184d 100644
--- a/plugins/inputs/consul/consul.go
+++ b/plugins/inputs/consul/consul.go
@@ -2,6 +2,7 @@ package consul
 
 import (
 	"net/http"
+	"strings"
 
 	"github.com/hashicorp/consul/api"
 	"github.com/influxdata/telegraf"
@@ -17,6 +18,7 @@ type Consul struct {
 	Password   string
 	Datacentre string
 	tls.ClientConfig
+	TagDelimiter string
 
 	// client used to connect to Consul agnet
 	client *api.Client
@@ -45,6 +47,11 @@ var sampleConfig = `
   # tls_key = "/etc/telegraf/key.pem"
   ## Use TLS but skip chain & host verification
   # insecure_skip_verify = true
+
+  ## Consul checks' tag splitting
+  # When tags are formatted like "key:value" with ":" as a delimiter then
+  # they will be splitted and reported as proper key:value in Telegraf
+  # tag_delimiter = ":"
 `
 
 func (c *Consul) Description() string {
@@ -86,7 +93,7 @@ func (c *Consul) createAPIClient() (*api.Client, error) {
 		return nil, err
 	}
 
-	config.HttpClient.Transport = &http.Transport{
+	config.Transport = &http.Transport{
 		TLSClientConfig: tlsCfg,
 	}
 
@@ -111,6 +118,19 @@ func (c *Consul) GatherHealthCheck(acc telegraf.Accumulator, checks []*api.Healt
 		tags["service_name"] = check.ServiceName
 		tags["check_id"] = check.CheckID
 
+		for _, checkTag := range check.ServiceTags {
+			if c.TagDelimiter != "" {
+				splittedTag := strings.SplitN(checkTag, c.TagDelimiter, 2)
+				if len(splittedTag) == 1 {
+					tags[checkTag] = checkTag
+				} else if len(splittedTag) == 2 {
+					tags[splittedTag[0]] = splittedTag[1]
+				}
+			} else {
+				tags[checkTag] = checkTag
+			}
+		}
+
 		acc.AddFields("consul_health_checks", record, tags)
 	}
 }
diff --git a/plugins/inputs/consul/consul_test.go b/plugins/inputs/consul/consul_test.go
index bbb43d06..e3a7f2fd 100644
--- a/plugins/inputs/consul/consul_test.go
+++ b/plugins/inputs/consul/consul_test.go
@@ -17,6 +17,7 @@ var sampleChecks = []*api.HealthCheck{
 		Output:      "OK",
 		ServiceID:   "foo.123",
 		ServiceName: "foo",
+		ServiceTags: []string{"bar", "env:sandbox", "tagkey:value:stillvalue"},
 	},
 }
 
@@ -30,15 +31,47 @@ func TestGatherHealthCheck(t *testing.T) {
 		"service_id": "foo.123",
 	}
 
+	expectedTags := map[string]string{
+		"node":                    "localhost",
+		"service_name":            "foo",
+		"check_id":                "foo.health123",
+		"bar":                     "bar",
+		"env:sandbox":             "env:sandbox",
+		"tagkey:value:stillvalue": "tagkey:value:stillvalue",
+	}
+
+	var acc testutil.Accumulator
+
+	consul := &Consul{}
+	consul.GatherHealthCheck(&acc, sampleChecks)
+
+	acc.AssertContainsTaggedFields(t, "consul_health_checks", expectedFields, expectedTags)
+}
+
+func TestGatherHealthCheckWithDelimitedTags(t *testing.T) {
+	expectedFields := map[string]interface{}{
+		"check_name": "foo.health",
+		"status":     "passing",
+		"passing":    1,
+		"critical":   0,
+		"warning":    0,
+		"service_id": "foo.123",
+	}
+
 	expectedTags := map[string]string{
 		"node":         "localhost",
 		"service_name": "foo",
 		"check_id":     "foo.health123",
+		"bar":          "bar",
+		"env":          "sandbox",
+		"tagkey":       "value:stillvalue",
 	}
 
 	var acc testutil.Accumulator
 
-	consul := &Consul{}
+	consul := &Consul{
+		TagDelimiter: ":",
+	}
 	consul.GatherHealthCheck(&acc, sampleChecks)
 
 	acc.AssertContainsTaggedFields(t, "consul_health_checks", expectedFields, expectedTags)
-- 
GitLab