Allow grok to produce metrics with no fields (#5533)
This commit is contained in:
parent
1dcfecdb59
commit
a0527db037
|
@ -11,10 +11,9 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/vjeantet/grok"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/metric"
|
||||
"github.com/vjeantet/grok"
|
||||
)
|
||||
|
||||
var timeLayouts = map[string]string{
|
||||
|
@ -361,10 +360,6 @@ func (p *Parser) ParseLine(line string) (telegraf.Metric, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if len(fields) == 0 {
|
||||
return nil, fmt.Errorf("grok: must have one or more fields")
|
||||
}
|
||||
|
||||
if p.UniqueTimestamp != "auto" {
|
||||
return metric.New(p.Measurement, tags, fields, timestamp)
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
@ -571,61 +572,81 @@ func TestCompileErrors(t *testing.T) {
|
|||
assert.Error(t, p.Compile())
|
||||
}
|
||||
|
||||
func TestParseErrors(t *testing.T) {
|
||||
// Parse fails because the pattern doesn't exist
|
||||
func TestParseErrors_MissingPattern(t *testing.T) {
|
||||
p := &Parser{
|
||||
Measurement: "grok",
|
||||
Patterns: []string{"%{TEST_LOG_B}"},
|
||||
CustomPatterns: `
|
||||
TEST_LOG_A %{HTTPDATE:ts:ts-httpd} %{WORD:myword:int} %{}
|
||||
`,
|
||||
}
|
||||
assert.Error(t, p.Compile())
|
||||
require.Error(t, p.Compile())
|
||||
_, err := p.ParseLine(`[04/Jun/2016:12:41:45 +0100] notnumber 200 192.168.1.1 5.432µs 101`)
|
||||
assert.Error(t, err)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
// Parse fails because myword is not an int
|
||||
p = &Parser{
|
||||
func TestParseErrors_WrongIntegerType(t *testing.T) {
|
||||
p := &Parser{
|
||||
Measurement: "grok",
|
||||
Patterns: []string{"%{TEST_LOG_A}"},
|
||||
CustomPatterns: `
|
||||
TEST_LOG_A %{HTTPDATE:ts:ts-httpd} %{WORD:myword:int}
|
||||
TEST_LOG_A %{NUMBER:ts:ts-epoch} %{WORD:myword:int}
|
||||
`,
|
||||
}
|
||||
assert.NoError(t, p.Compile())
|
||||
_, err = p.ParseLine(`04/Jun/2016:12:41:45 +0100 notnumber`)
|
||||
assert.Error(t, err)
|
||||
require.NoError(t, p.Compile())
|
||||
m, err := p.ParseLine(`0 notnumber`)
|
||||
require.NoError(t, err)
|
||||
testutil.RequireMetricEqual(t,
|
||||
m,
|
||||
testutil.MustMetric("grok", map[string]string{}, map[string]interface{}{}, time.Unix(0, 0)))
|
||||
}
|
||||
|
||||
// Parse fails because myword is not a float
|
||||
p = &Parser{
|
||||
func TestParseErrors_WrongFloatType(t *testing.T) {
|
||||
p := &Parser{
|
||||
Measurement: "grok",
|
||||
Patterns: []string{"%{TEST_LOG_A}"},
|
||||
CustomPatterns: `
|
||||
TEST_LOG_A %{HTTPDATE:ts:ts-httpd} %{WORD:myword:float}
|
||||
TEST_LOG_A %{NUMBER:ts:ts-epoch} %{WORD:myword:float}
|
||||
`,
|
||||
}
|
||||
assert.NoError(t, p.Compile())
|
||||
_, err = p.ParseLine(`04/Jun/2016:12:41:45 +0100 notnumber`)
|
||||
assert.Error(t, err)
|
||||
require.NoError(t, p.Compile())
|
||||
m, err := p.ParseLine(`0 notnumber`)
|
||||
require.NoError(t, err)
|
||||
testutil.RequireMetricEqual(t,
|
||||
m,
|
||||
testutil.MustMetric("grok", map[string]string{}, map[string]interface{}{}, time.Unix(0, 0)))
|
||||
}
|
||||
|
||||
// Parse fails because myword is not a duration
|
||||
p = &Parser{
|
||||
func TestParseErrors_WrongDurationType(t *testing.T) {
|
||||
p := &Parser{
|
||||
Measurement: "grok",
|
||||
Patterns: []string{"%{TEST_LOG_A}"},
|
||||
CustomPatterns: `
|
||||
TEST_LOG_A %{HTTPDATE:ts:ts-httpd} %{WORD:myword:duration}
|
||||
TEST_LOG_A %{NUMBER:ts:ts-epoch} %{WORD:myword:duration}
|
||||
`,
|
||||
}
|
||||
assert.NoError(t, p.Compile())
|
||||
_, err = p.ParseLine(`04/Jun/2016:12:41:45 +0100 notnumber`)
|
||||
assert.Error(t, err)
|
||||
require.NoError(t, p.Compile())
|
||||
m, err := p.ParseLine(`0 notnumber`)
|
||||
require.NoError(t, err)
|
||||
testutil.RequireMetricEqual(t,
|
||||
m,
|
||||
testutil.MustMetric("grok", map[string]string{}, map[string]interface{}{}, time.Unix(0, 0)))
|
||||
}
|
||||
|
||||
// Parse fails because the time layout is wrong.
|
||||
p = &Parser{
|
||||
func TestParseErrors_WrongTimeLayout(t *testing.T) {
|
||||
p := &Parser{
|
||||
Measurement: "grok",
|
||||
Patterns: []string{"%{TEST_LOG_A}"},
|
||||
CustomPatterns: `
|
||||
TEST_LOG_A %{HTTPDATE:ts:ts-unix} %{WORD:myword:duration}
|
||||
TEST_LOG_A %{NUMBER:ts:ts-epoch} %{WORD:myword:duration}
|
||||
`,
|
||||
}
|
||||
assert.NoError(t, p.Compile())
|
||||
_, err = p.ParseLine(`04/Jun/2016:12:41:45 +0100 notnumber`)
|
||||
assert.Error(t, err)
|
||||
require.NoError(t, p.Compile())
|
||||
m, err := p.ParseLine(`0 notnumber`)
|
||||
require.NoError(t, err)
|
||||
testutil.RequireMetricEqual(t,
|
||||
m,
|
||||
testutil.MustMetric("grok", map[string]string{}, map[string]interface{}{}, time.Unix(0, 0)))
|
||||
}
|
||||
|
||||
func TestTsModder(t *testing.T) {
|
||||
|
|
|
@ -298,7 +298,6 @@ func newJSONParser(
|
|||
return parser
|
||||
}
|
||||
|
||||
//Deprecated: Use NewParser to get a JSONParser object
|
||||
func newGrokParser(metricName string,
|
||||
patterns []string, nPatterns []string,
|
||||
cPatterns string, cPatternFiles []string,
|
||||
|
|
Loading…
Reference in New Issue