github.com/Psiphon-Inc/goarista@v0.0.0-20160825065156-d002785f4c67/cmd/octsdb/config.go (about) 1 // Copyright (C) 2016 Arista Networks, Inc. 2 // Use of this source code is governed by the Apache License 2.0 3 // that can be found in the COPYING file. 4 5 package main 6 7 import ( 8 "encoding/json" 9 "fmt" 10 "io/ioutil" 11 "regexp" 12 "strings" 13 ) 14 15 // Config is the representation of octsdb's JSON config file. 16 type Config struct { 17 // Prefixes to subscribe to. 18 Subscriptions []string 19 20 // MetricPrefix, if set, is used to prefix all the metric names. 21 MetricPrefix string 22 23 // Metrics to collect and how to munge them. 24 Metrics map[string]*Metric 25 } 26 27 // A Metric to collect and how to massage it into an OpenTSDB put. 28 type Metric struct { 29 // Path is a regexp to match on the Update's full path. 30 // The regexp must be a prefix match. 31 // The regexp can define named capture groups to use as tags. 32 Path string 33 34 // Path compiled as a regexp. 35 re *regexp.Regexp 36 37 // Additional tags to add to this metric. 38 Tags map[string]string 39 } 40 41 func loadConfig(path string) (*Config, error) { 42 cfg, err := ioutil.ReadFile(path) 43 if err != nil { 44 return nil, fmt.Errorf("Failed to load config: %v", err) 45 } 46 config := new(Config) 47 err = json.Unmarshal(cfg, config) 48 if err != nil { 49 return nil, fmt.Errorf("Failed to parse config: %v", err) 50 } 51 for _, metric := range config.Metrics { 52 metric.re = regexp.MustCompile(metric.Path) 53 } 54 return config, nil 55 } 56 57 // Match applies this config to the given OpenConfig path. 58 // If the path doesn't match anything in the config, an empty string 59 // is returned as the metric name. 60 func (c *Config) Match(path string) (metricName string, tags map[string]string) { 61 tags = make(map[string]string) 62 63 for _, metric := range c.Metrics { 64 found := metric.re.FindStringSubmatch(path) 65 if found == nil { 66 continue 67 } 68 for i, name := range metric.re.SubexpNames() { 69 if i == 0 { 70 continue 71 } else if name == "" { 72 if metricName != "" { 73 metricName += "/" 74 } 75 metricName += found[i] 76 } else { 77 tags[name] = found[i] 78 } 79 } 80 for tag, value := range metric.Tags { 81 tags[tag] = value 82 } 83 break 84 } 85 if metricName != "" { 86 metricName = strings.ToLower(strings.Replace(metricName, "/", ".", -1)) 87 if c.MetricPrefix != "" { 88 metricName = c.MetricPrefix + "." + metricName 89 } 90 } 91 return 92 }