Update prometheus/procfs

Fixes: https://github.com/prometheus/node_exporter/issues/1721

Signed-off-by: Ben Kochie <superq@gmail.com>
This commit is contained in:
Ben Kochie 2020-06-06 09:00:09 +02:00
commit baa7ab732f
No known key found for this signature in database
GPG key ID: C646B23C9E3245F1
51 changed files with 2699 additions and 292 deletions

View file

@ -43,10 +43,11 @@ type BcacheStats struct { // nolint:golint
// BdevStats contains statistics for one backing device.
type BdevStats struct {
Name string
DirtyData uint64
FiveMin PeriodStats
Total PeriodStats
Name string
DirtyData uint64
FiveMin PeriodStats
Total PeriodStats
WritebackRateDebug WritebackRateDebugStats
}
// CacheStats contains statistics for one cache device.
@ -82,3 +83,14 @@ type PeriodStats struct {
CacheMisses uint64
CacheReadaheads uint64
}
// WritebackRateDebugStats contains bcache writeback statistics.
type WritebackRateDebugStats struct {
Rate uint64
Dirty uint64
Target uint64
Proportional int64
Integral int64
Change int64
NextIO int64
}

View file

@ -174,6 +174,17 @@ func dehumanize(hbytes []byte) (uint64, error) {
return res, nil
}
func dehumanizeSigned(str string) (int64, error) {
value, err := dehumanize([]byte(strings.TrimPrefix(str, "-")))
if err != nil {
return 0, err
}
if strings.HasPrefix(str, "-") {
return int64(-value), nil
}
return int64(value), nil
}
type parser struct {
uuidPath string
subDir string
@ -232,6 +243,72 @@ func parsePriorityStats(line string, ps *PriorityStats) error {
return nil
}
// ParseWritebackRateDebug parses lines from the writeback_rate_debug file.
func parseWritebackRateDebug(line string, wrd *WritebackRateDebugStats) error {
switch {
case strings.HasPrefix(line, "rate:"):
fields := strings.Fields(line)
rawValue := fields[len(fields)-1]
valueStr := strings.TrimSuffix(rawValue, "/sec")
value, err := dehumanize([]byte(valueStr))
if err != nil {
return err
}
wrd.Rate = value
case strings.HasPrefix(line, "dirty:"):
fields := strings.Fields(line)
valueStr := fields[len(fields)-1]
value, err := dehumanize([]byte(valueStr))
if err != nil {
return err
}
wrd.Dirty = value
case strings.HasPrefix(line, "target:"):
fields := strings.Fields(line)
valueStr := fields[len(fields)-1]
value, err := dehumanize([]byte(valueStr))
if err != nil {
return err
}
wrd.Target = value
case strings.HasPrefix(line, "proportional:"):
fields := strings.Fields(line)
valueStr := fields[len(fields)-1]
value, err := dehumanizeSigned(valueStr)
if err != nil {
return err
}
wrd.Proportional = value
case strings.HasPrefix(line, "integral:"):
fields := strings.Fields(line)
valueStr := fields[len(fields)-1]
value, err := dehumanizeSigned(valueStr)
if err != nil {
return err
}
wrd.Integral = value
case strings.HasPrefix(line, "change:"):
fields := strings.Fields(line)
rawValue := fields[len(fields)-1]
valueStr := strings.TrimSuffix(rawValue, "/sec")
value, err := dehumanizeSigned(valueStr)
if err != nil {
return err
}
wrd.Change = value
case strings.HasPrefix(line, "next io:"):
fields := strings.Fields(line)
rawValue := fields[len(fields)-1]
valueStr := strings.TrimSuffix(rawValue, "ms")
value, err := strconv.ParseInt(valueStr, 10, 64)
if err != nil {
return err
}
wrd.NextIO = value
}
return nil
}
func (p *parser) getPriorityStats() PriorityStats {
var res PriorityStats
@ -263,6 +340,35 @@ func (p *parser) getPriorityStats() PriorityStats {
return res
}
func (p *parser) getWritebackRateDebug() WritebackRateDebugStats {
var res WritebackRateDebugStats
if p.err != nil {
return res
}
path := path.Join(p.currentDir, "writeback_rate_debug")
file, err := os.Open(path)
if err != nil {
p.err = fmt.Errorf("failed to read: %s", path)
return res
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
err = parseWritebackRateDebug(scanner.Text(), &res)
if err != nil {
p.err = fmt.Errorf("failed to parse: %s (%s)", path, err)
return res
}
}
if err := scanner.Err(); err != nil {
p.err = fmt.Errorf("failed to parse: %s (%s)", path, err)
return res
}
return res
}
// GetStats collects from sysfs files data tied to one bcache ID.
func GetStats(uuidPath string, priorityStats bool) (*Stats, error) {
var bs Stats
@ -339,6 +445,9 @@ func GetStats(uuidPath string, priorityStats bool) (*Stats, error) {
par.setSubDir(bds.Name)
bds.DirtyData = par.readValue("dirty_data")
wrd := par.getWritebackRateDebug()
bds.WritebackRateDebug = wrd
// dir <uuidPath>/<bds.Name>/stats_five_minute
par.setSubDir(bds.Name, "stats_five_minute")
bds.FiveMin.Bypassed = par.readValue("bypassed")