lib/protoparser/influx: allow multiple whitespace chars between measurement, fields and timestamp in Influx line protocol

This commit is contained in:
Aliaksandr Valialkin 2020-12-06 11:59:13 +02:00
parent 6f0038209c
commit b0e4b234cb
3 changed files with 43 additions and 2 deletions

View file

@ -2,6 +2,10 @@
# tip # tip
* FEATURE: allow multiple whitespace chars between measurements, fields and timestamp when parsing InfluxDB line protocol.
Though [InfluxDB line protocol](https://docs.influxdata.com/influxdb/v1.8/write_protocols/line_protocol_tutorial/) denies multiple whitespace chars between these entities,
some apps improperly put multiple whitespace chars. This workaround allows accepting data from such apps.
# [v1.49.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.49.0) # [v1.49.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.49.0)

View file

@ -69,7 +69,7 @@ func (r *Row) unmarshal(s string, tagsPool []Tag, fieldsPool []Field, noEscapeCh
return tagsPool, fieldsPool, fmt.Errorf("cannot find Whitespace I in %q", s) return tagsPool, fieldsPool, fmt.Errorf("cannot find Whitespace I in %q", s)
} }
measurementTags := s[:n] measurementTags := s[:n]
s = s[n+1:] s = stripLeadingWhitespace(s[n+1:])
// Parse measurement and tags // Parse measurement and tags
var err error var err error
@ -110,7 +110,7 @@ func (r *Row) unmarshal(s string, tagsPool []Tag, fieldsPool []Field, noEscapeCh
return tagsPool, fieldsPool, err return tagsPool, fieldsPool, err
} }
r.Fields = fieldsPool[fieldsStart:] r.Fields = fieldsPool[fieldsStart:]
s = s[n+1:] s = stripLeadingWhitespace(s[n+1:])
// Parse timestamp // Parse timestamp
timestamp, err := fastfloat.ParseInt64(s) timestamp, err := fastfloat.ParseInt64(s)
@ -409,3 +409,10 @@ func isInQuote(s string, noEscapeChars bool) bool {
s = s[n+1:] s = s[n+1:]
} }
} }
func stripLeadingWhitespace(s string) string {
for len(s) > 0 && s[0] == ' ' {
s = s[1:]
}
return s
}

View file

@ -468,6 +468,36 @@ func TestRowsUnmarshalSuccess(t *testing.T) {
}, },
}) })
// Superfluous whitespace between tags, fields and timestamps.
f(`cpu_utilization,host=mnsbook-pro.local value=119.8 1607222595591`, &Rows{
Rows: []Row{{
Measurement: "cpu_utilization",
Tags: []Tag{{
Key: "host",
Value: "mnsbook-pro.local",
}},
Fields: []Field{{
Key: "value",
Value: 119.8,
}},
Timestamp: 1607222595591,
}},
})
f(`cpu_utilization,host=mnsbook-pro.local value=119.8 1607222595591`, &Rows{
Rows: []Row{{
Measurement: "cpu_utilization",
Tags: []Tag{{
Key: "host",
Value: "mnsbook-pro.local",
}},
Fields: []Field{{
Key: "value",
Value: 119.8,
}},
Timestamp: 1607222595591,
}},
})
f("x,y=z,g=p:\\ \\ 5432\\,\\ gp\\ mon\\ [lol]\\ con10\\ cmd5\\ SELECT f=1", &Rows{ f("x,y=z,g=p:\\ \\ 5432\\,\\ gp\\ mon\\ [lol]\\ con10\\ cmd5\\ SELECT f=1", &Rows{
Rows: []Row{{ Rows: []Row{{
Measurement: "x", Measurement: "x",