config.go 2.2 KB

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