Skip to content

Commit

Permalink
Agent ingests graphite plaintext metric tags (#4897)
Browse files Browse the repository at this point in the history
Graphite has support for storing data in tags to identify series of
metrics. This change introduces support for this feature in the graphite
text protocol. Presently the agent ingests
`my.series;tag1=value1 1 999999999` as a metric point with name
"my.series;tag1=value1". Per the graphite spec this will now be ingested
as a metric point with name "my.series" and a tag for ("tag1": "value1")

Signed-off-by: Christian Kruse <[email protected]>

reframe changelog as a feature add

Signed-off-by: Christian Kruse <[email protected]>

Signed-off-by: Christian Kruse <[email protected]>
  • Loading branch information
c-kruse authored Oct 25, 2022
1 parent 5f672b7 commit 97ecc7e
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 2 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG-6.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic
Versioning](http://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added
- Include support for handling metric tags in the graphite plaintext
protocol. Agents now respect the new graphite tag specification.

## [6.8.2] - 2022-10-06

### Changed
Expand Down
28 changes: 26 additions & 2 deletions agent/transformers/graphite.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package transformers

import (
"bufio"
"fmt"
"strconv"
"strings"

Expand Down Expand Up @@ -64,7 +65,13 @@ func ParseGraphite(event *types.Event) GraphiteList {
continue
}

g.Path = args[0]
var err error
var tags []*types.MetricTag
g.Path, tags, err = parseSeries(args[0])
if err != nil {
logger.WithFields(fields).WithError(ErrMetricExtraction).Errorf("metric series name is invalid: %q %s", args[0], err)
continue
}

f, err := strconv.ParseFloat(args[1], 64)
if err != nil {
Expand All @@ -79,7 +86,7 @@ func ParseGraphite(event *types.Event) GraphiteList {
continue
}
g.Timestamp = i
g.Tags = event.Check.OutputMetricTags
g.Tags = append(event.Check.OutputMetricTags, tags...)
graphiteList = append(graphiteList, g)
}
if err := s.Err(); err != nil {
Expand All @@ -88,3 +95,20 @@ func ParseGraphite(event *types.Event) GraphiteList {

return graphiteList
}

func parseSeries(series string) (string, []*types.MetricTag, error) {
var tags []*types.MetricTag
parts := strings.Split(series, ";")
if len(parts) == 1 {
return series, tags, nil
}
for i := 1; i < len(parts); i++ {
tagTxt := parts[i]
tagParts := strings.Split(tagTxt, "=")
if len(tagParts) != 2 {
return parts[0], tags, fmt.Errorf("invalid graphite data tag format must be in form of name=value: %s", tagTxt)
}
tags = append(tags, &types.MetricTag{Name: tagParts[0], Value: tagParts[1]})
}
return parts[0], tags, nil
}
14 changes: 14 additions & 0 deletions agent/transformers/graphite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,20 @@ func TestParseGraphite(t *testing.T) {
metric: "metric.value 1 noon",
expectedFormat: GraphiteList(nil),
},
{
metric: "os.disk.used_bytes;GH=#4677;type=issue 2048 123456789",
expectedFormat: GraphiteList{
{
Path: "os.disk.used_bytes",
Value: 2048,
Timestamp: 123456789,
Tags: []*types.MetricTag{
{Name: "GH", Value: "#4677"},
{Name: "type", Value: "issue"},
},
},
},
},
}

for _, tc := range testCases {
Expand Down

0 comments on commit 97ecc7e

Please sign in to comment.