aboutsummaryrefslogtreecommitdiff
path: root/collector/btrfs_linux.go
diff options
context:
space:
mode:
authorSilke Hofstra <silkeh@users.noreply.github.com>2020-02-19 15:48:51 +0100
committerGitHub <noreply@github.com>2020-02-19 15:48:51 +0100
commit8faa843fc42260cabb749cc9eb8886c191f28f7c (patch)
tree175a091379d2bb4b419a5b917647abfb40a00094 /collector/btrfs_linux.go
parentca1ac435eae5182b2795e14caa80713a7440687b (diff)
downloadprometheus_node_collector-8faa843fc42260cabb749cc9eb8886c191f28f7c.tar.bz2
prometheus_node_collector-8faa843fc42260cabb749cc9eb8886c191f28f7c.tar.xz
prometheus_node_collector-8faa843fc42260cabb749cc9eb8886c191f28f7c.zip
Add Btrfs collector (#1512)
* Add procfs/btrfs to vendor folder * Add Btrfs collector Resolves #1100 Signed-off-by: Silke Hofstra <silke@slxh.eu>
Diffstat (limited to 'collector/btrfs_linux.go')
-rw-r--r--collector/btrfs_linux.go189
1 files changed, 189 insertions, 0 deletions
diff --git a/collector/btrfs_linux.go b/collector/btrfs_linux.go
new file mode 100644
index 0000000..2336e65
--- /dev/null
+++ b/collector/btrfs_linux.go
@@ -0,0 +1,189 @@
1// Copyright 2019 The Prometheus Authors
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14// +build !nobtrfs
15
16package collector
17
18import (
19 "fmt"
20
21 "github.com/go-kit/kit/log"
22 "github.com/prometheus/client_golang/prometheus"
23 "github.com/prometheus/procfs/btrfs"
24)
25
26// A btrfsCollector is a Collector which gathers metrics from Btrfs filesystems.
27type btrfsCollector struct {
28 fs btrfs.FS
29 logger log.Logger
30}
31
32func init() {
33 registerCollector("btrfs", defaultEnabled, NewBtrfsCollector)
34}
35
36// NewBtrfsCollector returns a new Collector exposing Btrfs statistics.
37func NewBtrfsCollector(logger log.Logger) (Collector, error) {
38 fs, err := btrfs.NewFS(*sysPath)
39 if err != nil {
40 return nil, fmt.Errorf("failed to open sysfs: %v", err)
41 }
42
43 return &btrfsCollector{
44 fs: fs,
45 logger: logger,
46 }, nil
47}
48
49// Update retrieves and exports Btrfs statistics.
50// It implements Collector.
51func (c *btrfsCollector) Update(ch chan<- prometheus.Metric) error {
52 stats, err := c.fs.Stats()
53 if err != nil {
54 return fmt.Errorf("failed to retrieve Btrfs stats: %v", err)
55 }
56
57 for _, s := range stats {
58 c.updateBtrfsStats(ch, s)
59 }
60
61 return nil
62}
63
64// btrfsMetric represents a single Btrfs metric that is converted into a Prometheus Metric.
65type btrfsMetric struct {
66 name string
67 desc string
68 value float64
69 extraLabel []string
70 extraLabelValue []string
71}
72
73// updateBtrfsStats collects statistics for one bcache ID.
74func (c *btrfsCollector) updateBtrfsStats(ch chan<- prometheus.Metric, s *btrfs.Stats) {
75 const subsystem = "btrfs"
76
77 // Basic information about the filesystem.
78 devLabels := []string{"uuid"}
79
80 // Retrieve the metrics.
81 metrics := c.getMetrics(s)
82
83 // Convert all gathered metrics to Prometheus Metrics and add to channel.
84 for _, m := range metrics {
85 labels := append(devLabels, m.extraLabel...)
86
87 desc := prometheus.NewDesc(
88 prometheus.BuildFQName(namespace, subsystem, m.name),
89 m.desc,
90 labels,
91 nil,
92 )
93
94 labelValues := []string{s.UUID}
95 if len(m.extraLabelValue) > 0 {
96 labelValues = append(labelValues, m.extraLabelValue...)
97 }
98
99 ch <- prometheus.MustNewConstMetric(
100 desc,
101 prometheus.GaugeValue,
102 m.value,
103 labelValues...,
104 )
105 }
106}
107
108// getMetrics returns metrics for the given Btrfs statistics.
109func (c *btrfsCollector) getMetrics(s *btrfs.Stats) []btrfsMetric {
110 metrics := []btrfsMetric{
111 {
112 name: "info",
113 desc: "Filesystem information",
114 value: 1,
115 extraLabel: []string{"label"},
116 extraLabelValue: []string{s.Label},
117 },
118 {
119 name: "global_rsv_size_bytes",
120 desc: "Size of global reserve.",
121 value: float64(s.Allocation.GlobalRsvSize),
122 },
123 }
124
125 // Information about devices.
126 for n, dev := range s.Devices {
127 metrics = append(metrics, btrfsMetric{
128 name: "device_size_bytes",
129 desc: "Size of a device that is part of the filesystem.",
130 value: float64(dev.Size),
131 extraLabel: []string{"device"},
132 extraLabelValue: []string{n},
133 })
134 }
135
136 // Information about data, metadata and system data.
137 metrics = append(metrics, c.getAllocationStats("data", s.Allocation.Data)...)
138 metrics = append(metrics, c.getAllocationStats("metadata", s.Allocation.Metadata)...)
139 metrics = append(metrics, c.getAllocationStats("system", s.Allocation.System)...)
140
141 return metrics
142}
143
144// getAllocationStats returns allocation metrics for the given Btrfs Allocation statistics.
145func (c *btrfsCollector) getAllocationStats(a string, s *btrfs.AllocationStats) []btrfsMetric {
146 metrics := []btrfsMetric{
147 {
148 name: "reserved_bytes",
149 desc: "Amount of space reserved for a data type",
150 value: float64(s.ReservedBytes),
151 extraLabel: []string{"block_group_type"},
152 extraLabelValue: []string{a},
153 },
154 }
155
156 // Add all layout statistics.
157 for layout, stats := range s.Layouts {
158 metrics = append(metrics, c.getLayoutStats(a, layout, stats)...)
159 }
160
161 return metrics
162}
163
164// getLayoutStats returns metrics for a data layout.
165func (c *btrfsCollector) getLayoutStats(a, l string, s *btrfs.LayoutUsage) []btrfsMetric {
166 return []btrfsMetric{
167 {
168 name: "used_bytes",
169 desc: "Amount of used space by a layout/data type",
170 value: float64(s.UsedBytes),
171 extraLabel: []string{"block_group_type", "mode"},
172 extraLabelValue: []string{a, l},
173 },
174 {
175 name: "size_bytes",
176 desc: "Amount of space allocated for a layout/data type",
177 value: float64(s.TotalBytes),
178 extraLabel: []string{"block_group_type", "mode"},
179 extraLabelValue: []string{a, l},
180 },
181 {
182 name: "allocation_ratio",
183 desc: "Data allocation ratio for a layout/data type",
184 value: s.Ratio,
185 extraLabel: []string{"block_group_type", "mode"},
186 extraLabelValue: []string{a, l},
187 },
188 }
189}