Этот коммит содержится в:
Christopher Speller
2017-06-21 19:06:17 -07:00
коммит произвёл Corey Hulen
родитель 6b39c308d8
Коммит 42f28ab8e3
714 изменённых файлов: 54430 добавлений и 51180 удалений

4
vendor/github.com/prometheus/procfs/.travis.yml сгенерированный поставляемый
Просмотреть файл

@@ -1,5 +1,5 @@
sudo: false
language: go
go:
- 1.6.4
- 1.7.4
- 1.7.6
- 1.8.3

16
vendor/github.com/prometheus/procfs/Makefile сгенерированный поставляемый
Просмотреть файл

@@ -1,6 +1,18 @@
ci:
ci: fmt lint test
fmt:
! gofmt -l *.go | read nothing
go vet
go test -v ./...
lint:
go get github.com/golang/lint/golint
golint *.go
test: sysfs/fixtures/.unpacked
go test -v ./...
sysfs/fixtures/.unpacked: sysfs/fixtures.tar.gz
cd sysfs && tar xzf fixtures.tar.gz
touch $@
.PHONY: fmt lint test ci

84
vendor/github.com/prometheus/procfs/bcache/bcache.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,84 @@
// Copyright 2017 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package bcache provides access to statistics exposed by the bcache (Linux
// block cache).
package bcache
// Stats contains bcache runtime statistics, parsed from /sys/fs/bcache/.
//
// The names and meanings of each statistic were taken from bcache.txt and
// files in drivers/md/bcache in the Linux kernel source. Counters are uint64
// (in-kernel counters are mostly unsigned long).
type Stats struct {
// The name of the bcache used to source these statistics.
Name string
Bcache BcacheStats
Bdevs []BdevStats
Caches []CacheStats
}
// BcacheStats contains statistics tied to a bcache ID.
type BcacheStats struct {
AverageKeySize uint64
BtreeCacheSize uint64
CacheAvailablePercent uint64
Congested uint64
RootUsagePercent uint64
TreeDepth uint64
Internal InternalStats
FiveMin PeriodStats
Total PeriodStats
}
// BdevStats contains statistics for one backing device.
type BdevStats struct {
Name string
DirtyData uint64
FiveMin PeriodStats
Total PeriodStats
}
// CacheStats contains statistics for one cache device.
type CacheStats struct {
Name string
IOErrors uint64
MetadataWritten uint64
Written uint64
Priority PriorityStats
}
// PriorityStats contains statistics from the priority_stats file.
type PriorityStats struct {
UnusedPercent uint64
MetadataPercent uint64
}
// InternalStats contains internal bcache statistics.
type InternalStats struct {
ActiveJournalEntries uint64
BtreeNodes uint64
BtreeReadAverageDurationNanoSeconds uint64
CacheReadRaces uint64
}
// PeriodStats contains statistics for a time period (5 min or total).
type PeriodStats struct {
Bypassed uint64
CacheBypassHits uint64
CacheBypassMisses uint64
CacheHits uint64
CacheMissCollisions uint64
CacheMisses uint64
CacheReadaheads uint64
}

330
vendor/github.com/prometheus/procfs/bcache/get.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,330 @@
// Copyright 2017 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package bcache
import (
"bufio"
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
"strconv"
"strings"
)
// ParsePseudoFloat parses the peculiar format produced by bcache's bch_hprint.
func parsePseudoFloat(str string) (float64, error) {
ss := strings.Split(str, ".")
intPart, err := strconv.ParseFloat(ss[0], 64)
if err != nil {
return 0, err
}
if len(ss) == 1 {
// Pure integers are fine.
return intPart, nil
}
fracPart, err := strconv.ParseFloat(ss[1], 64)
if err != nil {
return 0, err
}
// fracPart is a number between 0 and 1023 divided by 100; it is off
// by a small amount. Unexpected bumps in time lines may occur because
// for bch_hprint .1 != .10 and .10 > .9 (at least up to Linux
// v4.12-rc3).
// Restore the proper order:
fracPart = fracPart / 10.24
return intPart + fracPart, nil
}
// Dehumanize converts a human-readable byte slice into a uint64.
func dehumanize(hbytes []byte) (uint64, error) {
ll := len(hbytes)
if ll == 0 {
return 0, fmt.Errorf("zero-length reply")
}
lastByte := hbytes[ll-1]
mul := float64(1)
var (
mant float64
err error
)
// If lastByte is beyond the range of ASCII digits, it must be a
// multiplier.
if lastByte > 57 {
// Remove multiplier from slice.
hbytes = hbytes[:len(hbytes)-1]
const (
_ = 1 << (10 * iota)
KiB
MiB
GiB
TiB
PiB
EiB
ZiB
YiB
)
multipliers := map[rune]float64{
// Source for conversion rules:
// linux-kernel/drivers/md/bcache/util.c:bch_hprint()
'k': KiB,
'M': MiB,
'G': GiB,
'T': TiB,
'P': PiB,
'E': EiB,
'Z': ZiB,
'Y': YiB,
}
mul = float64(multipliers[rune(lastByte)])
mant, err = parsePseudoFloat(string(hbytes))
if err != nil {
return 0, err
}
} else {
// Not humanized by bch_hprint
mant, err = strconv.ParseFloat(string(hbytes), 64)
if err != nil {
return 0, err
}
}
res := uint64(mant * mul)
return res, nil
}
type parser struct {
uuidPath string
subDir string
currentDir string
err error
}
func (p *parser) setSubDir(pathElements ...string) {
p.subDir = path.Join(pathElements...)
p.currentDir = path.Join(p.uuidPath, p.subDir)
}
func (p *parser) readValue(fileName string) uint64 {
if p.err != nil {
return 0
}
path := path.Join(p.currentDir, fileName)
byt, err := ioutil.ReadFile(path)
if err != nil {
p.err = fmt.Errorf("failed to read: %s", path)
return 0
}
// Remove trailing newline.
byt = byt[:len(byt)-1]
res, err := dehumanize(byt)
p.err = err
return res
}
// ParsePriorityStats parses lines from the priority_stats file.
func parsePriorityStats(line string, ps *PriorityStats) (error) {
var (
value uint64
err error
)
switch {
case strings.HasPrefix(line, "Unused:"):
fields := strings.Fields(line)
rawValue := fields[len(fields)-1]
valueStr := strings.TrimSuffix(rawValue, "%")
value, err = strconv.ParseUint(valueStr, 10, 64)
if err != nil {
return err
}
ps.UnusedPercent = value
case strings.HasPrefix(line, "Metadata:"):
fields := strings.Fields(line)
rawValue := fields[len(fields)-1]
valueStr := strings.TrimSuffix(rawValue, "%")
value, err = strconv.ParseUint(valueStr, 10, 64)
if err != nil {
return err
}
ps.MetadataPercent = value
}
return nil
}
func (p *parser) getPriorityStats() PriorityStats {
var res PriorityStats
if p.err != nil {
return res
}
path := path.Join(p.currentDir, "priority_stats")
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 = parsePriorityStats(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) (*Stats, error) {
var bs Stats
par := parser{uuidPath: uuidPath}
// bcache stats
// dir <uuidPath>
par.setSubDir("")
bs.Bcache.AverageKeySize = par.readValue("average_key_size")
bs.Bcache.BtreeCacheSize = par.readValue("btree_cache_size")
bs.Bcache.CacheAvailablePercent = par.readValue("cache_available_percent")
bs.Bcache.Congested = par.readValue("congested")
bs.Bcache.RootUsagePercent = par.readValue("root_usage_percent")
bs.Bcache.TreeDepth = par.readValue("tree_depth")
// bcache stats (internal)
// dir <uuidPath>/internal
par.setSubDir("internal")
bs.Bcache.Internal.ActiveJournalEntries = par.readValue("active_journal_entries")
bs.Bcache.Internal.BtreeNodes = par.readValue("btree_nodes")
bs.Bcache.Internal.BtreeReadAverageDurationNanoSeconds = par.readValue("btree_read_average_duration_us")
bs.Bcache.Internal.CacheReadRaces = par.readValue("cache_read_races")
// bcache stats (period)
// dir <uuidPath>/stats_five_minute
par.setSubDir("stats_five_minute")
bs.Bcache.FiveMin.Bypassed = par.readValue("bypassed")
bs.Bcache.FiveMin.CacheHits = par.readValue("cache_hits")
bs.Bcache.FiveMin.Bypassed = par.readValue("bypassed")
bs.Bcache.FiveMin.CacheBypassHits = par.readValue("cache_bypass_hits")
bs.Bcache.FiveMin.CacheBypassMisses = par.readValue("cache_bypass_misses")
bs.Bcache.FiveMin.CacheHits = par.readValue("cache_hits")
bs.Bcache.FiveMin.CacheMissCollisions = par.readValue("cache_miss_collisions")
bs.Bcache.FiveMin.CacheMisses = par.readValue("cache_misses")
bs.Bcache.FiveMin.CacheReadaheads = par.readValue("cache_readaheads")
// dir <uuidPath>/stats_total
par.setSubDir("stats_total")
bs.Bcache.Total.Bypassed = par.readValue("bypassed")
bs.Bcache.Total.CacheHits = par.readValue("cache_hits")
bs.Bcache.Total.Bypassed = par.readValue("bypassed")
bs.Bcache.Total.CacheBypassHits = par.readValue("cache_bypass_hits")
bs.Bcache.Total.CacheBypassMisses = par.readValue("cache_bypass_misses")
bs.Bcache.Total.CacheHits = par.readValue("cache_hits")
bs.Bcache.Total.CacheMissCollisions = par.readValue("cache_miss_collisions")
bs.Bcache.Total.CacheMisses = par.readValue("cache_misses")
bs.Bcache.Total.CacheReadaheads = par.readValue("cache_readaheads")
if par.err != nil {
return nil, par.err
}
// bdev stats
reg := path.Join(uuidPath, "bdev[0-9]*")
bdevDirs, err := filepath.Glob(reg)
if err != nil {
return nil, err
}
bs.Bdevs = make([]BdevStats, len(bdevDirs))
for ii, bdevDir := range bdevDirs {
var bds = &bs.Bdevs[ii]
bds.Name = filepath.Base(bdevDir)
par.setSubDir(bds.Name)
bds.DirtyData = par.readValue("dirty_data")
// dir <uuidPath>/<bds.Name>/stats_five_minute
par.setSubDir(bds.Name, "stats_five_minute")
bds.FiveMin.Bypassed = par.readValue("bypassed")
bds.FiveMin.CacheBypassHits = par.readValue("cache_bypass_hits")
bds.FiveMin.CacheBypassMisses = par.readValue("cache_bypass_misses")
bds.FiveMin.CacheHits = par.readValue("cache_hits")
bds.FiveMin.CacheMissCollisions = par.readValue("cache_miss_collisions")
bds.FiveMin.CacheMisses = par.readValue("cache_misses")
bds.FiveMin.CacheReadaheads = par.readValue("cache_readaheads")
// dir <uuidPath>/<bds.Name>/stats_total
par.setSubDir("stats_total")
bds.Total.Bypassed = par.readValue("bypassed")
bds.Total.CacheBypassHits = par.readValue("cache_bypass_hits")
bds.Total.CacheBypassMisses = par.readValue("cache_bypass_misses")
bds.Total.CacheHits = par.readValue("cache_hits")
bds.Total.CacheMissCollisions = par.readValue("cache_miss_collisions")
bds.Total.CacheMisses = par.readValue("cache_misses")
bds.Total.CacheReadaheads = par.readValue("cache_readaheads")
}
if par.err != nil {
return nil, par.err
}
// cache stats
reg = path.Join(uuidPath, "cache[0-9]*")
cacheDirs, err := filepath.Glob(reg)
if err != nil {
return nil, err
}
bs.Caches = make([]CacheStats, len(cacheDirs))
for ii, cacheDir := range cacheDirs {
var cs = &bs.Caches[ii]
cs.Name = filepath.Base(cacheDir)
// dir is <uuidPath>/<cs.Name>
par.setSubDir(cs.Name)
cs.IOErrors = par.readValue("io_errors")
cs.MetadataWritten = par.readValue("metadata_written")
cs.Written = par.readValue("written")
ps := par.getPriorityStats()
cs.Priority = ps
}
if par.err != nil {
return nil, par.err
}
return &bs, nil
}

114
vendor/github.com/prometheus/procfs/bcache/get_test.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,114 @@
// Copyright 2017 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package bcache
import (
"testing"
"math"
)
func TestDehumanizeTests(t *testing.T) {
dehumanizeTests := []struct {
in []byte
out uint64
invalid bool
}{
{
in: []byte("542k"),
out: 555008,
},
{
in: []byte("322M"),
out: 337641472,
},
{
in: []byte("1.1k"),
out: 1124,
},
{
in: []byte("1.9k"),
out: 1924,
},
{
in: []byte("1.10k"),
out: 2024,
},
{
in: []byte(""),
out: 0,
invalid: true,
},
}
for _, tst := range dehumanizeTests {
got, err := dehumanize(tst.in)
if tst.invalid && err == nil {
t.Error("expected an error, but none occurred")
}
if !tst.invalid && err != nil {
t.Errorf("unexpected error: %v", err)
}
if got != tst.out {
t.Errorf("dehumanize: '%s', want %f, got %f", tst.in, tst.out, got)
}
}
}
func TestParsePseudoFloatTests(t *testing.T) {
parsePseudoFloatTests := []struct {
in string
out float64
}{
{
in: "1.1",
out: float64(1.097656),
},
{
in: "1.9",
out: float64(1.878906),
},
{
in: "1.10",
out: float64(1.976562),
},
}
for _, tst := range parsePseudoFloatTests {
got, err := parsePseudoFloat(tst.in)
if err != nil || math.Abs(got - tst.out) > 0.0001 {
t.Errorf("parsePseudoFloat: %s, want %f, got %f", tst.in, tst.out, got)
}
}
}
func TestPriorityStats(t *testing.T) {
var want = PriorityStats{
UnusedPercent: 99,
MetadataPercent: 5,
}
var (
in string
gotErr error
got PriorityStats
)
in = "Metadata: 5%"
gotErr = parsePriorityStats(in, &got)
if gotErr != nil || got.MetadataPercent != want.MetadataPercent {
t.Errorf("parsePriorityStats: '%s', want %f, got %f", in, want.MetadataPercent, got.MetadataPercent)
}
in = "Unused: 99%"
gotErr = parsePriorityStats(in, &got)
if gotErr != nil || got.UnusedPercent != want.UnusedPercent {
t.Errorf("parsePriorityStats: '%s', want %f, got %f", in, want.UnusedPercent, got.UnusedPercent)
}
}

28
vendor/github.com/prometheus/procfs/fixtures/net/xfrm_stat сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,28 @@
XfrmInError 1
XfrmInBufferError 2
XfrmInHdrError 4
XfrmInNoStates 3
XfrmInStateProtoError 40
XfrmInStateModeError 100
XfrmInStateSeqError 6000
XfrmInStateExpired 4
XfrmInStateMismatch 23451
XfrmInStateInvalid 55555
XfrmInTmplMismatch 51
XfrmInNoPols 65432
XfrmInPolBlock 100
XfrmInPolError 10000
XfrmOutError 1000000
XfrmOutBundleGenError 43321
XfrmOutBundleCheckError 555
XfrmOutNoStates 869
XfrmOutStateProtoError 4542
XfrmOutStateModeError 4
XfrmOutStateSeqError 543
XfrmOutStateExpired 565
XfrmOutPolBlock 43456
XfrmOutPolDead 7656
XfrmOutPolError 1454
XfrmFwdHdrError 6654
XfrmOutStateInvalid 28765
XfrmAcquireError 24532

2
vendor/github.com/prometheus/procfs/fixtures/stat сгенерированный поставляемый
Просмотреть файл

@@ -12,5 +12,5 @@ ctxt 38014093
btime 1418183276
processes 26442
procs_running 2
procs_blocked 0
procs_blocked 1
softirq 5057579 250191 1481983 1647 211099 186066 0 1783454 622196 12499 508444

193
vendor/github.com/prometheus/procfs/stat.go сгенерированный поставляемый
Просмотреть файл

@@ -3,15 +3,66 @@ package procfs
import (
"bufio"
"fmt"
"io"
"os"
"strconv"
"strings"
)
// CPUStat shows how much time the cpu spend in various stages.
type CPUStat struct {
User float64
Nice float64
System float64
Idle float64
Iowait float64
IRQ float64
SoftIRQ float64
Steal float64
Guest float64
GuestNice float64
}
// SoftIRQStat represent the softirq statistics as exported in the procfs stat file.
// A nice introduction can be found at https://0xax.gitbooks.io/linux-insides/content/interrupts/interrupts-9.html
// It is possible to get per-cpu stats by reading /proc/softirqs
type SoftIRQStat struct {
Hi uint64
Timer uint64
NetTx uint64
NetRx uint64
Block uint64
BlockIoPoll uint64
Tasklet uint64
Sched uint64
Hrtimer uint64
Rcu uint64
}
// Stat represents kernel/system statistics.
type Stat struct {
// Boot time in seconds since the Epoch.
BootTime int64
BootTime uint64
// Summed up cpu statistics.
CPUTotal CPUStat
// Per-CPU statistics.
CPU []CPUStat
// Number of times interrupts were handled, which contains numbered and unnumbered IRQs.
IRQTotal uint64
// Number of times a numbered IRQ was triggered.
IRQ []uint64
// Number of times a context switch happened.
ContextSwitches uint64
// Number of times a process was created.
ProcessCreated uint64
// Number of processes currently running.
ProcessesRunning uint64
// Number of processes currently blocked (waiting for IO).
ProcessesBlocked uint64
// Number of times a softirq was scheduled.
SoftIRQTotal uint64
// Detailed softirq statistics.
SoftIRQ SoftIRQStat
}
// NewStat returns kernel/system statistics read from /proc/stat.
@@ -24,33 +75,145 @@ func NewStat() (Stat, error) {
return fs.NewStat()
}
// Parse a cpu statistics line and returns the CPUStat struct plus the cpu id (or -1 for the overall sum).
func parseCPUStat(line string) (CPUStat, int64, error) {
cpuStat := CPUStat{}
var cpu string
count, err := fmt.Sscanf(line, "%s %f %f %f %f %f %f %f %f %f %f",
&cpu,
&cpuStat.User, &cpuStat.Nice, &cpuStat.System, &cpuStat.Idle,
&cpuStat.Iowait, &cpuStat.IRQ, &cpuStat.SoftIRQ, &cpuStat.Steal,
&cpuStat.Guest, &cpuStat.GuestNice)
if err != nil && err != io.EOF {
return CPUStat{}, -1, fmt.Errorf("couldn't parse %s (cpu): %s", line, err)
}
if count == 0 {
return CPUStat{}, -1, fmt.Errorf("couldn't parse %s (cpu): 0 elements parsed", line)
}
cpuStat.User /= userHZ
cpuStat.Nice /= userHZ
cpuStat.System /= userHZ
cpuStat.Idle /= userHZ
cpuStat.Iowait /= userHZ
cpuStat.IRQ /= userHZ
cpuStat.SoftIRQ /= userHZ
cpuStat.Steal /= userHZ
cpuStat.Guest /= userHZ
cpuStat.GuestNice /= userHZ
if cpu == "cpu" {
return cpuStat, -1, nil
}
cpuID, err := strconv.ParseInt(cpu[3:], 10, 64)
if err != nil {
return CPUStat{}, -1, fmt.Errorf("couldn't parse %s (cpu/cpuid): %s", line, err)
}
return cpuStat, cpuID, nil
}
// Parse a softirq line.
func parseSoftIRQStat(line string) (SoftIRQStat, uint64, error) {
softIRQStat := SoftIRQStat{}
var total uint64
var prefix string
_, err := fmt.Sscanf(line, "%s %d %d %d %d %d %d %d %d %d %d %d",
&prefix, &total,
&softIRQStat.Hi, &softIRQStat.Timer, &softIRQStat.NetTx, &softIRQStat.NetRx,
&softIRQStat.Block, &softIRQStat.BlockIoPoll,
&softIRQStat.Tasklet, &softIRQStat.Sched,
&softIRQStat.Hrtimer, &softIRQStat.Rcu)
if err != nil {
return SoftIRQStat{}, 0, fmt.Errorf("couldn't parse %s (softirq): %s", line, err)
}
return softIRQStat, total, nil
}
// NewStat returns an information about current kernel/system statistics.
func (fs FS) NewStat() (Stat, error) {
// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt
f, err := os.Open(fs.Path("stat"))
if err != nil {
return Stat{}, err
}
defer f.Close()
s := bufio.NewScanner(f)
for s.Scan() {
line := s.Text()
if !strings.HasPrefix(line, "btime") {
stat := Stat{}
scanner := bufio.NewScanner(f)
for scanner.Scan() {
line := scanner.Text()
parts := strings.Fields(scanner.Text())
// require at least <key> <value>
if len(parts) < 2 {
continue
}
fields := strings.Fields(line)
if len(fields) != 2 {
return Stat{}, fmt.Errorf("couldn't parse %s line %s", f.Name(), line)
switch {
case parts[0] == "btime":
if stat.BootTime, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
return Stat{}, fmt.Errorf("couldn't parse %s (btime): %s", parts[1], err)
}
case parts[0] == "intr":
if stat.IRQTotal, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
return Stat{}, fmt.Errorf("couldn't parse %s (intr): %s", parts[1], err)
}
numberedIRQs := parts[2:]
stat.IRQ = make([]uint64, len(numberedIRQs))
for i, count := range numberedIRQs {
if stat.IRQ[i], err = strconv.ParseUint(count, 10, 64); err != nil {
return Stat{}, fmt.Errorf("couldn't parse %s (intr%d): %s", count, i, err)
}
}
case parts[0] == "ctxt":
if stat.ContextSwitches, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
return Stat{}, fmt.Errorf("couldn't parse %s (ctxt): %s", parts[1], err)
}
case parts[0] == "processes":
if stat.ProcessCreated, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
return Stat{}, fmt.Errorf("couldn't parse %s (processes): %s", parts[1], err)
}
case parts[0] == "procs_running":
if stat.ProcessesRunning, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
return Stat{}, fmt.Errorf("couldn't parse %s (procs_running): %s", parts[1], err)
}
case parts[0] == "procs_blocked":
if stat.ProcessesBlocked, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
return Stat{}, fmt.Errorf("couldn't parse %s (procs_blocked): %s", parts[1], err)
}
case parts[0] == "softirq":
softIRQStats, total, err := parseSoftIRQStat(line)
if err != nil {
return Stat{}, err
}
stat.SoftIRQTotal = total
stat.SoftIRQ = softIRQStats
case strings.HasPrefix(parts[0], "cpu"):
cpuStat, cpuID, err := parseCPUStat(line)
if err != nil {
return Stat{}, err
}
if cpuID == -1 {
stat.CPUTotal = cpuStat
} else {
for int64(len(stat.CPU)) <= cpuID {
stat.CPU = append(stat.CPU, CPUStat{})
}
stat.CPU[cpuID] = cpuStat
}
}
i, err := strconv.ParseInt(fields[1], 10, 32)
if err != nil {
return Stat{}, fmt.Errorf("couldn't parse %s: %s", fields[1], err)
}
return Stat{BootTime: i}, nil
}
if err := s.Err(); err != nil {
if err := scanner.Err(); err != nil {
return Stat{}, fmt.Errorf("couldn't parse %s: %s", f.Name(), err)
}
return Stat{}, fmt.Errorf("couldn't parse %s, missing btime", f.Name())
return stat, nil
}

51
vendor/github.com/prometheus/procfs/stat_test.go сгенерированный поставляемый
Просмотреть файл

@@ -8,7 +8,54 @@ func TestStat(t *testing.T) {
t.Fatal(err)
}
if want, have := int64(1418183276), s.BootTime; want != have {
t.Errorf("want boot time %d, have %d", want, have)
// cpu
if want, have := float64(301854)/userHZ, s.CPUTotal.User; want != have {
t.Errorf("want cpu/user %v, have %v", want, have)
}
if want, have := float64(31)/userHZ, s.CPU[7].SoftIRQ; want != have {
t.Errorf("want cpu7/softirq %v, have %v", want, have)
}
// intr
if want, have := uint64(8885917), s.IRQTotal; want != have {
t.Errorf("want irq/total %d, have %d", want, have)
}
if want, have := uint64(1), s.IRQ[8]; want != have {
t.Errorf("want irq8 %d, have %d", want, have)
}
// ctxt
if want, have := uint64(38014093), s.ContextSwitches; want != have {
t.Errorf("want context switches (ctxt) %d, have %d", want, have)
}
// btime
if want, have := uint64(1418183276), s.BootTime; want != have {
t.Errorf("want boot time (btime) %d, have %d", want, have)
}
// processes
if want, have := uint64(26442), s.ProcessCreated; want != have {
t.Errorf("want process created (processes) %d, have %d", want, have)
}
// procs_running
if want, have := uint64(2), s.ProcessesRunning; want != have {
t.Errorf("want processes running (procs_running) %d, have %d", want, have)
}
// procs_blocked
if want, have := uint64(1), s.ProcessesBlocked; want != have {
t.Errorf("want processes blocked (procs_blocked) %d, have %d", want, have)
}
// softirq
if want, have := uint64(5057579), s.SoftIRQTotal; want != have {
t.Errorf("want softirq total %d, have %d", want, have)
}
if want, have := uint64(508444), s.SoftIRQ.Rcu; want != have {
t.Errorf("want softirq RCU %d, have %d", want, have)
}
}

1
vendor/github.com/prometheus/procfs/sysfs/.gitignore сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1 @@
fixtures/

Двоичные данные
vendor/github.com/prometheus/procfs/sysfs/fixtures.tar.gz сгенерированный поставляемый Обычный файл

Двоичный файл не отображается.

1
vendor/github.com/prometheus/procfs/sysfs/fixtures/fs/xfs/sda1/stats/stats сгенерированный поставляемый
Просмотреть файл

@@ -1 +0,0 @@
extent_alloc 1 0 0 0

1
vendor/github.com/prometheus/procfs/sysfs/fixtures/fs/xfs/sdb1/stats/stats сгенерированный поставляемый
Просмотреть файл

@@ -1 +0,0 @@
extent_alloc 2 0 0 0

26
vendor/github.com/prometheus/procfs/sysfs/fs.go сгенерированный поставляемый
Просмотреть файл

@@ -18,6 +18,7 @@ import (
"os"
"path/filepath"
"github.com/prometheus/procfs/bcache"
"github.com/prometheus/procfs/xfs"
)
@@ -80,3 +81,28 @@ func (fs FS) XFSStats() ([]*xfs.Stats, error) {
return stats, nil
}
// BcacheStats retrieves bcache runtime statistics for each bcache.
func (fs FS) BcacheStats() ([]*bcache.Stats, error) {
matches, err := filepath.Glob(fs.Path("fs/bcache/*-*"))
if err != nil {
return nil, err
}
stats := make([]*bcache.Stats, 0, len(matches))
for _, uuidPath := range matches {
// "*-*" in glob above indicates the name of the bcache.
name := filepath.Base(uuidPath)
// stats
s, err := bcache.GetStats(uuidPath)
if err != nil {
return nil, err
}
s.Name = name
stats = append(stats, s)
}
return stats, nil
}

42
vendor/github.com/prometheus/procfs/sysfs/fs_test.go сгенерированный поставляемый
Просмотреть файл

@@ -64,3 +64,45 @@ func TestFSXFSStats(t *testing.T) {
}
}
}
func TestFSBcacheStats(t *testing.T) {
stats, err := FS("fixtures").BcacheStats()
if err != nil {
t.Fatalf("failed to parse bcache stats: %v", err)
}
tests := []struct {
name string
bdevs int
caches int
}{
{
name: "deaddd54-c735-46d5-868e-f331c5fd7c74",
bdevs: 1,
caches: 1,
},
}
const expect = 1
if l := len(stats); l != expect {
t.Fatalf("unexpected number of bcache stats: %d", l)
}
if l := len(tests); l != expect {
t.Fatalf("unexpected number of tests: %d", l)
}
for i, tt := range tests {
if want, got := tt.name, stats[i].Name; want != got {
t.Errorf("unexpected stats name:\nwant: %q\nhave: %q", want, got)
}
if want, got := tt.bdevs, len(stats[i].Bdevs); want != got {
t.Errorf("unexpected value allocated:\nwant: %d\nhave: %d", want, got)
}
if want, got := tt.caches, len(stats[i].Caches); want != got {
t.Errorf("unexpected value allocated:\nwant: %d\nhave: %d", want, got)
}
}
}

187
vendor/github.com/prometheus/procfs/xfrm.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,187 @@
// Copyright 2017 Prometheus Team
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package procfs
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
// XfrmStat models the contents of /proc/net/xfrm_stat.
type XfrmStat struct {
// All errors which are not matched by other
XfrmInError int
// No buffer is left
XfrmInBufferError int
// Header Error
XfrmInHdrError int
// No state found
// i.e. either inbound SPI, address, or IPSEC protocol at SA is wrong
XfrmInNoStates int
// Transformation protocol specific error
// e.g. SA Key is wrong
XfrmInStateProtoError int
// Transformation mode specific error
XfrmInStateModeError int
// Sequence error
// e.g. sequence number is out of window
XfrmInStateSeqError int
// State is expired
XfrmInStateExpired int
// State has mismatch option
// e.g. UDP encapsulation type is mismatched
XfrmInStateMismatch int
// State is invalid
XfrmInStateInvalid int
// No matching template for states
// e.g. Inbound SAs are correct but SP rule is wrong
XfrmInTmplMismatch int
// No policy is found for states
// e.g. Inbound SAs are correct but no SP is found
XfrmInNoPols int
// Policy discards
XfrmInPolBlock int
// Policy error
XfrmInPolError int
// All errors which are not matched by others
XfrmOutError int
// Bundle generation error
XfrmOutBundleGenError int
// Bundle check error
XfrmOutBundleCheckError int
// No state was found
XfrmOutNoStates int
// Transformation protocol specific error
XfrmOutStateProtoError int
// Transportation mode specific error
XfrmOutStateModeError int
// Sequence error
// i.e sequence number overflow
XfrmOutStateSeqError int
// State is expired
XfrmOutStateExpired int
// Policy discads
XfrmOutPolBlock int
// Policy is dead
XfrmOutPolDead int
// Policy Error
XfrmOutPolError int
XfrmFwdHdrError int
XfrmOutStateInvalid int
XfrmAcquireError int
}
// NewXfrmStat reads the xfrm_stat statistics.
func NewXfrmStat() (XfrmStat, error) {
fs, err := NewFS(DefaultMountPoint)
if err != nil {
return XfrmStat{}, err
}
return fs.NewXfrmStat()
}
// NewXfrmStat reads the xfrm_stat statistics from the 'proc' filesystem.
func (fs FS) NewXfrmStat() (XfrmStat, error) {
file, err := os.Open(fs.Path("net/xfrm_stat"))
if err != nil {
return XfrmStat{}, err
}
defer file.Close()
var (
x = XfrmStat{}
s = bufio.NewScanner(file)
)
for s.Scan() {
fields := strings.Fields(s.Text())
if len(fields) != 2 {
return XfrmStat{}, fmt.Errorf(
"couldnt parse %s line %s", file.Name(), s.Text())
}
name := fields[0]
value, err := strconv.Atoi(fields[1])
if err != nil {
return XfrmStat{}, err
}
switch name {
case "XfrmInError":
x.XfrmInError = value
case "XfrmInBufferError":
x.XfrmInBufferError = value
case "XfrmInHdrError":
x.XfrmInHdrError = value
case "XfrmInNoStates":
x.XfrmInNoStates = value
case "XfrmInStateProtoError":
x.XfrmInStateProtoError = value
case "XfrmInStateModeError":
x.XfrmInStateModeError = value
case "XfrmInStateSeqError":
x.XfrmInStateSeqError = value
case "XfrmInStateExpired":
x.XfrmInStateExpired = value
case "XfrmInStateInvalid":
x.XfrmInStateInvalid = value
case "XfrmInTmplMismatch":
x.XfrmInTmplMismatch = value
case "XfrmInNoPols":
x.XfrmInNoPols = value
case "XfrmInPolBlock":
x.XfrmInPolBlock = value
case "XfrmInPolError":
x.XfrmInPolError = value
case "XfrmOutError":
x.XfrmOutError = value
case "XfrmInStateMismatch":
x.XfrmInStateMismatch = value
case "XfrmOutBundleGenError":
x.XfrmOutBundleGenError = value
case "XfrmOutBundleCheckError":
x.XfrmOutBundleCheckError = value
case "XfrmOutNoStates":
x.XfrmOutNoStates = value
case "XfrmOutStateProtoError":
x.XfrmOutStateProtoError = value
case "XfrmOutStateModeError":
x.XfrmOutStateModeError = value
case "XfrmOutStateSeqError":
x.XfrmOutStateSeqError = value
case "XfrmOutStateExpired":
x.XfrmOutStateExpired = value
case "XfrmOutPolBlock":
x.XfrmOutPolBlock = value
case "XfrmOutPolDead":
x.XfrmOutPolDead = value
case "XfrmOutPolError":
x.XfrmOutPolError = value
case "XfrmFwdHdrError":
x.XfrmFwdHdrError = value
case "XfrmOutStateInvalid":
x.XfrmOutStateInvalid = value
case "XfrmAcquireError":
x.XfrmAcquireError = value
}
}
return x, s.Err()
}

66
vendor/github.com/prometheus/procfs/xfrm_test.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,66 @@
// Copyright 2017 Prometheus Team
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package procfs
import (
"testing"
)
func TestXfrmStats(t *testing.T) {
xfrmStats, err := FS("fixtures").NewXfrmStat()
if err != nil {
t.Fatal(err)
}
for _, test := range []struct {
name string
want int
got int
}{
{name: "XfrmInError", want: 1, got: xfrmStats.XfrmInError},
{name: "XfrmInBufferError", want: 2, got: xfrmStats.XfrmInBufferError},
{name: "XfrmInHdrError", want: 4, got: xfrmStats.XfrmInHdrError},
{name: "XfrmInNoStates", want: 3, got: xfrmStats.XfrmInNoStates},
{name: "XfrmInStateProtoError", want: 40, got: xfrmStats.XfrmInStateProtoError},
{name: "XfrmInStateModeError", want: 100, got: xfrmStats.XfrmInStateModeError},
{name: "XfrmInStateSeqError", want: 6000, got: xfrmStats.XfrmInStateSeqError},
{name: "XfrmInStateExpired", want: 4, got: xfrmStats.XfrmInStateExpired},
{name: "XfrmInStateMismatch", want: 23451, got: xfrmStats.XfrmInStateMismatch},
{name: "XfrmInStateInvalid", want: 55555, got: xfrmStats.XfrmInStateInvalid},
{name: "XfrmInTmplMismatch", want: 51, got: xfrmStats.XfrmInTmplMismatch},
{name: "XfrmInNoPols", want: 65432, got: xfrmStats.XfrmInNoPols},
{name: "XfrmInPolBlock", want: 100, got: xfrmStats.XfrmInPolBlock},
{name: "XfrmInPolError", want: 10000, got: xfrmStats.XfrmInPolError},
{name: "XfrmOutError", want: 1000000, got: xfrmStats.XfrmOutError},
{name: "XfrmOutBundleGenError", want: 43321, got: xfrmStats.XfrmOutBundleGenError},
{name: "XfrmOutBundleCheckError", want: 555, got: xfrmStats.XfrmOutBundleCheckError},
{name: "XfrmOutNoStates", want: 869, got: xfrmStats.XfrmOutNoStates},
{name: "XfrmOutStateProtoError", want: 4542, got: xfrmStats.XfrmOutStateProtoError},
{name: "XfrmOutStateModeError", want: 4, got: xfrmStats.XfrmOutStateModeError},
{name: "XfrmOutStateSeqError", want: 543, got: xfrmStats.XfrmOutStateSeqError},
{name: "XfrmOutStateExpired", want: 565, got: xfrmStats.XfrmOutStateExpired},
{name: "XfrmOutPolBlock", want: 43456, got: xfrmStats.XfrmOutPolBlock},
{name: "XfrmOutPolDead", want: 7656, got: xfrmStats.XfrmOutPolDead},
{name: "XfrmOutPolError", want: 1454, got: xfrmStats.XfrmOutPolError},
{name: "XfrmFwdHdrError", want: 6654, got: xfrmStats.XfrmFwdHdrError},
{name: "XfrmOutStateInvaliad", want: 28765, got: xfrmStats.XfrmOutStateInvalid},
{name: "XfrmAcquireError", want: 24532, got: xfrmStats.XfrmAcquireError},
{name: "XfrmInStateInvalid", want: 55555, got: xfrmStats.XfrmInStateInvalid},
{name: "XfrmOutError", want: 1000000, got: xfrmStats.XfrmOutError},
} {
if test.want != test.got {
t.Errorf("Want %s %d, have %d", test.name, test.want, test.got)
}
}
}