Skip to content

Commit

Permalink
Add public function to graphite parser to apply template
Browse files Browse the repository at this point in the history
  • Loading branch information
sparrc committed Oct 6, 2015
1 parent 897a5ef commit 883d32c
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 3 deletions.
21 changes: 18 additions & 3 deletions services/graphite/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ func NewParserWithOptions(options Options) (*Parser, error) {
filter := ""
// Format is [filter] <template> [tag1=value1,tag2=value2]
parts := strings.Fields(pattern)
if len(parts) >= 2 {
if len(parts) < 1 {
continue
} else if len(parts) >= 2 {
if strings.Contains(parts[1], "=") {
template = parts[0]
} else {
Expand Down Expand Up @@ -97,8 +99,8 @@ func (p *Parser) Parse(line string) (models.Point, error) {
}

// decode the name and tags
matcher := p.matcher.Match(fields[0])
measurement, tags := matcher.Apply(fields[0])
template := p.matcher.Match(fields[0])
measurement, tags := template.Apply(fields[0])

// Could not extract measurement, use the raw value
if measurement == "" {
Expand Down Expand Up @@ -145,6 +147,19 @@ func (p *Parser) Parse(line string) (models.Point, error) {
return point, nil
}

// Apply extracts the template fields form the given line and returns the
// measurement name and tags
func (p *Parser) ApplyTemplate(line string) (string, map[string]string) {
// Break line into fields (name, value, timestamp), only name is used
fields := strings.Fields(line)
if len(fields) == 0 {
return "", make(map[string]string)
}
// decode the name and tags
template := p.matcher.Match(fields[0])
return template.Apply(fields[0])
}

// template represents a pattern and tags to map a graphite metric string to a influxdb Point
type template struct {
tags []string
Expand Down
89 changes: 89 additions & 0 deletions services/graphite/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -546,3 +546,92 @@ func TestParseTemplateWhitespace(t *testing.T) {
t.Errorf("parse mismatch: got %v, exp %v", pt.String(), exp.String())
}
}

// Test basic functionality of ApplyTemplate
func TestApplyTemplate(t *testing.T) {
o := graphite.Options{
Separator: "_",
Templates: []string{"current.* measurement.measurement"},
}
p, err := graphite.NewParserWithOptions(o)
if err != nil {
t.Fatalf("unexpected error creating parser, got %v", err)
}

measurement, _ := p.ApplyTemplate("current.users")
if measurement != "current_users" {
t.Errorf("Parser.ApplyTemplate unexpected result. got %s, exp %s",
measurement, "current_users")
}
}

// Test basic functionality of ApplyTemplate
func TestApplyTemplateNoMatch(t *testing.T) {
o := graphite.Options{
Separator: "_",
Templates: []string{"foo.bar measurement.measurement"},
}
p, err := graphite.NewParserWithOptions(o)
if err != nil {
t.Fatalf("unexpected error creating parser, got %v", err)
}

measurement, _ := p.ApplyTemplate("current.users")
if measurement != "current.users" {
t.Errorf("Parser.ApplyTemplate unexpected result. got %s, exp %s",
measurement, "current.users")
}
}

// Test that most specific template is chosen
func TestApplyTemplateSpecific(t *testing.T) {
o := graphite.Options{
Separator: "_",
Templates: []string{
"current.* measurement.measurement",
"current.*.* measurement.measurement.service",
},
}
p, err := graphite.NewParserWithOptions(o)
if err != nil {
t.Fatalf("unexpected error creating parser, got %v", err)
}

measurement, tags := p.ApplyTemplate("current.users.facebook")
if measurement != "current_users" {
t.Errorf("Parser.ApplyTemplate unexpected result. got %s, exp %s",
measurement, "current_users")
}
service, ok := tags["service"]
if !ok {
t.Error("Expected for template to apply a 'service' tag, but not found")
}
if service != "facebook" {
t.Errorf("Expected service='facebook' tag, got service='%s'", service)
}
}

func TestApplyTemplateTags(t *testing.T) {
o := graphite.Options{
Separator: "_",
Templates: []string{"current.* measurement.measurement region=us-west"},
}
p, err := graphite.NewParserWithOptions(o)
if err != nil {
t.Fatalf("unexpected error creating parser, got %v", err)
}

measurement, tags := p.ApplyTemplate("current.users")
if measurement != "current_users" {
t.Errorf("Parser.ApplyTemplate unexpected result. got %s, exp %s",
measurement, "current_users")
}

region, ok := tags["region"]
if !ok {
t.Error("Expected for template to apply a 'region' tag, but not found")
}
if region != "us-west" {
t.Errorf("Expected region='us-west' tag, got region='%s'", region)
}
}

0 comments on commit 883d32c

Please sign in to comment.