app/vminsert/graphite: allow skipping timestamps in Graphite plaintext protocol

In this case VictoriaMetrics uses the ingestion time as a timestamp.
This commit is contained in:
Aliaksandr Valialkin 2019-06-18 19:04:02 +03:00
parent 341bed4822
commit a8d4224828
4 changed files with 31 additions and 8 deletions

View file

@ -264,6 +264,7 @@ Example for writing data with Graphite plaintext protocol to local VictoriaMetri
echo "foo.bar.baz;tag1=value1;tag2=value2 123 `date +%s`" | nc -N localhost 2003 echo "foo.bar.baz;tag1=value1;tag2=value2 123 `date +%s`" | nc -N localhost 2003
``` ```
VictoriaMetrics sets the current time if timestamp is omitted.
Arbitrary number of lines delimited by `\n` may be sent in one go. Arbitrary number of lines delimited by `\n` may be sent in one go.
After that the data may be read via [/api/v1/export](#how-to-export-time-series) endpoint: After that the data may be read via [/api/v1/export](#how-to-export-time-series) endpoint:

View file

@ -86,7 +86,9 @@ func (r *Row) unmarshal(s string, tagsPool []Tag) ([]Tag, error) {
n = strings.IndexByte(tail, ' ') n = strings.IndexByte(tail, ' ')
if n < 0 { if n < 0 {
return tagsPool, fmt.Errorf("cannot find whitespace between value and timestamp in %q", s) // There is no timestamp. Use default timestamp instead.
r.Value = fastfloat.ParseBestEffort(tail)
return tagsPool, nil
} }
r.Value = fastfloat.ParseBestEffort(tail[:n]) r.Value = fastfloat.ParseBestEffort(tail[:n])
r.Timestamp = fastfloat.ParseInt64BestEffort(tail[n+1:]) r.Timestamp = fastfloat.ParseInt64BestEffort(tail[n+1:])

View file

@ -22,9 +22,6 @@ func TestRowsUnmarshalFailure(t *testing.T) {
// Missing value // Missing value
f("aaa") f("aaa")
// Missing timestamp
f("aaa 1123")
// Invalid multiline // Invalid multiline
f("aaa\nbbb 123 34") f("aaa\nbbb 123 34")
@ -81,6 +78,14 @@ func TestRowsUnmarshalSuccess(t *testing.T) {
}}, }},
}) })
// Missing timestamp
f("aaa 1123", &Rows{
Rows: []Row{{
Metric: "aaa",
Value: 1123,
}},
})
// Tags // Tags
f("foo;bar=baz 1 2", &Rows{ f("foo;bar=baz 1 2", &Rows{
Rows: []Row{{ Rows: []Row{{
@ -116,13 +121,17 @@ func TestRowsUnmarshalSuccess(t *testing.T) {
}) })
// Multi lines // Multi lines
f("foo 0.3 2\nbar.baz 0.34 43\n", &Rows{ f("foo 0.3 2\naaa 3\nbar.baz 0.34 43\n", &Rows{
Rows: []Row{ Rows: []Row{
{ {
Metric: "foo", Metric: "foo",
Value: 0.3, Value: 0.3,
Timestamp: 2, Timestamp: 2,
}, },
{
Metric: "aaa",
Value: 3,
},
{ {
Metric: "bar.baz", Metric: "bar.baz",
Value: 0.34, Value: 0.34,

View file

@ -87,10 +87,21 @@ func (ctx *pushCtx) Read(r io.Reader) bool {
return false return false
} }
// Convert timestamps from seconds to milliseconds // Fill missing timestamps with the current timestamp rounded to seconds.
for i := range ctx.Rows.Rows { currentTimestamp := time.Now().Unix()
ctx.Rows.Rows[i].Timestamp *= 1e3 rows := ctx.Rows.Rows
for i := range rows {
r := &rows[i]
if r.Timestamp == 0 {
r.Timestamp = currentTimestamp
}
} }
// Convert timestamps from seconds to milliseconds.
for i := range rows {
rows[i].Timestamp *= 1e3
}
return true return true
} }