Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions metricbeat/module/graphite/server/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,12 @@
parts := strings.Fields(metric)
currentTime := common.Time(time.Now())
if len(parts) < 2 {
return "", currentTime, 0, errors.New("Message not in expected format")

Check failure on line 122 in metricbeat/module/graphite/server/data.go

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest)

ST1005: error strings should not be capitalized (staticcheck)
} else {
metricName = parts[0]
val, err := strconv.ParseFloat(parts[1], 64)
if err != nil {
return "", currentTime, 0, errors.New("Unable to parse metric value")

Check failure on line 127 in metricbeat/module/graphite/server/data.go

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest)

ST1005: error strings should not be capitalized (staticcheck)
} else {
value = val
}
Expand All @@ -132,11 +132,11 @@

if len(parts) == 3 {
if parts[2] == "N" {
timestamp = currentTime

Check failure on line 135 in metricbeat/module/graphite/server/data.go

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest)

ineffectual assignment to timestamp (ineffassign)
}
ts, err := strconv.ParseFloat(parts[2], 64)
if err != nil {
return "", currentTime, 0, errors.New("Unable to parse timestamp")

Check failure on line 139 in metricbeat/module/graphite/server/data.go

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest)

ST1005: error strings should not be capitalized (staticcheck)
}

if ts != -1 {
Expand All @@ -162,6 +162,10 @@

tagsMap := make(map[string][]string)
for i := 0; i < len(t.Parts); i++ {
// Avoid out-of-bounds access when metric has fewer parts than template.
if i >= len(parts) {
break
}
if t.Parts[i] == "metric" {
metric = append(metric, parts[i])
} else if t.Parts[i] == "metric*" {
Expand Down
124 changes: 123 additions & 1 deletion metricbeat/module/graphite/server/data_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/elastic/beats/v7/libbeat/common"
"github.com/elastic/elastic-agent-libs/mapstr"
Expand Down Expand Up @@ -79,7 +80,6 @@ func TestMetricProcessorDeleteTemplate(t *testing.T) {
processor.RemoveTemplate(temp)
out := processor.templates.Search([]string{"a", "b", "c"})
assert.Nil(t, out)

}

func TestMetricProcessorProcess(t *testing.T) {
Expand Down Expand Up @@ -108,3 +108,125 @@ func TestMetricProcessorProcess(t *testing.T) {
assert.NotNil(t, event["stats"])
assert.Equal(t, event["stats"], float64(42))
}

func TestTemplateApply(t *testing.T) {
tests := []struct {
name string
tmpl template
parts []string
wantMetric string
wantTagsCount int
}{
{
name: "metric shorter than template",
tmpl: template{
Delimiter: ".",
Parts: []string{"", "host", "region", "service", "metric"},
},
parts: []string{"server1", "us-east"},
wantMetric: "",
wantTagsCount: 1,
},
{
name: "single part metric",
tmpl: template{
Delimiter: ".",
Parts: []string{"", "host", "region", "service", "metric"},
},
parts: []string{"server1"},
wantMetric: "",
wantTagsCount: 0,
},
{
name: "empty metric parts",
tmpl: template{
Delimiter: ".",
Parts: []string{"", "host", "region", "service", "metric"},
},
parts: []string{},
wantMetric: "",
wantTagsCount: 0,
},
{
name: "nil metric parts",
tmpl: template{
Delimiter: ".",
Parts: []string{"", "host", "region", "service", "metric"},
},
parts: nil,
wantMetric: "",
wantTagsCount: 0,
},
{
name: "metric star captures remaining from current index",
tmpl: template{
Delimiter: "_",
Parts: []string{"", "host", "metric*"},
},
parts: []string{"server1", "cpu", "idle", "percent"},
wantMetric: "idle_percent",
wantTagsCount: 1,
},
{
name: "empty template parts",
tmpl: template{
Delimiter: ".",
Parts: []string{},
},
parts: []string{"server1", "us-east"},
wantMetric: "",
wantTagsCount: 0,
},
{
name: "template with predefined tags",
tmpl: template{
Delimiter: ".",
Parts: []string{"metric"},
Tags: map[string]string{"env": "prod", "dc": "us-east"},
},
parts: []string{"cpu"},
wantMetric: "cpu",
wantTagsCount: 2,
},
{
name: "duplicate tag keys in template are combined",
tmpl: template{
Delimiter: "_",
Parts: []string{"host", "host", "metric"},
},
parts: []string{"server1", "server2", "cpu"},
wantMetric: "cpu",
wantTagsCount: 1,
},
{
name: "all parts are metric",
tmpl: template{
Delimiter: ".",
Parts: []string{"metric", "metric", "metric"},
},
parts: []string{"cpu", "idle", "percent"},
wantMetric: "cpu.idle.percent",
wantTagsCount: 0,
},
{
name: "metric star at beginning",
tmpl: template{
Delimiter: "_",
Parts: []string{"metric*"},
},
parts: []string{"cpu", "idle", "percent"},
wantMetric: "cpu_idle_percent",
wantTagsCount: 0,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
require.NotPanics(t, func() {
metric, tags := tt.tmpl.Apply(tt.parts)
assert.Equal(t, tt.wantMetric, metric)
assert.Len(t, tags, tt.wantTagsCount)
})
})
}
}
Loading