diff options
author | Julius Volz <julius@soundcloud.com> | 2015-09-03 16:59:56 +0200 |
---|---|---|
committer | Julius Volz <julius@soundcloud.com> | 2015-09-04 15:42:44 +0200 |
commit | e13f91042797c571df31ed5ffa1e8bd53583b889 (patch) | |
tree | 98f50f5539ad875a9c553d4f821fc94784806de9 /collector/textfile.go | |
parent | 704e8f76d81e9569873eb8f8a0bac0bc1dd74c4e (diff) | |
download | prometheus_node_collector-e13f91042797c571df31ed5ffa1e8bd53583b889.tar.bz2 prometheus_node_collector-e13f91042797c571df31ed5ffa1e8bd53583b889.tar.xz prometheus_node_collector-e13f91042797c571df31ed5ffa1e8bd53583b889.zip |
Fix mtime reporting in textfile collector, add tests.
Diffstat (limited to 'collector/textfile.go')
-rw-r--r-- | collector/textfile.go | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/collector/textfile.go b/collector/textfile.go index 0950ad9..e032bed 100644 --- a/collector/textfile.go +++ b/collector/textfile.go | |||
@@ -8,6 +8,7 @@ import ( | |||
8 | "io/ioutil" | 8 | "io/ioutil" |
9 | "os" | 9 | "os" |
10 | "path/filepath" | 10 | "path/filepath" |
11 | "sort" | ||
11 | "strings" | 12 | "strings" |
12 | "time" | 13 | "time" |
13 | 14 | ||
@@ -25,6 +26,7 @@ var ( | |||
25 | ) | 26 | ) |
26 | 27 | ||
27 | type textFileCollector struct { | 28 | type textFileCollector struct { |
29 | path string | ||
28 | } | 30 | } |
29 | 31 | ||
30 | func init() { | 32 | func init() { |
@@ -34,15 +36,19 @@ func init() { | |||
34 | // Takes a registers a | 36 | // Takes a registers a |
35 | // SetMetricFamilyInjectionHook. | 37 | // SetMetricFamilyInjectionHook. |
36 | func NewTextFileCollector() (Collector, error) { | 38 | func NewTextFileCollector() (Collector, error) { |
37 | if *textFileDirectory == "" { | 39 | c := &textFileCollector{ |
40 | path: *textFileDirectory, | ||
41 | } | ||
42 | |||
43 | if c.path == "" { | ||
38 | // This collector is enabled by default, so do not fail if | 44 | // This collector is enabled by default, so do not fail if |
39 | // the flag is not passed. | 45 | // the flag is not passed. |
40 | log.Infof("No directory specified, see --textfile.directory") | 46 | log.Infof("No directory specified, see --textfile.directory") |
41 | } else { | 47 | } else { |
42 | prometheus.SetMetricFamilyInjectionHook(parseTextFiles) | 48 | prometheus.SetMetricFamilyInjectionHook(c.parseTextFiles) |
43 | } | 49 | } |
44 | 50 | ||
45 | return &textFileCollector{}, nil | 51 | return c, nil |
46 | } | 52 | } |
47 | 53 | ||
48 | // textFile collector works via SetMetricFamilyInjectionHook in parseTextFiles. | 54 | // textFile collector works via SetMetricFamilyInjectionHook in parseTextFiles. |
@@ -50,26 +56,29 @@ func (c *textFileCollector) Update(ch chan<- prometheus.Metric) (err error) { | |||
50 | return nil | 56 | return nil |
51 | } | 57 | } |
52 | 58 | ||
53 | func parseTextFiles() []*dto.MetricFamily { | 59 | func (c *textFileCollector) parseTextFiles() []*dto.MetricFamily { |
54 | var parser text.Parser | ||
55 | error := 0.0 | 60 | error := 0.0 |
56 | metricFamilies := make([]*dto.MetricFamily, 0) | 61 | metricFamilies := make([]*dto.MetricFamily, 0) |
57 | mtimes := map[string]time.Time{} | 62 | mtimes := map[string]time.Time{} |
58 | 63 | ||
59 | // Iterate over files and accumulate their metrics. | 64 | // Iterate over files and accumulate their metrics. |
60 | files, _ := ioutil.ReadDir(*textFileDirectory) | 65 | files, err := ioutil.ReadDir(c.path) |
66 | if err != nil && c.path != "" { | ||
67 | log.Errorf("Error reading textfile collector directory %s: %s", c.path, err) | ||
68 | error = 1.0 | ||
69 | } | ||
61 | for _, f := range files { | 70 | for _, f := range files { |
62 | if !strings.HasSuffix(f.Name(), ".prom") { | 71 | if !strings.HasSuffix(f.Name(), ".prom") { |
63 | continue | 72 | continue |
64 | } | 73 | } |
65 | path := filepath.Join(*textFileDirectory, f.Name()) | 74 | path := filepath.Join(c.path, f.Name()) |
66 | file, err := os.Open(path) | 75 | file, err := os.Open(path) |
67 | if err != nil { | 76 | if err != nil { |
68 | log.Errorf("Error opening %s: %v", path, err) | 77 | log.Errorf("Error opening %s: %v", path, err) |
69 | error = 1.0 | 78 | error = 1.0 |
70 | continue | 79 | continue |
71 | } | 80 | } |
72 | parsedFamilies, err := parser.TextToMetricFamilies(file) | 81 | parsedFamilies, err := (&text.Parser{}).TextToMetricFamilies(file) |
73 | if err != nil { | 82 | if err != nil { |
74 | log.Errorf("Error parsing %s: %v", path, err) | 83 | log.Errorf("Error parsing %s: %v", path, err) |
75 | error = 1.0 | 84 | error = 1.0 |
@@ -95,16 +104,24 @@ func parseTextFiles() []*dto.MetricFamily { | |||
95 | Type: dto.MetricType_GAUGE.Enum(), | 104 | Type: dto.MetricType_GAUGE.Enum(), |
96 | Metric: []*dto.Metric{}, | 105 | Metric: []*dto.Metric{}, |
97 | } | 106 | } |
98 | for name, mtime := range mtimes { | 107 | |
108 | // Sorting is needed for predictable output comparison in tests. | ||
109 | filenames := make([]string, 0, len(mtimes)) | ||
110 | for filename := range mtimes { | ||
111 | filenames = append(filenames, filename) | ||
112 | } | ||
113 | sort.Strings(filenames) | ||
114 | |||
115 | for _, filename := range filenames { | ||
99 | mtimeMetricFamily.Metric = append(mtimeMetricFamily.Metric, | 116 | mtimeMetricFamily.Metric = append(mtimeMetricFamily.Metric, |
100 | &dto.Metric{ | 117 | &dto.Metric{ |
101 | Label: []*dto.LabelPair{ | 118 | Label: []*dto.LabelPair{ |
102 | &dto.LabelPair{ | 119 | &dto.LabelPair{ |
103 | Name: proto.String("file"), | 120 | Name: proto.String("file"), |
104 | Value: &name, | 121 | Value: proto.String(filename), |
105 | }, | 122 | }, |
106 | }, | 123 | }, |
107 | Gauge: &dto.Gauge{Value: proto.Float64(float64(mtime.UnixNano()) / 1e9)}, | 124 | Gauge: &dto.Gauge{Value: proto.Float64(float64(mtimes[filename].UnixNano()) / 1e9)}, |
108 | }, | 125 | }, |
109 | ) | 126 | ) |
110 | } | 127 | } |