...
 
Commits (4)
# Golang CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-go/ for more details
version: 2
jobs:
build:
docker:
- image: circleci/golang:1.10-stretch
working_directory: /go/src/github.com/DCSO/fluxline
steps:
- checkout
- run: go get -v -t -d ./...
- run: go test -v ./...
# fluxline
# fluxline [![CircleCI](https://circleci.com/gh/DCSO/fluxline.svg?style=shield)](https://circleci.com/gh/DCSO/fluxline) [![Documentation](https://godoc.org/github.com/DCSO/fluxline?status.svg)](http://godoc.org/github.com/DCSO/fluxline)
Encoder for Golang to prepare sets of metrics in [InfluxDB's Line Protocol](https://docs.influxdata.com/influxdb/v1.4/write_protocols/line_protocol_reference) format. As input, we use structs annotated with the `influx` tag, similar to how `encoding/json` works.
......
golang-github-dcso-fluxline (0.0~git20181026.4f8ed83-1) unstable; urgency=medium
* New upstream snapshot.
* Bump Standards-Version.
-- Sascha Steinbiss <satta@debian.org> Mon, 26 Nov 2018 20:39:19 +0100
golang-github-dcso-fluxline (0.0~git20180222.25ae683-1) unstable; urgency=medium
* Initial release (Closes: #891137)
......
......@@ -7,7 +7,7 @@ Build-Depends: debhelper (>= 11),
dh-golang,
golang-any,
golang-github-showmax-go-fqdn-dev
Standards-Version: 4.1.3
Standards-Version: 4.2.1
Homepage: https://github.com/DCSO/fluxline
Vcs-Browser: https://salsa.debian.org/go-team/packages/golang-github-dcso-fluxline
Vcs-Git: https://salsa.debian.org/go-team/packages/golang-github-dcso-fluxline.git
......
......@@ -28,16 +28,17 @@ func escapeSpecialChars(in string) string {
return str
}
func toInfluxRepr(tag string, val interface{}) (string, error) {
func toInfluxRepr(tag string, val interface{}, nostatictypes bool) (string, error) {
switch v := val.(type) {
case string:
if len(v) > 64000 {
return "", fmt.Errorf("%s: string too long (%d characters, max. 64K)", tag, len(v))
}
return fmt.Sprintf("%q", v), nil
case int32, int64, int16, int8, int:
return fmt.Sprintf("%di", v), nil
case uint32, uint64, uint16, uint8, uint:
case int32, int64, int16, int8, int, uint32, uint64, uint16, uint8, uint:
if nostatictypes {
return fmt.Sprintf("%d", v), nil
}
return fmt.Sprintf("%di", v), nil
case float64, float32:
return fmt.Sprintf("%g", v), nil
......@@ -51,7 +52,7 @@ func toInfluxRepr(tag string, val interface{}) (string, error) {
}
func recordFields(val interface{},
fieldSet map[string]string) (map[string]string, error) {
fieldSet map[string]string, nostatictypes bool) (map[string]string, error) {
t := reflect.TypeOf(val)
v := reflect.ValueOf(val)
......@@ -61,7 +62,7 @@ func recordFields(val interface{},
if tag == "" {
continue
}
repr, err := toInfluxRepr(tag, v.Field(i).Interface())
repr, err := toInfluxRepr(tag, v.Field(i).Interface(), nostatictypes)
if err != nil {
return nil, err
}
......@@ -116,10 +117,10 @@ func (a *Encoder) formatLineProtocol(prefix string,
// Encode writes the line protocol representation for a given measurement
// name, data struct and tag map to the io.Writer specified on encoder creation.
func (a *Encoder) Encode(prefix string, val interface{},
tags map[string]string) error {
func (a *Encoder) encodeGeneric(prefix string, val interface{},
tags map[string]string, nostatictypes bool) error {
fieldSet := make(map[string]string)
fieldSet, err := recordFields(val, fieldSet)
fieldSet, err := recordFields(val, fieldSet, nostatictypes)
if err != nil {
return err
}
......@@ -127,6 +128,21 @@ func (a *Encoder) Encode(prefix string, val interface{},
return err
}
// Encode writes the line protocol representation for a given measurement
// name, data struct and tag map to the io.Writer specified on encoder creation.
func (a *Encoder) Encode(prefix string, val interface{},
tags map[string]string) error {
return a.encodeGeneric(prefix, val, tags, false)
}
// EncodeWithoutTypes writes the line protocol representation for a given measurement
// name, data struct and tag map to the io.Writer specified on encoder creation.
// In contrast to Encode(), this method never appends type suffixes to values.
func (a *Encoder) EncodeWithoutTypes(prefix string, val interface{},
tags map[string]string) error {
return a.encodeGeneric(prefix, val, tags, true)
}
// EncodeMap writes the line protocol representation for a given measurement
// name, field value map and tag map to the io.Writer specified on encoder
// creation.
......
......@@ -102,6 +102,22 @@ func TestEncoderTypeFail(t *testing.T) {
}
}
func TestEncoderNoTypes(t *testing.T) {
var b bytes.Buffer
ile := NewEncoder(&b)
tags := make(map[string]string)
err := ile.EncodeWithoutTypes("mytool", testStruct, tags)
if err != nil {
t.Fatal(err)
}
out := b.String()
if match, _ := regexp.Match(`^mytool,host=[^,]+ testval=1,testvalue=2,testvalue2=-3,testvalue3=\"foobar\\\"baz\",testvaluebool=false,testvalueflt32=3.1415927,testvalueflt64=1.29e-24,testvaluetime=`, []byte(out)); !match {
t.Fatalf("unexpected match content: %s", out)
}
}
func TestEncoderStringTooLongFail(t *testing.T) {
var b bytes.Buffer
......