From 893357f01e5533881ac3e5d64b1be4d6ebf5bd3c Mon Sep 17 00:00:00 2001
From: Dhruv Bansal <dhruv@ph.utexas.edu>
Date: Wed, 3 Feb 2016 22:06:41 +0000
Subject: [PATCH] Updated Riemann output:

* Customizable 'separator' option instead of hard-coded '_'

* String values are sent as "State" instead of "Metric", preventing
  Riemann from rejecting them

* Riemann service name is set to an (ugly) combination of input name &
  (sorted) tags' values...this allows connecting different events for
  the same input together on the Riemann side

closes #642
---
 CHANGELOG.md                       |  1 +
 plugins/outputs/riemann/riemann.go | 46 +++++++++++++++++++++++++++---
 2 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index bff50a5f..548ea993 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,7 @@ parsing JSON data as it does now.
 ### Bugfixes
 - [#443](https://github.com/influxdata/telegraf/issues/443): Fix Ping command timeout parameter on Linux.
 - [#662](https://github.com/influxdata/telegraf/pull/667): Change `[tags]` to `[global_tags]` to fix multiple-plugin tags bug.
+- [#642](https://github.com/influxdata/telegraf/issues/642): Riemann output plugin issues.
 
 ## v0.10.2 [2016-02-04]
 
diff --git a/plugins/outputs/riemann/riemann.go b/plugins/outputs/riemann/riemann.go
index 326bb570..d2044139 100644
--- a/plugins/outputs/riemann/riemann.go
+++ b/plugins/outputs/riemann/riemann.go
@@ -4,6 +4,8 @@ import (
 	"errors"
 	"fmt"
 	"os"
+	"sort"
+	"strings"
 
 	"github.com/amir/raidman"
 	"github.com/influxdata/telegraf"
@@ -13,6 +15,7 @@ import (
 type Riemann struct {
 	URL       string
 	Transport string
+	Separator string
 
 	client *raidman.Client
 }
@@ -22,6 +25,8 @@ var sampleConfig = `
   url = "localhost:5555"
   ### transport protocol to use either tcp or udp
   transport = "tcp"
+  ### separator to use between input name and field name in Riemann service name
+  separator = " "
 `
 
 func (r *Riemann) Connect() error {
@@ -55,7 +60,7 @@ func (r *Riemann) Write(metrics []telegraf.Metric) error {
 
 	var events []*raidman.Event
 	for _, p := range metrics {
-		evs := buildEvents(p)
+		evs := buildEvents(p, r.Separator)
 		for _, ev := range evs {
 			events = append(events, ev)
 		}
@@ -70,7 +75,7 @@ func (r *Riemann) Write(metrics []telegraf.Metric) error {
 	return nil
 }
 
-func buildEvents(p telegraf.Metric) []*raidman.Event {
+func buildEvents(p telegraf.Metric, s string) []*raidman.Event {
 	events := []*raidman.Event{}
 	for fieldName, value := range p.Fields() {
 		host, ok := p.Tags()["host"]
@@ -85,15 +90,48 @@ func buildEvents(p telegraf.Metric) []*raidman.Event {
 
 		event := &raidman.Event{
 			Host:    host,
-			Service: p.Name() + "_" + fieldName,
-			Metric:  value,
+			Service: serviceName(s, p.Name(), p.Tags(), fieldName),
 		}
+
+		switch value.(type) {
+		case string:
+			event.State = value.(string)
+		default:
+			event.Metric = value
+		}
+
 		events = append(events, event)
 	}
 
 	return events
 }
 
+func serviceName(s string, n string, t map[string]string, f string) string {
+	serviceStrings := []string{}
+	serviceStrings = append(serviceStrings, n)
+
+	// we'll skip the 'host' tag
+	tagStrings := []string{}
+	tagNames := []string{}
+
+	for tagName := range t {
+		tagNames = append(tagNames, tagName)
+	}
+	sort.Strings(tagNames)
+
+	for _, tagName := range tagNames {
+		if tagName != "host" {
+			tagStrings = append(tagStrings, t[tagName])
+		}
+	}
+	var tagString string = strings.Join(tagStrings, s)
+	if tagString != "" {
+		serviceStrings = append(serviceStrings, tagString)
+	}
+	serviceStrings = append(serviceStrings, f)
+	return strings.Join(serviceStrings, s)
+}
+
 func init() {
 	outputs.Add("riemann", func() telegraf.Output {
 		return &Riemann{}
-- 
GitLab