aboutsummaryrefslogtreecommitdiff
path: root/collector/textfile.go
diff options
context:
space:
mode:
authorJulius Volz <julius@soundcloud.com>2015-09-03 16:59:56 +0200
committerJulius Volz <julius@soundcloud.com>2015-09-04 15:42:44 +0200
commite13f91042797c571df31ed5ffa1e8bd53583b889 (patch)
tree98f50f5539ad875a9c553d4f821fc94784806de9 /collector/textfile.go
parent704e8f76d81e9569873eb8f8a0bac0bc1dd74c4e (diff)
downloadprometheus_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.go39
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
27type textFileCollector struct { 28type textFileCollector struct {
29 path string
28} 30}
29 31
30func init() { 32func init() {
@@ -34,15 +36,19 @@ func init() {
34// Takes a registers a 36// Takes a registers a
35// SetMetricFamilyInjectionHook. 37// SetMetricFamilyInjectionHook.
36func NewTextFileCollector() (Collector, error) { 38func 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
53func parseTextFiles() []*dto.MetricFamily { 59func (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 }