adds tab as second separator for graphite text protocol (#1733)

* adds tab as second separator for graphite text protocol

* changes indexFunc for indexAny

* Update lib/protoparser/graphite/parser_test.go

Co-authored-by: Aliaksandr Valialkin <valyala@victoriametrics.com>
This commit is contained in:
Nikolay 2021-10-22 12:23:45 +03:00 committed by Aliaksandr Valialkin
parent 3ccc37a98b
commit 83e1dfccba
No known key found for this signature in database
GPG key ID: A72BEC6CD3D0DED1
2 changed files with 38 additions and 4 deletions

View file

@ -9,6 +9,10 @@ import (
"github.com/valyala/fastjson/fastfloat" "github.com/valyala/fastjson/fastfloat"
) )
// graphite text line protocol may use white space or tab as separator
// See https://github.com/grobian/carbon-c-relay/commit/f3ffe6cc2b52b07d14acbda649ad3fd6babdd528
const graphiteSeparators = " \t"
// Rows contains parsed graphite rows. // Rows contains parsed graphite rows.
type Rows struct { type Rows struct {
Rows []Row Rows []Row
@ -84,9 +88,9 @@ func (r *Row) UnmarshalMetricAndTags(s string, tagsPool []Tag) ([]Tag, error) {
func (r *Row) unmarshal(s string, tagsPool []Tag) ([]Tag, error) { func (r *Row) unmarshal(s string, tagsPool []Tag) ([]Tag, error) {
r.reset() r.reset()
n := strings.IndexByte(s, ' ') n := strings.IndexAny(s, graphiteSeparators)
if n < 0 { if n < 0 {
return tagsPool, fmt.Errorf("cannot find whitespace between metric and value in %q", s) return tagsPool, fmt.Errorf("cannot find separator between metric and value in %q", s)
} }
metricAndTags := s[:n] metricAndTags := s[:n]
tail := s[n+1:] tail := s[n+1:]
@ -96,7 +100,7 @@ func (r *Row) unmarshal(s string, tagsPool []Tag) ([]Tag, error) {
return tagsPool, err return tagsPool, err
} }
n = strings.IndexByte(tail, ' ') n = strings.IndexAny(tail, graphiteSeparators)
if n < 0 { if n < 0 {
// There is no timestamp. Use default timestamp instead. // There is no timestamp. Use default timestamp instead.
v, err := fastfloat.Parse(tail) v, err := fastfloat.Parse(tail)

View file

@ -1,10 +1,11 @@
package graphite package graphite
import ( import (
"github.com/VictoriaMetrics/VictoriaMetrics/lib/fasttime"
"reflect" "reflect"
"strings" "strings"
"testing" "testing"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/fasttime"
) )
func TestUnmarshalMetricAndTagsFailure(t *testing.T) { func TestUnmarshalMetricAndTagsFailure(t *testing.T) {
@ -258,6 +259,35 @@ func TestRowsUnmarshalSuccess(t *testing.T) {
}, },
}, },
}) })
// With tab as separator
// See https://github.com/grobian/carbon-c-relay/commit/f3ffe6cc2b52b07d14acbda649ad3fd6babdd528
f("foo.baz\t125.456\t1789\n", &Rows{
Rows: []Row{{
Metric: "foo.baz",
Value: 125.456,
Timestamp: 1789,
}},
})
// With tab as separator and tags
f("foo;baz=bar;bb=;y=x;=z\t1\t2", &Rows{
Rows: []Row{{
Metric: "foo",
Tags: []Tag{
{
Key: "baz",
Value: "bar",
},
{
Key: "y",
Value: "x",
},
},
Value: 1,
Timestamp: 2,
}},
})
} }
func Test_streamContext_Read(t *testing.T) { func Test_streamContext_Read(t *testing.T) {