mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
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:
parent
341bed4822
commit
a8d4224828
4 changed files with 31 additions and 8 deletions
|
@ -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:
|
||||||
|
|
||||||
|
|
|
@ -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:])
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue