Add plugin Warp10

This commit is contained in:
Aurélien Hébert 2016-10-21 10:36:19 +02:00
parent 91f48e7ad5
commit 435ece6787
6 changed files with 228 additions and 0 deletions

View File

@ -60,6 +60,7 @@ docker-run:
docker run --name mqtt -p "1883:1883" -d ncarlier/mqtt
docker run --name riemann -p "5555:5555" -d blalor/riemann
docker run --name nats -p "4222:4222" -d nats
docker run --name warp10 -p "8090:8080" -p "8091:8081" -d -i warp10io/warp10:1.0.16-ci
# Run docker containers necessary for CircleCI unit tests
docker-run-circle:
@ -73,6 +74,7 @@ docker-run-circle:
docker run --name mqtt -p "1883:1883" -d ncarlier/mqtt
docker run --name riemann -p "5555:5555" -d blalor/riemann
docker run --name nats -p "4222:4222" -d nats
docker run --name warp10 -p "8090:8080" -p "8091:8081" -d -i waxzce/warp10forci:latest
# Kill all docker containers, ignore errors
docker-kill:

View File

@ -253,6 +253,7 @@ want to add support for another service or third-party API.
* [opentsdb](https://github.com/influxdata/telegraf/tree/master/plugins/outputs/opentsdb)
* [prometheus](https://github.com/influxdata/telegraf/tree/master/plugins/outputs/prometheus_client)
* [riemann](https://github.com/influxdata/telegraf/tree/master/plugins/outputs/riemann)
* [warp10](https://github.com/influxdata/telegraf/tree/master/plugins/outputs/warp10)
## Contributing

View File

@ -19,4 +19,5 @@ import (
_ "github.com/influxdata/telegraf/plugins/outputs/opentsdb"
_ "github.com/influxdata/telegraf/plugins/outputs/prometheus_client"
_ "github.com/influxdata/telegraf/plugins/outputs/riemann"
_ "github.com/influxdata/telegraf/plugins/outputs/warp10"
)

View File

@ -0,0 +1,23 @@
# README #
Telegraph plugin to push metrics on Warp10
### Telegraph output for Warp10 ###
Execute a post http on Warp10 at every flush time configured in telegraph in order to push the metrics collected
### Config ###
Add following instruction in the config file (Output part)
```
[[outputs.warp10]]
warpUrl = "http://localhost:4242"
token = "token"
prefix = "telegraf."
debug = false
```
### Contact ###
* contact@cityzendata.com

View File

@ -0,0 +1,179 @@
package warp10
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"sort"
"strconv"
"strings"
"time"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/plugins/outputs"
)
type Warp10 struct {
Prefix string
WarpUrl string
Token string
Debug bool
}
var sampleConfig = `
# prefix for metrics class Name
prefix = "Prefix"
## POST HTTP(or HTTPS) ##
# Url name of the Warp 10 server
warp_url = "WarpUrl"
# Token to access your app on warp 10
token = "Token"
# Debug true - Prints Warp communication
debug = false
`
type MetricLine struct {
Metric string
Timestamp int64
Value string
Tags string
}
func (o *Warp10) Connect() error {
return nil
}
func (o *Warp10) Write(metrics []telegraf.Metric) error {
var out io.Writer = ioutil.Discard
if o.Debug {
out = os.Stdout
}
if len(metrics) == 0 {
return nil
}
var now = time.Now()
collectString := make([]string, 0)
index := 0
for _, mm := range metrics {
for k, v := range mm.Fields() {
metric := &MetricLine{
Metric: fmt.Sprintf("%s%s", o.Prefix, mm.Name()+"."+k),
Timestamp: now.Unix() * 1000000,
}
metricValue, err := buildValue(v)
if err != nil {
log.Printf("Warp: %s\n", err.Error())
continue
}
metric.Value = metricValue
tagsSlice := buildTags(mm.Tags())
metric.Tags = strings.Join(tagsSlice, ",")
messageLine := fmt.Sprintf("%d// %s{%s} %s\n", metric.Timestamp, metric.Metric, metric.Tags, metric.Value)
collectString = append(collectString, messageLine)
index += 1
}
}
payload := fmt.Sprint(strings.Join(collectString, "\n"))
//defer connection.Close()
req, err := http.NewRequest("POST", o.WarpUrl, bytes.NewBufferString(payload))
req.Header.Set("X-Warp10-Token", o.Token)
req.Header.Set("Content-Type", "text/plain")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Fprintf(out, "response Status: %#v", resp.Status)
fmt.Fprintf(out, "response Headers: %#v", resp.Header)
body, _ := ioutil.ReadAll(resp.Body)
fmt.Fprintf(out, "response Body: %#v", string(body))
return nil
}
func buildTags(ptTags map[string]string) []string {
sizeTags := len(ptTags)
sizeTags += 1
tags := make([]string, sizeTags)
index := 0
for k, v := range ptTags {
tags[index] = fmt.Sprintf("%s=%s", k, v)
index += 1
}
tags[index] = fmt.Sprintf("source=telegraf")
sort.Strings(tags)
return tags
}
func buildValue(v interface{}) (string, error) {
var retv string
switch p := v.(type) {
case int64:
retv = IntToString(int64(p))
case string:
retv = fmt.Sprintf("'%s'", p)
case bool:
retv = BoolToString(bool(p))
case uint64:
retv = UIntToString(uint64(p))
case float64:
retv = FloatToString(float64(p))
default:
retv = fmt.Sprintf("'%s'", p)
// return retv, fmt.Errorf("unexpected type %T with value %v for Warp", v, v)
}
return retv, nil
}
func IntToString(input_num int64) string {
return strconv.FormatInt(input_num, 10)
}
func BoolToString(input_bool bool) string {
return strconv.FormatBool(input_bool)
}
func UIntToString(input_num uint64) string {
return strconv.FormatUint(input_num, 10)
}
func FloatToString(input_num float64) string {
return strconv.FormatFloat(input_num, 'f', 6, 64)
}
func (o *Warp10) SampleConfig() string {
return sampleConfig
}
func (o *Warp10) Description() string {
return "Configuration for Warp server to send metrics to"
}
func (o *Warp10) Close() error {
// Basically nothing to do for Warp10 here
return nil
}
func init() {
outputs.Add("warp10", func() telegraf.Output {
return &Warp10{}
})
}

View File

@ -0,0 +1,22 @@
package warp10
import (
"testing"
"github.com/influxdata/telegraf/testutil"
"github.com/stretchr/testify/require"
)
func TestWriteWarp10(t *testing.T) {
w := Warp10{
Prefix: "unit.test",
WarpUrl: "http://localhost:8090",
Token: "WRITE",
Debug: false,
}
//err := i.Connect()
//require.NoError(t, err)
err := w.Write(testutil.MockMetrics())
require.NoError(t, err)
}