Modify ShouldPass so that it checks the tags of a metric, if configured.

A plugin can have 'tagpass' and 'tagdrop' subsections:

[disk.tagpass]

And tagname = array lists of things to filter by:

fstype = [ "ext4", "xfs" ]
path = [ "/", /opt", "/home" ]

[disk.tagdrop]
path = [ "/" ]
This commit is contained in:
Simon Fraser 2015-08-10 20:41:20 +01:00 committed by Cameron Sparr
parent cd5c85a245
commit 29e8ce68e4
1 changed files with 93 additions and 5 deletions

View File

@ -43,6 +43,10 @@ type Config struct {
func (c *Config) Plugins() map[string]*ast.Table { func (c *Config) Plugins() map[string]*ast.Table {
return c.plugins return c.plugins
} }
type TagFilter struct {
Name string
Filter []string
}
// Outputs returns the configured outputs as a map of name -> output toml // Outputs returns the configured outputs as a map of name -> output toml
func (c *Config) Outputs() map[string]*ast.Table { func (c *Config) Outputs() map[string]*ast.Table {
@ -50,17 +54,21 @@ func (c *Config) Outputs() map[string]*ast.Table {
} }
// ConfiguredPlugin containing a name, interval, and drop/pass prefix lists // ConfiguredPlugin containing a name, interval, and drop/pass prefix lists
// Also lists the tags to filter
type ConfiguredPlugin struct { type ConfiguredPlugin struct {
Name string Name string
Drop []string Drop []string
Pass []string Pass []string
TagDrop []TagFilter
TagPass []TagFilter
Interval time.Duration Interval time.Duration
} }
// ShouldPass returns true if the metric should pass, false if should drop // ShouldPass returns true if the metric should pass, false if should drop
func (cp *ConfiguredPlugin) ShouldPass(measurement string) bool { func (cp *ConfiguredPlugin) ShouldPass(measurement string, tags map[string]string) bool {
if cp.Pass != nil { if cp.Pass != nil {
for _, pat := range cp.Pass { for _, pat := range cp.Pass {
if strings.HasPrefix(measurement, pat) { if strings.HasPrefix(measurement, pat) {
@ -81,16 +89,41 @@ func (cp *ConfiguredPlugin) ShouldPass(measurement string) bool {
return true return true
} }
return true if cp.TagPass != nil {
for _, pat := range cp.TagPass {
if tagval, ok := tags[pat.Name]; ok {
for _, filter := range pat.Filter {
if filter == tagval {
return true
}
}
}
}
return false
}
if cp.TagDrop != nil {
for _, pat := range cp.TagDrop {
if tagval, ok := tags[pat.Name]; ok {
for _, filter := range pat.Filter {
if filter == tagval {
return false
}
}
}
}
return true
}
return nil
} }
// ApplyOutput loads the toml config into the given interface // ApplyOutput loads the toml config into the given interface
func (c *Config) ApplyOutput(name string, v interface{}) error { func (c *Config) ApplyOutput(name string, v interface{}) error {
if c.outputs[name] != nil { if c.outputs[name] != nil {
return toml.UnmarshalTable(c.outputs[name], v) return toml.UnmarshalTable(c.outputs[name], v)
} }
return nil
} }
// ApplyAgent loads the toml config into the given interface // ApplyAgent loads the toml config into the given interface
@ -147,9 +180,47 @@ func (c *Config) ApplyPlugin(name string, v interface{}) (*ConfiguredPlugin, err
} }
} }
if node, ok := tbl.Fields["tagpass"]; ok {
if subtbl, ok := node.(*ast.Table); ok {
for name, val := range subtbl.Fields {
if kv, ok := val.(*ast.KeyValue); ok {
tagfilter := &TagFilter{Name: name}
if ary, ok := kv.Value.(*ast.Array); ok {
for _, elem := range ary.Value {
if str, ok := elem.(*ast.String); ok {
tagfilter.Filter = append(tagfilter.Filter, str.Value)
}
}
}
cp.TagPass = append(cp.TagPass, *tagfilter)
}
}
}
}
if node, ok := tbl.Fields["tagdrop"]; ok {
if subtbl, ok := node.(*ast.Table); ok {
for name, val := range subtbl.Fields {
if kv, ok := val.(*ast.KeyValue); ok {
tagfilter := &TagFilter{Name: name}
if ary, ok := kv.Value.(*ast.Array); ok {
for _, elem := range ary.Value {
if str, ok := elem.(*ast.String); ok {
tagfilter.Filter = append(tagfilter.Filter, str.Value)
}
}
}
cp.TagDrop = append(cp.TagDrop, *tagfilter)
}
}
}
}
delete(tbl.Fields, "drop") delete(tbl.Fields, "drop")
delete(tbl.Fields, "pass") delete(tbl.Fields, "pass")
delete(tbl.Fields, "interval") delete(tbl.Fields, "interval")
delete(tbl.Fields, "tagdrop")
delete(tbl.Fields, "tagpass")
return cp, toml.UnmarshalTable(tbl, v) return cp, toml.UnmarshalTable(tbl, v)
} }
@ -227,6 +298,20 @@ func LoadConfig(path string) (*Config, error) {
return c, nil return c, nil
} }
// ListTags returns a string of tags specified in the config,
// line-protocol style
func (c *Config) ListTags() string {
var tags []string
for k, v := range c.Tags {
tags = append(tags, fmt.Sprintf("%s=%s", k, v))
}
sort.Strings(tags)
return strings.Join(tags, " ")
}
type hasConfig interface { type hasConfig interface {
BasicConfig() string BasicConfig() string
} }
@ -281,6 +366,9 @@ database = "telegraf" # required.
# Set the user agent for the POSTs (can be useful for log differentiation) # Set the user agent for the POSTs (can be useful for log differentiation)
# user_agent = "telegraf" # user_agent = "telegraf"
# Tags can also be specified via a normal map, but only one form at a time:
# [influxdb.tags]
# tags = { "dc" = "us-east-1" } # tags = { "dc" = "us-east-1" }
# Configuration for telegraf itself # Configuration for telegraf itself