Use an 'auto' parser by default for value input format

This commit is contained in:
Cameron Sparr 2016-04-05 18:37:46 -06:00
parent 0f16c0f4cf
commit 416591006b
3 changed files with 90 additions and 4 deletions

View File

@ -150,8 +150,14 @@ as the parsed metric.
#### Value Configuration:
You **must** tell Telegraf what type of metric to collect by using the
`data_type` configuration option.
You **should** tell Telegraf what type of metric to collect by using the
`data_type` configuration option. The options are:
1. integer
1. float
1. string
1. boolean
1. auto (this will try parsing into the above types, in order)
**Note:** It is also recommended that you set `name_override` to a measurement
name that makes sense for your metric, otherwise it will just be set to the
@ -170,7 +176,7 @@ name of the plugin.
## more about them here:
## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_INPUT.md
data_format = "value"
data_type = "integer" # required
data_type = "integer"
```
# Graphite:

View File

@ -26,7 +26,9 @@ func (v *ValueParser) Parse(buf []byte) ([]telegraf.Metric, error) {
var value interface{}
var err error
switch v.DataType {
case "", "int", "integer":
case "", "auto":
value, err = autoParse(valueStr)
case "int", "integer":
value, err = strconv.Atoi(valueStr)
case "float", "long":
value, err = strconv.ParseFloat(valueStr, 64)
@ -49,6 +51,30 @@ func (v *ValueParser) Parse(buf []byte) ([]telegraf.Metric, error) {
return []telegraf.Metric{metric}, nil
}
// autoParse tries to parse the given string into (in order):
// 1. integer
// 2. float
// 3. boolean
// 4. string
func autoParse(valueStr string) (interface{}, error) {
var value interface{}
var err error
// 1st try integer:
if value, err = strconv.Atoi(valueStr); err == nil {
return value, err
}
// 2nd try float:
if value, err = strconv.ParseFloat(valueStr, 64); err == nil {
return value, err
}
// 3rd try boolean:
if value, err = strconv.ParseBool(valueStr); err == nil {
return value, err
}
// 4th, none worked, so string
return valueStr, nil
}
func (v *ValueParser) ParseLine(line string) (telegraf.Metric, error) {
metrics, err := v.Parse([]byte(line))

View File

@ -60,6 +60,60 @@ func TestParseValidValues(t *testing.T) {
assert.Equal(t, map[string]string{}, metrics[0].Tags())
}
func TestParseAutoValues(t *testing.T) {
parser := ValueParser{
MetricName: "value_test",
DataType: "auto",
}
metrics, err := parser.Parse([]byte("55"))
assert.NoError(t, err)
assert.Len(t, metrics, 1)
assert.Equal(t, "value_test", metrics[0].Name())
assert.Equal(t, map[string]interface{}{
"value": int64(55),
}, metrics[0].Fields())
assert.Equal(t, map[string]string{}, metrics[0].Tags())
parser = ValueParser{
MetricName: "value_test",
DataType: "auto",
}
metrics, err = parser.Parse([]byte("64.1"))
assert.NoError(t, err)
assert.Len(t, metrics, 1)
assert.Equal(t, "value_test", metrics[0].Name())
assert.Equal(t, map[string]interface{}{
"value": float64(64.1),
}, metrics[0].Fields())
assert.Equal(t, map[string]string{}, metrics[0].Tags())
parser = ValueParser{
MetricName: "value_test",
DataType: "auto",
}
metrics, err = parser.Parse([]byte("foobar"))
assert.NoError(t, err)
assert.Len(t, metrics, 1)
assert.Equal(t, "value_test", metrics[0].Name())
assert.Equal(t, map[string]interface{}{
"value": "foobar",
}, metrics[0].Fields())
assert.Equal(t, map[string]string{}, metrics[0].Tags())
parser = ValueParser{
MetricName: "value_test",
DataType: "auto",
}
metrics, err = parser.Parse([]byte("true"))
assert.NoError(t, err)
assert.Len(t, metrics, 1)
assert.Equal(t, "value_test", metrics[0].Name())
assert.Equal(t, map[string]interface{}{
"value": true,
}, metrics[0].Fields())
assert.Equal(t, map[string]string{}, metrics[0].Tags())
}
func TestParseMultipleValues(t *testing.T) {
parser := ValueParser{
MetricName: "value_test",