Update dependencies
This commit is contained in:
59
vendor/github.com/prometheus/procfs/.golangci.yml
generated
vendored
59
vendor/github.com/prometheus/procfs/.golangci.yml
generated
vendored
@@ -1,12 +1,51 @@
|
||||
---
|
||||
version: "2"
|
||||
linters:
|
||||
enable:
|
||||
- godot
|
||||
- revive
|
||||
|
||||
linter-settings:
|
||||
godot:
|
||||
capital: true
|
||||
exclude:
|
||||
# Ignore "See: URL"
|
||||
- 'See:'
|
||||
- errorlint
|
||||
- forbidigo
|
||||
- gocritic
|
||||
- godot
|
||||
- misspell
|
||||
- revive
|
||||
- testifylint
|
||||
settings:
|
||||
forbidigo:
|
||||
forbid:
|
||||
- pattern: ^fmt\.Print.*$
|
||||
msg: Do not commit print statements.
|
||||
gocritic:
|
||||
enable-all: true
|
||||
disabled-checks:
|
||||
- commentFormatting
|
||||
- commentedOutCode
|
||||
- deferInLoop
|
||||
- filepathJoin
|
||||
- hugeParam
|
||||
- importShadow
|
||||
- paramTypeCombine
|
||||
- rangeValCopy
|
||||
- tooManyResultsChecker
|
||||
- unnamedResult
|
||||
- whyNoLint
|
||||
godot:
|
||||
exclude:
|
||||
# Ignore "See: URL".
|
||||
- 'See:'
|
||||
capital: true
|
||||
misspell:
|
||||
locale: US
|
||||
exclusions:
|
||||
presets:
|
||||
- comments
|
||||
- common-false-positives
|
||||
- legacy
|
||||
- std-error-handling
|
||||
warn-unused: true
|
||||
formatters:
|
||||
enable:
|
||||
- gofmt
|
||||
- goimports
|
||||
settings:
|
||||
goimports:
|
||||
local-prefixes:
|
||||
- github.com/prometheus/procfs
|
||||
|
||||
3
vendor/github.com/prometheus/procfs/MAINTAINERS.md
generated
vendored
3
vendor/github.com/prometheus/procfs/MAINTAINERS.md
generated
vendored
@@ -1,2 +1,3 @@
|
||||
* Johannes 'fish' Ziemke <github@freigeist.org> @discordianfish
|
||||
* Paul Gier <pgier@redhat.com> @pgier
|
||||
* Paul Gier <paulgier@gmail.com> @pgier
|
||||
* Ben Kochie <superq@gmail.com> @SuperQ
|
||||
|
||||
2
vendor/github.com/prometheus/procfs/Makefile
generated
vendored
2
vendor/github.com/prometheus/procfs/Makefile
generated
vendored
@@ -1,4 +1,4 @@
|
||||
# Copyright 2018 The Prometheus Authors
|
||||
# Copyright 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
|
||||
|
||||
59
vendor/github.com/prometheus/procfs/Makefile.common
generated
vendored
59
vendor/github.com/prometheus/procfs/Makefile.common
generated
vendored
@@ -49,23 +49,24 @@ endif
|
||||
GOTEST := $(GO) test
|
||||
GOTEST_DIR :=
|
||||
ifneq ($(CIRCLE_JOB),)
|
||||
ifneq ($(shell which gotestsum),)
|
||||
ifneq ($(shell command -v gotestsum 2> /dev/null),)
|
||||
GOTEST_DIR := test-results
|
||||
GOTEST := gotestsum --junitfile $(GOTEST_DIR)/unit-tests.xml --
|
||||
endif
|
||||
endif
|
||||
|
||||
PROMU_VERSION ?= 0.14.0
|
||||
PROMU_VERSION ?= 0.17.0
|
||||
PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz
|
||||
|
||||
SKIP_GOLANGCI_LINT :=
|
||||
GOLANGCI_LINT :=
|
||||
GOLANGCI_LINT_OPTS ?=
|
||||
GOLANGCI_LINT_VERSION ?= v1.49.0
|
||||
# golangci-lint only supports linux, darwin and windows platforms on i386/amd64.
|
||||
GOLANGCI_LINT_VERSION ?= v2.1.5
|
||||
GOLANGCI_FMT_OPTS ?=
|
||||
# golangci-lint only supports linux, darwin and windows platforms on i386/amd64/arm64.
|
||||
# windows isn't included here because of the path separator being different.
|
||||
ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin))
|
||||
ifeq ($(GOHOSTARCH),$(filter $(GOHOSTARCH),amd64 i386))
|
||||
ifeq ($(GOHOSTARCH),$(filter $(GOHOSTARCH),amd64 i386 arm64))
|
||||
# If we're in CI and there is an Actions file, that means the linter
|
||||
# is being run in Actions, so we don't need to run it here.
|
||||
ifneq (,$(SKIP_GOLANGCI_LINT))
|
||||
@@ -91,6 +92,8 @@ BUILD_DOCKER_ARCHS = $(addprefix common-docker-,$(DOCKER_ARCHS))
|
||||
PUBLISH_DOCKER_ARCHS = $(addprefix common-docker-publish-,$(DOCKER_ARCHS))
|
||||
TAG_DOCKER_ARCHS = $(addprefix common-docker-tag-latest-,$(DOCKER_ARCHS))
|
||||
|
||||
SANITIZED_DOCKER_IMAGE_TAG := $(subst +,-,$(DOCKER_IMAGE_TAG))
|
||||
|
||||
ifeq ($(GOHOSTARCH),amd64)
|
||||
ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux freebsd darwin windows))
|
||||
# Only supported on amd64
|
||||
@@ -136,7 +139,7 @@ common-deps:
|
||||
update-go-deps:
|
||||
@echo ">> updating Go dependencies"
|
||||
@for m in $$($(GO) list -mod=readonly -m -f '{{ if and (not .Indirect) (not .Main)}}{{.Path}}{{end}}' all); do \
|
||||
$(GO) get -d $$m; \
|
||||
$(GO) get $$m; \
|
||||
done
|
||||
$(GO) mod tidy
|
||||
|
||||
@@ -154,9 +157,13 @@ $(GOTEST_DIR):
|
||||
@mkdir -p $@
|
||||
|
||||
.PHONY: common-format
|
||||
common-format:
|
||||
common-format: $(GOLANGCI_LINT)
|
||||
@echo ">> formatting code"
|
||||
$(GO) fmt $(pkgs)
|
||||
ifdef GOLANGCI_LINT
|
||||
@echo ">> formatting code with golangci-lint"
|
||||
$(GOLANGCI_LINT) fmt $(GOLANGCI_FMT_OPTS)
|
||||
endif
|
||||
|
||||
.PHONY: common-vet
|
||||
common-vet:
|
||||
@@ -167,16 +174,20 @@ common-vet:
|
||||
common-lint: $(GOLANGCI_LINT)
|
||||
ifdef GOLANGCI_LINT
|
||||
@echo ">> running golangci-lint"
|
||||
# 'go list' needs to be executed before staticcheck to prepopulate the modules cache.
|
||||
# Otherwise staticcheck might fail randomly for some reason not yet explained.
|
||||
$(GO) list -e -compiled -test=true -export=false -deps=true -find=false -tags= -- ./... > /dev/null
|
||||
$(GOLANGCI_LINT) run $(GOLANGCI_LINT_OPTS) $(pkgs)
|
||||
endif
|
||||
|
||||
.PHONY: common-lint-fix
|
||||
common-lint-fix: $(GOLANGCI_LINT)
|
||||
ifdef GOLANGCI_LINT
|
||||
@echo ">> running golangci-lint fix"
|
||||
$(GOLANGCI_LINT) run --fix $(GOLANGCI_LINT_OPTS) $(pkgs)
|
||||
endif
|
||||
|
||||
.PHONY: common-yamllint
|
||||
common-yamllint:
|
||||
@echo ">> running yamllint on all YAML files in the repository"
|
||||
ifeq (, $(shell which yamllint))
|
||||
ifeq (, $(shell command -v yamllint 2> /dev/null))
|
||||
@echo "yamllint not installed so skipping"
|
||||
else
|
||||
yamllint .
|
||||
@@ -202,10 +213,14 @@ common-tarball: promu
|
||||
@echo ">> building release tarball"
|
||||
$(PROMU) tarball --prefix $(PREFIX) $(BIN_DIR)
|
||||
|
||||
.PHONY: common-docker-repo-name
|
||||
common-docker-repo-name:
|
||||
@echo "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)"
|
||||
|
||||
.PHONY: common-docker $(BUILD_DOCKER_ARCHS)
|
||||
common-docker: $(BUILD_DOCKER_ARCHS)
|
||||
$(BUILD_DOCKER_ARCHS): common-docker-%:
|
||||
docker build -t "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" \
|
||||
docker build -t "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" \
|
||||
-f $(DOCKERFILE_PATH) \
|
||||
--build-arg ARCH="$*" \
|
||||
--build-arg OS="linux" \
|
||||
@@ -214,19 +229,19 @@ $(BUILD_DOCKER_ARCHS): common-docker-%:
|
||||
.PHONY: common-docker-publish $(PUBLISH_DOCKER_ARCHS)
|
||||
common-docker-publish: $(PUBLISH_DOCKER_ARCHS)
|
||||
$(PUBLISH_DOCKER_ARCHS): common-docker-publish-%:
|
||||
docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)"
|
||||
docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)"
|
||||
|
||||
DOCKER_MAJOR_VERSION_TAG = $(firstword $(subst ., ,$(shell cat VERSION)))
|
||||
.PHONY: common-docker-tag-latest $(TAG_DOCKER_ARCHS)
|
||||
common-docker-tag-latest: $(TAG_DOCKER_ARCHS)
|
||||
$(TAG_DOCKER_ARCHS): common-docker-tag-latest-%:
|
||||
docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest"
|
||||
docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)"
|
||||
docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest"
|
||||
docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)"
|
||||
|
||||
.PHONY: common-docker-manifest
|
||||
common-docker-manifest:
|
||||
DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG)" $(foreach ARCH,$(DOCKER_ARCHS),$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$(ARCH):$(DOCKER_IMAGE_TAG))
|
||||
DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG)"
|
||||
DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)" $(foreach ARCH,$(DOCKER_ARCHS),$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$(ARCH):$(SANITIZED_DOCKER_IMAGE_TAG))
|
||||
DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)"
|
||||
|
||||
.PHONY: promu
|
||||
promu: $(PROMU)
|
||||
@@ -238,8 +253,8 @@ $(PROMU):
|
||||
cp $(PROMU_TMP)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM)/promu $(FIRST_GOPATH)/bin/promu
|
||||
rm -r $(PROMU_TMP)
|
||||
|
||||
.PHONY: proto
|
||||
proto:
|
||||
.PHONY: common-proto
|
||||
common-proto:
|
||||
@echo ">> generating code from proto files"
|
||||
@./scripts/genproto.sh
|
||||
|
||||
@@ -265,3 +280,9 @@ $(1)_precheck:
|
||||
exit 1; \
|
||||
fi
|
||||
endef
|
||||
|
||||
govulncheck: install-govulncheck
|
||||
govulncheck ./...
|
||||
|
||||
install-govulncheck:
|
||||
command -v govulncheck > /dev/null || go install golang.org/x/vuln/cmd/govulncheck@latest
|
||||
|
||||
10
vendor/github.com/prometheus/procfs/README.md
generated
vendored
10
vendor/github.com/prometheus/procfs/README.md
generated
vendored
@@ -47,15 +47,15 @@ However, most of the API includes unit tests which can be run with `make test`.
|
||||
The procfs library includes a set of test fixtures which include many example files from
|
||||
the `/proc` and `/sys` filesystems. These fixtures are included as a [ttar](https://github.com/ideaship/ttar) file
|
||||
which is extracted automatically during testing. To add/update the test fixtures, first
|
||||
ensure the `fixtures` directory is up to date by removing the existing directory and then
|
||||
extracting the ttar file using `make fixtures/.unpacked` or just `make test`.
|
||||
ensure the `testdata/fixtures` directory is up to date by removing the existing directory and then
|
||||
extracting the ttar file using `make testdata/fixtures/.unpacked` or just `make test`.
|
||||
|
||||
```bash
|
||||
rm -rf fixtures
|
||||
rm -rf testdata/fixtures
|
||||
make test
|
||||
```
|
||||
|
||||
Next, make the required changes to the extracted files in the `fixtures` directory. When
|
||||
Next, make the required changes to the extracted files in the `testdata/fixtures` directory. When
|
||||
the changes are complete, run `make update_fixtures` to create a new `fixtures.ttar` file
|
||||
based on the updated `fixtures` directory. And finally, verify the changes using
|
||||
`git diff fixtures.ttar`.
|
||||
`git diff testdata/fixtures.ttar`.
|
||||
|
||||
19
vendor/github.com/prometheus/procfs/arp.go
generated
vendored
19
vendor/github.com/prometheus/procfs/arp.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -23,9 +23,9 @@ import (
|
||||
|
||||
// Learned from include/uapi/linux/if_arp.h.
|
||||
const (
|
||||
// completed entry (ha valid).
|
||||
// Completed entry (ha valid).
|
||||
ATFComplete = 0x02
|
||||
// permanent entry.
|
||||
// Permanent entry.
|
||||
ATFPermanent = 0x04
|
||||
// Publish entry.
|
||||
ATFPublish = 0x08
|
||||
@@ -55,7 +55,7 @@ type ARPEntry struct {
|
||||
func (fs FS) GatherARPEntries() ([]ARPEntry, error) {
|
||||
data, err := os.ReadFile(fs.proc.Path("net/arp"))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading arp %q: %w", fs.proc.Path("net/arp"), err)
|
||||
return nil, fmt.Errorf("%w: error reading arp %s: %w", ErrFileRead, fs.proc.Path("net/arp"), err)
|
||||
}
|
||||
|
||||
return parseARPEntries(data)
|
||||
@@ -73,16 +73,17 @@ func parseARPEntries(data []byte) ([]ARPEntry, error) {
|
||||
columns := strings.Fields(line)
|
||||
width := len(columns)
|
||||
|
||||
if width == expectedHeaderWidth || width == 0 {
|
||||
switch width {
|
||||
case expectedHeaderWidth, 0:
|
||||
continue
|
||||
} else if width == expectedDataWidth {
|
||||
case expectedDataWidth:
|
||||
entry, err := parseARPEntry(columns)
|
||||
if err != nil {
|
||||
return []ARPEntry{}, fmt.Errorf("failed to parse ARP entry: %w", err)
|
||||
return []ARPEntry{}, fmt.Errorf("%w: Failed to parse ARP entry: %v: %w", ErrFileParse, entry, err)
|
||||
}
|
||||
entries = append(entries, entry)
|
||||
} else {
|
||||
return []ARPEntry{}, fmt.Errorf("%d columns were detected, but %d were expected", width, expectedDataWidth)
|
||||
default:
|
||||
return []ARPEntry{}, fmt.Errorf("%w: %d columns found, but expected %d: %w", ErrFileParse, width, expectedDataWidth, err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
18
vendor/github.com/prometheus/procfs/buddyinfo.go
generated
vendored
18
vendor/github.com/prometheus/procfs/buddyinfo.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2017 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -55,26 +55,24 @@ func parseBuddyInfo(r io.Reader) ([]BuddyInfo, error) {
|
||||
parts := strings.Fields(line)
|
||||
|
||||
if len(parts) < 4 {
|
||||
return nil, fmt.Errorf("invalid number of fields when parsing buddyinfo")
|
||||
return nil, fmt.Errorf("%w: Invalid number of fields, found: %v", ErrFileParse, parts)
|
||||
}
|
||||
|
||||
node := strings.TrimRight(parts[1], ",")
|
||||
zone := strings.TrimRight(parts[3], ",")
|
||||
node := strings.TrimSuffix(parts[1], ",")
|
||||
zone := strings.TrimSuffix(parts[3], ",")
|
||||
arraySize := len(parts[4:])
|
||||
|
||||
if bucketCount == -1 {
|
||||
bucketCount = arraySize
|
||||
} else {
|
||||
if bucketCount != arraySize {
|
||||
return nil, fmt.Errorf("mismatch in number of buddyinfo buckets, previous count %d, new count %d", bucketCount, arraySize)
|
||||
}
|
||||
} else if bucketCount != arraySize {
|
||||
return nil, fmt.Errorf("%w: mismatch in number of buddyinfo buckets, previous count %d, new count %d", ErrFileParse, bucketCount, arraySize)
|
||||
}
|
||||
|
||||
sizes := make([]float64, arraySize)
|
||||
for i := 0; i < arraySize; i++ {
|
||||
for i := range arraySize {
|
||||
sizes[i], err = strconv.ParseFloat(parts[i+4], 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid value in buddyinfo: %w", err)
|
||||
return nil, fmt.Errorf("%w: Invalid valid in buddyinfo: %f: %w", ErrFileParse, sizes[i], err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2
vendor/github.com/prometheus/procfs/cmdline.go
generated
vendored
2
vendor/github.com/prometheus/procfs/cmdline.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 The Prometheus Authors
|
||||
// Copyright 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
|
||||
|
||||
21
vendor/github.com/prometheus/procfs/cpuinfo.go
generated
vendored
21
vendor/github.com/prometheus/procfs/cpuinfo.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -79,7 +79,7 @@ func parseCPUInfoX86(info []byte) ([]CPUInfo, error) {
|
||||
// find the first "processor" line
|
||||
firstLine := firstNonEmptyLine(scanner)
|
||||
if !strings.HasPrefix(firstLine, "processor") || !strings.Contains(firstLine, ":") {
|
||||
return nil, fmt.Errorf("invalid cpuinfo file: %q", firstLine)
|
||||
return nil, fmt.Errorf("%w: Cannot parse line: %q", ErrFileParse, firstLine)
|
||||
}
|
||||
field := strings.SplitN(firstLine, ": ", 2)
|
||||
v, err := strconv.ParseUint(field[1], 0, 32)
|
||||
@@ -192,9 +192,10 @@ func parseCPUInfoARM(info []byte) ([]CPUInfo, error) {
|
||||
scanner := bufio.NewScanner(bytes.NewReader(info))
|
||||
|
||||
firstLine := firstNonEmptyLine(scanner)
|
||||
match, _ := regexp.MatchString("^[Pp]rocessor", firstLine)
|
||||
match, err := regexp.MatchString("^[Pp]rocessor", firstLine)
|
||||
if !match || !strings.Contains(firstLine, ":") {
|
||||
return nil, fmt.Errorf("invalid cpuinfo file: %q", firstLine)
|
||||
return nil, fmt.Errorf("%w: Cannot parse line: %q: %w", ErrFileParse, firstLine, err)
|
||||
|
||||
}
|
||||
field := strings.SplitN(firstLine, ": ", 2)
|
||||
cpuinfo := []CPUInfo{}
|
||||
@@ -258,7 +259,7 @@ func parseCPUInfoS390X(info []byte) ([]CPUInfo, error) {
|
||||
|
||||
firstLine := firstNonEmptyLine(scanner)
|
||||
if !strings.HasPrefix(firstLine, "vendor_id") || !strings.Contains(firstLine, ":") {
|
||||
return nil, fmt.Errorf("invalid cpuinfo file: %q", firstLine)
|
||||
return nil, fmt.Errorf("%w: Cannot parse line: %q", ErrFileParse, firstLine)
|
||||
}
|
||||
field := strings.SplitN(firstLine, ": ", 2)
|
||||
cpuinfo := []CPUInfo{}
|
||||
@@ -283,7 +284,7 @@ func parseCPUInfoS390X(info []byte) ([]CPUInfo, error) {
|
||||
if strings.HasPrefix(line, "processor") {
|
||||
match := cpuinfoS390XProcessorRegexp.FindStringSubmatch(line)
|
||||
if len(match) < 2 {
|
||||
return nil, fmt.Errorf("invalid cpuinfo file: %q", firstLine)
|
||||
return nil, fmt.Errorf("%w: %q", ErrFileParse, firstLine)
|
||||
}
|
||||
cpu := commonCPUInfo
|
||||
v, err := strconv.ParseUint(match[1], 0, 32)
|
||||
@@ -343,7 +344,7 @@ func parseCPUInfoMips(info []byte) ([]CPUInfo, error) {
|
||||
// find the first "processor" line
|
||||
firstLine := firstNonEmptyLine(scanner)
|
||||
if !strings.HasPrefix(firstLine, "system type") || !strings.Contains(firstLine, ":") {
|
||||
return nil, fmt.Errorf("invalid cpuinfo file: %q", firstLine)
|
||||
return nil, fmt.Errorf("%w: %q", ErrFileParse, firstLine)
|
||||
}
|
||||
field := strings.SplitN(firstLine, ": ", 2)
|
||||
cpuinfo := []CPUInfo{}
|
||||
@@ -385,7 +386,7 @@ func parseCPUInfoLoong(info []byte) ([]CPUInfo, error) {
|
||||
// find the first "processor" line
|
||||
firstLine := firstNonEmptyLine(scanner)
|
||||
if !strings.HasPrefix(firstLine, "system type") || !strings.Contains(firstLine, ":") {
|
||||
return nil, errors.New("invalid cpuinfo file: " + firstLine)
|
||||
return nil, fmt.Errorf("%w: %q", ErrFileParse, firstLine)
|
||||
}
|
||||
field := strings.SplitN(firstLine, ": ", 2)
|
||||
cpuinfo := []CPUInfo{}
|
||||
@@ -421,7 +422,7 @@ func parseCPUInfoPPC(info []byte) ([]CPUInfo, error) {
|
||||
|
||||
firstLine := firstNonEmptyLine(scanner)
|
||||
if !strings.HasPrefix(firstLine, "processor") || !strings.Contains(firstLine, ":") {
|
||||
return nil, fmt.Errorf("invalid cpuinfo file: %q", firstLine)
|
||||
return nil, fmt.Errorf("%w: %q", ErrFileParse, firstLine)
|
||||
}
|
||||
field := strings.SplitN(firstLine, ": ", 2)
|
||||
v, err := strconv.ParseUint(field[1], 0, 32)
|
||||
@@ -466,7 +467,7 @@ func parseCPUInfoRISCV(info []byte) ([]CPUInfo, error) {
|
||||
|
||||
firstLine := firstNonEmptyLine(scanner)
|
||||
if !strings.HasPrefix(firstLine, "processor") || !strings.Contains(firstLine, ":") {
|
||||
return nil, fmt.Errorf("invalid cpuinfo file: %q", firstLine)
|
||||
return nil, fmt.Errorf("%w: %q", ErrFileParse, firstLine)
|
||||
}
|
||||
field := strings.SplitN(firstLine, ": ", 2)
|
||||
v, err := strconv.ParseUint(field[1], 0, 32)
|
||||
|
||||
2
vendor/github.com/prometheus/procfs/cpuinfo_armx.go
generated
vendored
2
vendor/github.com/prometheus/procfs/cpuinfo_armx.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020 The Prometheus Authors
|
||||
// Copyright 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
|
||||
|
||||
2
vendor/github.com/prometheus/procfs/cpuinfo_loong64.go
generated
vendored
2
vendor/github.com/prometheus/procfs/cpuinfo_loong64.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 The Prometheus Authors
|
||||
// Copyright 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
|
||||
|
||||
2
vendor/github.com/prometheus/procfs/cpuinfo_mipsx.go
generated
vendored
2
vendor/github.com/prometheus/procfs/cpuinfo_mipsx.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020 The Prometheus Authors
|
||||
// Copyright 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
|
||||
|
||||
2
vendor/github.com/prometheus/procfs/cpuinfo_others.go
generated
vendored
2
vendor/github.com/prometheus/procfs/cpuinfo_others.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020 The Prometheus Authors
|
||||
// Copyright 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
|
||||
|
||||
2
vendor/github.com/prometheus/procfs/cpuinfo_ppcx.go
generated
vendored
2
vendor/github.com/prometheus/procfs/cpuinfo_ppcx.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020 The Prometheus Authors
|
||||
// Copyright 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
|
||||
|
||||
2
vendor/github.com/prometheus/procfs/cpuinfo_riscvx.go
generated
vendored
2
vendor/github.com/prometheus/procfs/cpuinfo_riscvx.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020 The Prometheus Authors
|
||||
// Copyright 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
|
||||
|
||||
2
vendor/github.com/prometheus/procfs/cpuinfo_s390x.go
generated
vendored
2
vendor/github.com/prometheus/procfs/cpuinfo_s390x.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020 The Prometheus Authors
|
||||
// Copyright 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
|
||||
|
||||
2
vendor/github.com/prometheus/procfs/cpuinfo_x86.go
generated
vendored
2
vendor/github.com/prometheus/procfs/cpuinfo_x86.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020 The Prometheus Authors
|
||||
// Copyright 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
|
||||
|
||||
9
vendor/github.com/prometheus/procfs/crypto.go
generated
vendored
9
vendor/github.com/prometheus/procfs/crypto.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -55,12 +55,13 @@ func (fs FS) Crypto() ([]Crypto, error) {
|
||||
path := fs.proc.Path("crypto")
|
||||
b, err := util.ReadFileNoStat(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading crypto %q: %w", path, err)
|
||||
return nil, fmt.Errorf("%w: Cannot read file %v: %w", ErrFileRead, b, err)
|
||||
|
||||
}
|
||||
|
||||
crypto, err := parseCrypto(bytes.NewReader(b))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing crypto %q: %w", path, err)
|
||||
return nil, fmt.Errorf("%w: Cannot parse %v: %w", ErrFileParse, crypto, err)
|
||||
}
|
||||
|
||||
return crypto, nil
|
||||
@@ -83,7 +84,7 @@ func parseCrypto(r io.Reader) ([]Crypto, error) {
|
||||
|
||||
kv := strings.Split(text, ":")
|
||||
if len(kv) != 2 {
|
||||
return nil, fmt.Errorf("malformed crypto line: %q", text)
|
||||
return nil, fmt.Errorf("%w: Cannot parse line: %q", ErrFileParse, text)
|
||||
}
|
||||
|
||||
k := strings.TrimSpace(kv[0])
|
||||
|
||||
2
vendor/github.com/prometheus/procfs/doc.go
generated
vendored
2
vendor/github.com/prometheus/procfs/doc.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2014 Prometheus Team
|
||||
// Copyright 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
|
||||
|
||||
23
vendor/github.com/prometheus/procfs/fs.go
generated
vendored
23
vendor/github.com/prometheus/procfs/fs.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2018 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -20,11 +20,18 @@ import (
|
||||
// FS represents the pseudo-filesystem sys, which provides an interface to
|
||||
// kernel data structures.
|
||||
type FS struct {
|
||||
proc fs.FS
|
||||
proc fs.FS
|
||||
isReal bool
|
||||
}
|
||||
|
||||
// DefaultMountPoint is the common mount point of the proc filesystem.
|
||||
const DefaultMountPoint = fs.DefaultProcMountPoint
|
||||
const (
|
||||
// DefaultMountPoint is the common mount point of the proc filesystem.
|
||||
DefaultMountPoint = fs.DefaultProcMountPoint
|
||||
|
||||
// SectorSize represents the size of a sector in bytes.
|
||||
// It is specific to Linux block I/O operations.
|
||||
SectorSize = 512
|
||||
)
|
||||
|
||||
// NewDefaultFS returns a new proc FS mounted under the default proc mountPoint.
|
||||
// It will error if the mount point directory can't be read or is a file.
|
||||
@@ -39,5 +46,11 @@ func NewFS(mountPoint string) (FS, error) {
|
||||
if err != nil {
|
||||
return FS{}, err
|
||||
}
|
||||
return FS{fs}, nil
|
||||
|
||||
isReal, err := isRealProc(mountPoint)
|
||||
if err != nil {
|
||||
return FS{}, err
|
||||
}
|
||||
|
||||
return FS{fs, isReal}, nil
|
||||
}
|
||||
|
||||
23
vendor/github.com/prometheus/procfs/fs_statfs_notype.go
generated
vendored
Normal file
23
vendor/github.com/prometheus/procfs/fs_statfs_notype.go
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 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.
|
||||
|
||||
//go:build !freebsd && !linux
|
||||
// +build !freebsd,!linux
|
||||
|
||||
package procfs
|
||||
|
||||
// isRealProc returns true on architectures that don't have a Type argument
|
||||
// in their Statfs_t struct.
|
||||
func isRealProc(_ string) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
33
vendor/github.com/prometheus/procfs/fs_statfs_type.go
generated
vendored
Normal file
33
vendor/github.com/prometheus/procfs/fs_statfs_type.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright 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.
|
||||
|
||||
//go:build freebsd || linux
|
||||
// +build freebsd linux
|
||||
|
||||
package procfs
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// isRealProc determines whether supplied mountpoint is really a proc filesystem.
|
||||
func isRealProc(mountPoint string) (bool, error) {
|
||||
stat := syscall.Statfs_t{}
|
||||
err := syscall.Statfs(mountPoint, &stat)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// 0x9fa0 is PROC_SUPER_MAGIC: https://elixir.bootlin.com/linux/v6.1/source/include/uapi/linux/magic.h#L87
|
||||
return stat.Type == 0x9fa0, nil
|
||||
}
|
||||
21
vendor/github.com/prometheus/procfs/fscache.go
generated
vendored
21
vendor/github.com/prometheus/procfs/fscache.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -162,7 +162,7 @@ type Fscacheinfo struct {
|
||||
ReleaseRequestsAgainstPagesStoredByTimeLockGranted uint64
|
||||
// Number of release reqs ignored due to in-progress store
|
||||
ReleaseRequestsIgnoredDueToInProgressStore uint64
|
||||
// Number of page stores cancelled due to release req
|
||||
// Number of page stores canceled due to release req
|
||||
PageStoresCancelledByReleaseRequests uint64
|
||||
VmscanWaiting uint64
|
||||
// Number of times async ops added to pending queues
|
||||
@@ -171,11 +171,11 @@ type Fscacheinfo struct {
|
||||
OpsRunning uint64
|
||||
// Number of times async ops queued for processing
|
||||
OpsEnqueued uint64
|
||||
// Number of async ops cancelled
|
||||
// Number of async ops canceled
|
||||
OpsCancelled uint64
|
||||
// Number of async ops rejected due to object lookup/create failure
|
||||
OpsRejected uint64
|
||||
// Number of async ops initialised
|
||||
// Number of async ops initialized
|
||||
OpsInitialised uint64
|
||||
// Number of async ops queued for deferred release
|
||||
OpsDeferred uint64
|
||||
@@ -236,7 +236,7 @@ func (fs FS) Fscacheinfo() (Fscacheinfo, error) {
|
||||
|
||||
m, err := parseFscacheinfo(bytes.NewReader(b))
|
||||
if err != nil {
|
||||
return Fscacheinfo{}, fmt.Errorf("failed to parse Fscacheinfo: %w", err)
|
||||
return Fscacheinfo{}, fmt.Errorf("%w: Cannot parse %v: %w", ErrFileParse, m, err)
|
||||
}
|
||||
|
||||
return *m, nil
|
||||
@@ -245,7 +245,7 @@ func (fs FS) Fscacheinfo() (Fscacheinfo, error) {
|
||||
func setFSCacheFields(fields []string, setFields ...*uint64) error {
|
||||
var err error
|
||||
if len(fields) < len(setFields) {
|
||||
return fmt.Errorf("Insufficient number of fields, expected %v, got %v", len(setFields), len(fields))
|
||||
return fmt.Errorf("%w: Expected %d, but got %d: %w", ErrFileParse, len(setFields), len(fields), err)
|
||||
}
|
||||
|
||||
for i := range setFields {
|
||||
@@ -263,7 +263,7 @@ func parseFscacheinfo(r io.Reader) (*Fscacheinfo, error) {
|
||||
for s.Scan() {
|
||||
fields := strings.Fields(s.Text())
|
||||
if len(fields) < 2 {
|
||||
return nil, fmt.Errorf("malformed Fscacheinfo line: %q", s.Text())
|
||||
return nil, fmt.Errorf("%w: malformed Fscacheinfo line: %q", ErrFileParse, s.Text())
|
||||
}
|
||||
|
||||
switch fields[0] {
|
||||
@@ -388,20 +388,21 @@ func parseFscacheinfo(r io.Reader) (*Fscacheinfo, error) {
|
||||
}
|
||||
}
|
||||
case "CacheOp:":
|
||||
if strings.Split(fields[1], "=")[0] == "alo" {
|
||||
switch strings.Split(fields[1], "=")[0] {
|
||||
case "alo":
|
||||
err := setFSCacheFields(fields[1:], &m.CacheopAllocationsinProgress, &m.CacheopLookupObjectInProgress,
|
||||
&m.CacheopLookupCompleteInPorgress, &m.CacheopGrabObjectInProgress)
|
||||
if err != nil {
|
||||
return &m, err
|
||||
}
|
||||
} else if strings.Split(fields[1], "=")[0] == "inv" {
|
||||
case "inv":
|
||||
err := setFSCacheFields(fields[1:], &m.CacheopInvalidations, &m.CacheopUpdateObjectInProgress,
|
||||
&m.CacheopDropObjectInProgress, &m.CacheopPutObjectInProgress, &m.CacheopAttributeChangeInProgress,
|
||||
&m.CacheopSyncCacheInProgress)
|
||||
if err != nil {
|
||||
return &m, err
|
||||
}
|
||||
} else {
|
||||
default:
|
||||
err := setFSCacheFields(fields[1:], &m.CacheopReadOrAllocPageInProgress, &m.CacheopReadOrAllocPagesInProgress,
|
||||
&m.CacheopAllocatePageInProgress, &m.CacheopAllocatePagesInProgress, &m.CacheopWritePagesInProgress,
|
||||
&m.CacheopUncachePagesInProgress, &m.CacheopDissociatePagesInProgress)
|
||||
|
||||
5
vendor/github.com/prometheus/procfs/internal/fs/fs.go
generated
vendored
5
vendor/github.com/prometheus/procfs/internal/fs/fs.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -28,6 +28,9 @@ const (
|
||||
|
||||
// DefaultConfigfsMountPoint is the common mount point of the configfs.
|
||||
DefaultConfigfsMountPoint = "/sys/kernel/config"
|
||||
|
||||
// DefaultSelinuxMountPoint is the common mount point of the selinuxfs.
|
||||
DefaultSelinuxMountPoint = "/sys/fs/selinux"
|
||||
)
|
||||
|
||||
// FS represents a pseudo-filesystem, normally /proc or /sys, which provides an
|
||||
|
||||
31
vendor/github.com/prometheus/procfs/internal/util/parse.go
generated
vendored
31
vendor/github.com/prometheus/procfs/internal/util/parse.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2018 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -14,6 +14,7 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -64,6 +65,21 @@ func ParsePInt64s(ss []string) ([]*int64, error) {
|
||||
return us, nil
|
||||
}
|
||||
|
||||
// Parses a uint64 from given hex in string.
|
||||
func ParseHexUint64s(ss []string) ([]*uint64, error) {
|
||||
us := make([]*uint64, 0, len(ss))
|
||||
for _, s := range ss {
|
||||
u, err := strconv.ParseUint(s, 16, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
us = append(us, &u)
|
||||
}
|
||||
|
||||
return us, nil
|
||||
}
|
||||
|
||||
// ReadUintFromFile reads a file and attempts to parse a uint64 from it.
|
||||
func ReadUintFromFile(path string) (uint64, error) {
|
||||
data, err := os.ReadFile(path)
|
||||
@@ -95,3 +111,16 @@ func ParseBool(b string) *bool {
|
||||
}
|
||||
return &truth
|
||||
}
|
||||
|
||||
// ReadHexFromFile reads a file and attempts to parse a uint64 from a hexadecimal format 0xXX.
|
||||
func ReadHexFromFile(path string) (uint64, error) {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
hexString := strings.TrimSpace(string(data))
|
||||
if !strings.HasPrefix(hexString, "0x") {
|
||||
return 0, errors.New("invalid format: hex string does not start with '0x'")
|
||||
}
|
||||
return strconv.ParseUint(hexString[2:], 16, 64)
|
||||
}
|
||||
|
||||
2
vendor/github.com/prometheus/procfs/internal/util/readfile.go
generated
vendored
2
vendor/github.com/prometheus/procfs/internal/util/readfile.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019 The Prometheus Authors
|
||||
// Copyright 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
|
||||
|
||||
22
vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go
generated
vendored
22
vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2018 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -20,6 +20,8 @@ package util
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
@@ -48,3 +50,21 @@ func SysReadFile(file string) (string, error) {
|
||||
|
||||
return string(bytes.TrimSpace(b[:n])), nil
|
||||
}
|
||||
|
||||
// SysReadUintFromFile reads a file using SysReadFile and attempts to parse a uint64 from it.
|
||||
func SysReadUintFromFile(path string) (uint64, error) {
|
||||
data, err := SysReadFile(path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64)
|
||||
}
|
||||
|
||||
// SysReadIntFromFile reads a file using SysReadFile and attempts to parse a int64 from it.
|
||||
func SysReadIntFromFile(path string) (int64, error) {
|
||||
data, err := SysReadFile(path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return strconv.ParseInt(strings.TrimSpace(string(data)), 10, 64)
|
||||
}
|
||||
|
||||
2
vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go
generated
vendored
2
vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019 The Prometheus Authors
|
||||
// Copyright 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
|
||||
|
||||
2
vendor/github.com/prometheus/procfs/internal/util/valueparser.go
generated
vendored
2
vendor/github.com/prometheus/procfs/internal/util/valueparser.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019 The Prometheus Authors
|
||||
// Copyright 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
|
||||
|
||||
9
vendor/github.com/prometheus/procfs/ipvs.go
generated
vendored
9
vendor/github.com/prometheus/procfs/ipvs.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2018 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -221,15 +221,16 @@ func parseIPPort(s string) (net.IP, uint16, error) {
|
||||
case 46:
|
||||
ip = net.ParseIP(s[1:40])
|
||||
if ip == nil {
|
||||
return nil, 0, fmt.Errorf("invalid IPv6 address: %s", s[1:40])
|
||||
return nil, 0, fmt.Errorf("%w: Invalid IPv6 addr %s: %w", ErrFileParse, s[1:40], err)
|
||||
}
|
||||
default:
|
||||
return nil, 0, fmt.Errorf("unexpected IP:Port: %s", s)
|
||||
return nil, 0, fmt.Errorf("%w: Unexpected IP:Port %s: %w", ErrFileParse, s, err)
|
||||
}
|
||||
|
||||
portString := s[len(s)-4:]
|
||||
if len(portString) != 4 {
|
||||
return nil, 0, fmt.Errorf("unexpected port string format: %s", portString)
|
||||
return nil, 0,
|
||||
fmt.Errorf("%w: Unexpected port string format %s: %w", ErrFileParse, portString, err)
|
||||
}
|
||||
port, err := strconv.ParseUint(portString, 16, 16)
|
||||
if err != nil {
|
||||
|
||||
45
vendor/github.com/prometheus/procfs/kernel_hung.go
generated
vendored
Normal file
45
vendor/github.com/prometheus/procfs/kernel_hung.go
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright 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.
|
||||
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package procfs
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// KernelHung contains information about to the kernel's hung_task_detect_count number.
|
||||
type KernelHung struct {
|
||||
// Indicates the total number of tasks that have been detected as hung since the system boot.
|
||||
// This file shows up if `CONFIG_DETECT_HUNG_TASK` is enabled.
|
||||
HungTaskDetectCount *uint64
|
||||
}
|
||||
|
||||
// KernelHung returns values from /proc/sys/kernel/hung_task_detect_count.
|
||||
func (fs FS) KernelHung() (KernelHung, error) {
|
||||
data, err := os.ReadFile(fs.proc.Path("sys", "kernel", "hung_task_detect_count"))
|
||||
if err != nil {
|
||||
return KernelHung{}, err
|
||||
}
|
||||
val, err := strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64)
|
||||
if err != nil {
|
||||
return KernelHung{}, err
|
||||
}
|
||||
return KernelHung{
|
||||
HungTaskDetectCount: &val,
|
||||
}, nil
|
||||
}
|
||||
2
vendor/github.com/prometheus/procfs/kernel_random.go
generated
vendored
2
vendor/github.com/prometheus/procfs/kernel_random.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020 The Prometheus Authors
|
||||
// Copyright 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
|
||||
|
||||
6
vendor/github.com/prometheus/procfs/loadavg.go
generated
vendored
6
vendor/github.com/prometheus/procfs/loadavg.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -44,14 +44,14 @@ func parseLoad(loadavgBytes []byte) (*LoadAvg, error) {
|
||||
loads := make([]float64, 3)
|
||||
parts := strings.Fields(string(loadavgBytes))
|
||||
if len(parts) < 3 {
|
||||
return nil, fmt.Errorf("malformed loadavg line: too few fields in loadavg string: %q", string(loadavgBytes))
|
||||
return nil, fmt.Errorf("%w: Malformed line %q", ErrFileParse, string(loadavgBytes))
|
||||
}
|
||||
|
||||
var err error
|
||||
for i, load := range parts[0:3] {
|
||||
loads[i], err = strconv.ParseFloat(load, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse load %q: %w", load, err)
|
||||
return nil, fmt.Errorf("%w: Cannot parse load: %f: %w", ErrFileParse, loads[i], err)
|
||||
}
|
||||
}
|
||||
return &LoadAvg{
|
||||
|
||||
185
vendor/github.com/prometheus/procfs/mdstat.go
generated
vendored
185
vendor/github.com/prometheus/procfs/mdstat.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2018 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -23,17 +23,38 @@ import (
|
||||
|
||||
var (
|
||||
statusLineRE = regexp.MustCompile(`(\d+) blocks .*\[(\d+)/(\d+)\] \[([U_]+)\]`)
|
||||
recoveryLineBlocksRE = regexp.MustCompile(`\((\d+)/\d+\)`)
|
||||
recoveryLineBlocksRE = regexp.MustCompile(`\((\d+/\d+)\)`)
|
||||
recoveryLinePctRE = regexp.MustCompile(`= (.+)%`)
|
||||
recoveryLineFinishRE = regexp.MustCompile(`finish=(.+)min`)
|
||||
recoveryLineSpeedRE = regexp.MustCompile(`speed=(.+)[A-Z]`)
|
||||
componentDeviceRE = regexp.MustCompile(`(.*)\[\d+\]`)
|
||||
componentDeviceRE = regexp.MustCompile(`(.*)\[(\d+)\](\([SF]+\))?`)
|
||||
personalitiesPrefix = "Personalities : "
|
||||
)
|
||||
|
||||
type MDStatComponent struct {
|
||||
// Name of the component device.
|
||||
Name string
|
||||
// DescriptorIndex number of component device, e.g. the order in the superblock.
|
||||
DescriptorIndex int32
|
||||
// Flags per Linux drivers/md/md.[ch] as of v6.12-rc1
|
||||
// Subset that are exposed in mdstat
|
||||
WriteMostly bool
|
||||
Journal bool
|
||||
Faulty bool // "Faulty" is what kernel source uses for "(F)"
|
||||
Spare bool
|
||||
Replacement bool
|
||||
// Some additional flags that are NOT exposed in procfs today; they may
|
||||
// be available via sysfs.
|
||||
// In_sync, Bitmap_sync, Blocked, WriteErrorSeen, FaultRecorded,
|
||||
// BlockedBadBlocks, WantReplacement, Candidate, ...
|
||||
}
|
||||
|
||||
// MDStat holds info parsed from /proc/mdstat.
|
||||
type MDStat struct {
|
||||
// Name of the device.
|
||||
Name string
|
||||
// raid type of the device.
|
||||
Type string
|
||||
// activity-state of the device.
|
||||
ActivityState string
|
||||
// Number of active disks.
|
||||
@@ -50,14 +71,16 @@ type MDStat struct {
|
||||
BlocksTotal int64
|
||||
// Number of blocks on the device that are in sync.
|
||||
BlocksSynced int64
|
||||
// Number of blocks on the device that need to be synced.
|
||||
BlocksToBeSynced int64
|
||||
// progress percentage of current sync
|
||||
BlocksSyncedPct float64
|
||||
// estimated finishing time for current sync (in minutes)
|
||||
BlocksSyncedFinishTime float64
|
||||
// current sync speed (in Kilobytes/sec)
|
||||
BlocksSyncedSpeed float64
|
||||
// Name of md component devices
|
||||
Devices []string
|
||||
// component devices
|
||||
Devices []MDStatComponent
|
||||
}
|
||||
|
||||
// MDStat parses an mdstat-file (/proc/mdstat) and returns a slice of
|
||||
@@ -70,7 +93,7 @@ func (fs FS) MDStat() ([]MDStat, error) {
|
||||
}
|
||||
mdstat, err := parseMDStat(data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing mdstat %q: %w", fs.proc.Path("mdstat"), err)
|
||||
return nil, fmt.Errorf("%w: Cannot parse %v: %w", ErrFileParse, fs.proc.Path("mdstat"), err)
|
||||
}
|
||||
return mdstat, nil
|
||||
}
|
||||
@@ -78,34 +101,58 @@ func (fs FS) MDStat() ([]MDStat, error) {
|
||||
// parseMDStat parses data from mdstat file (/proc/mdstat) and returns a slice of
|
||||
// structs containing the relevant info.
|
||||
func parseMDStat(mdStatData []byte) ([]MDStat, error) {
|
||||
// TODO:
|
||||
// - parse global hotspares from the "unused devices" line.
|
||||
mdStats := []MDStat{}
|
||||
lines := strings.Split(string(mdStatData), "\n")
|
||||
knownRaidTypes := make(map[string]bool)
|
||||
|
||||
for i, line := range lines {
|
||||
if strings.TrimSpace(line) == "" || line[0] == ' ' ||
|
||||
strings.HasPrefix(line, "Personalities") ||
|
||||
strings.HasPrefix(line, "unused") {
|
||||
continue
|
||||
}
|
||||
// Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
|
||||
if len(knownRaidTypes) == 0 && strings.HasPrefix(line, personalitiesPrefix) {
|
||||
personalities := strings.Fields(line[len(personalitiesPrefix):])
|
||||
for _, word := range personalities {
|
||||
word := word[1 : len(word)-1]
|
||||
knownRaidTypes[word] = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
deviceFields := strings.Fields(line)
|
||||
if len(deviceFields) < 3 {
|
||||
return nil, fmt.Errorf("not enough fields in mdline (expected at least 3): %s", line)
|
||||
return nil, fmt.Errorf("%w: Expected 3+ lines, got %q", ErrFileParse, line)
|
||||
}
|
||||
mdName := deviceFields[0] // mdx
|
||||
state := deviceFields[2] // active or inactive
|
||||
state := deviceFields[2] // active, inactive, broken
|
||||
|
||||
if len(lines) <= i+3 {
|
||||
return nil, fmt.Errorf("error parsing %q: too few lines for md device", mdName)
|
||||
mdType := "unknown" // raid1, raid5, etc.
|
||||
var deviceStartIndex int
|
||||
if len(deviceFields) > 3 { // mdType may be in the 3rd or 4th field
|
||||
if isRaidType(deviceFields[3], knownRaidTypes) {
|
||||
mdType = deviceFields[3]
|
||||
deviceStartIndex = 4
|
||||
} else if len(deviceFields) > 4 && isRaidType(deviceFields[4], knownRaidTypes) {
|
||||
// if the 3rd field is (...), the 4th field is the mdType
|
||||
mdType = deviceFields[4]
|
||||
deviceStartIndex = 5
|
||||
}
|
||||
}
|
||||
|
||||
// Failed disks have the suffix (F) & Spare disks have the suffix (S).
|
||||
if len(lines) <= i+3 {
|
||||
return nil, fmt.Errorf("%w: Too few lines for md device: %q", ErrFileParse, mdName)
|
||||
}
|
||||
|
||||
// Failed (Faulty) disks have the suffix (F) & Spare disks have the suffix (S).
|
||||
fail := int64(strings.Count(line, "(F)"))
|
||||
spare := int64(strings.Count(line, "(S)"))
|
||||
active, total, down, size, err := evalStatusLine(lines[i], lines[i+1])
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing md device lines: %w", err)
|
||||
return nil, fmt.Errorf("%w: Cannot parse md device lines: %v: %w", ErrFileParse, active, err)
|
||||
}
|
||||
|
||||
syncLineIdx := i + 2
|
||||
@@ -115,38 +162,49 @@ func parseMDStat(mdStatData []byte) ([]MDStat, error) {
|
||||
|
||||
// If device is syncing at the moment, get the number of currently
|
||||
// synced bytes, otherwise that number equals the size of the device.
|
||||
syncedBlocks := size
|
||||
blocksSynced := size
|
||||
blocksToBeSynced := size
|
||||
speed := float64(0)
|
||||
finish := float64(0)
|
||||
pct := float64(0)
|
||||
recovering := strings.Contains(lines[syncLineIdx], "recovery")
|
||||
reshaping := strings.Contains(lines[syncLineIdx], "reshape")
|
||||
resyncing := strings.Contains(lines[syncLineIdx], "resync")
|
||||
checking := strings.Contains(lines[syncLineIdx], "check")
|
||||
|
||||
// Append recovery and resyncing state info.
|
||||
if recovering || resyncing || checking {
|
||||
if recovering {
|
||||
if recovering || resyncing || checking || reshaping {
|
||||
switch {
|
||||
case recovering:
|
||||
state = "recovering"
|
||||
} else if checking {
|
||||
case reshaping:
|
||||
state = "reshaping"
|
||||
case checking:
|
||||
state = "checking"
|
||||
} else {
|
||||
default:
|
||||
state = "resyncing"
|
||||
}
|
||||
|
||||
// Handle case when resync=PENDING or resync=DELAYED.
|
||||
if strings.Contains(lines[syncLineIdx], "PENDING") ||
|
||||
strings.Contains(lines[syncLineIdx], "DELAYED") {
|
||||
syncedBlocks = 0
|
||||
blocksSynced = 0
|
||||
} else {
|
||||
syncedBlocks, pct, finish, speed, err = evalRecoveryLine(lines[syncLineIdx])
|
||||
blocksSynced, blocksToBeSynced, pct, finish, speed, err = evalRecoveryLine(lines[syncLineIdx])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing sync line in md device %q: %w", mdName, err)
|
||||
return nil, fmt.Errorf("%w: Cannot parse sync line in md device: %q: %w", ErrFileParse, mdName, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
devices, err := evalComponentDevices(deviceFields[deviceStartIndex:])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing components in md device %q: %w", mdName, err)
|
||||
}
|
||||
|
||||
mdStats = append(mdStats, MDStat{
|
||||
Name: mdName,
|
||||
Type: mdType,
|
||||
ActivityState: state,
|
||||
DisksActive: active,
|
||||
DisksFailed: fail,
|
||||
@@ -154,27 +212,38 @@ func parseMDStat(mdStatData []byte) ([]MDStat, error) {
|
||||
DisksSpare: spare,
|
||||
DisksTotal: total,
|
||||
BlocksTotal: size,
|
||||
BlocksSynced: syncedBlocks,
|
||||
BlocksSynced: blocksSynced,
|
||||
BlocksToBeSynced: blocksToBeSynced,
|
||||
BlocksSyncedPct: pct,
|
||||
BlocksSyncedFinishTime: finish,
|
||||
BlocksSyncedSpeed: speed,
|
||||
Devices: evalComponentDevices(deviceFields),
|
||||
Devices: devices,
|
||||
})
|
||||
}
|
||||
|
||||
return mdStats, nil
|
||||
}
|
||||
|
||||
// check if a string's format is like the mdType
|
||||
// Rule 1: mdType should not be like (...)
|
||||
// Rule 2: mdType should not be like sda[0]
|
||||
// .
|
||||
func isRaidType(mdType string, knownRaidTypes map[string]bool) bool {
|
||||
_, ok := knownRaidTypes[mdType]
|
||||
return !strings.ContainsAny(mdType, "([") && ok
|
||||
}
|
||||
|
||||
func evalStatusLine(deviceLine, statusLine string) (active, total, down, size int64, err error) {
|
||||
// e.g. 523968 blocks super 1.2 [4/4] [UUUU]
|
||||
statusFields := strings.Fields(statusLine)
|
||||
if len(statusFields) < 1 {
|
||||
return 0, 0, 0, 0, fmt.Errorf("unexpected statusLine %q", statusLine)
|
||||
return 0, 0, 0, 0, fmt.Errorf("%w: Unexpected statusline %q: %w", ErrFileParse, statusLine, err)
|
||||
}
|
||||
|
||||
sizeStr := statusFields[0]
|
||||
size, err = strconv.ParseInt(sizeStr, 10, 64)
|
||||
if err != nil {
|
||||
return 0, 0, 0, 0, fmt.Errorf("unexpected statusLine %q: %w", statusLine, err)
|
||||
return 0, 0, 0, 0, fmt.Errorf("%w: Unexpected statusline %q: %w", ErrFileParse, statusLine, err)
|
||||
}
|
||||
|
||||
if strings.Contains(deviceLine, "raid0") || strings.Contains(deviceLine, "linear") {
|
||||
@@ -189,78 +258,96 @@ func evalStatusLine(deviceLine, statusLine string) (active, total, down, size in
|
||||
|
||||
matches := statusLineRE.FindStringSubmatch(statusLine)
|
||||
if len(matches) != 5 {
|
||||
return 0, 0, 0, 0, fmt.Errorf("couldn't find all the substring matches: %s", statusLine)
|
||||
return 0, 0, 0, 0, fmt.Errorf("%w: Could not fild all substring matches %s: %w", ErrFileParse, statusLine, err)
|
||||
}
|
||||
|
||||
total, err = strconv.ParseInt(matches[2], 10, 64)
|
||||
if err != nil {
|
||||
return 0, 0, 0, 0, fmt.Errorf("unexpected statusLine %q: %w", statusLine, err)
|
||||
return 0, 0, 0, 0, fmt.Errorf("%w: Unexpected statusline %q: %w", ErrFileParse, statusLine, err)
|
||||
}
|
||||
|
||||
active, err = strconv.ParseInt(matches[3], 10, 64)
|
||||
if err != nil {
|
||||
return 0, 0, 0, 0, fmt.Errorf("unexpected statusLine %q: %w", statusLine, err)
|
||||
return 0, 0, 0, 0, fmt.Errorf("%w: Unexpected active %d: %w", ErrFileParse, active, err)
|
||||
}
|
||||
down = int64(strings.Count(matches[4], "_"))
|
||||
|
||||
return active, total, down, size, nil
|
||||
}
|
||||
|
||||
func evalRecoveryLine(recoveryLine string) (syncedBlocks int64, pct float64, finish float64, speed float64, err error) {
|
||||
func evalRecoveryLine(recoveryLine string) (blocksSynced int64, blocksToBeSynced int64, pct float64, finish float64, speed float64, err error) {
|
||||
matches := recoveryLineBlocksRE.FindStringSubmatch(recoveryLine)
|
||||
if len(matches) != 2 {
|
||||
return 0, 0, 0, 0, fmt.Errorf("unexpected recoveryLine: %s", recoveryLine)
|
||||
return 0, 0, 0, 0, 0, fmt.Errorf("%w: Unexpected recoveryLine blocks %s: %w", ErrFileParse, recoveryLine, err)
|
||||
}
|
||||
|
||||
syncedBlocks, err = strconv.ParseInt(matches[1], 10, 64)
|
||||
blocks := strings.Split(matches[1], "/")
|
||||
blocksSynced, err = strconv.ParseInt(blocks[0], 10, 64)
|
||||
if err != nil {
|
||||
return 0, 0, 0, 0, fmt.Errorf("error parsing int from recoveryLine %q: %w", recoveryLine, err)
|
||||
return 0, 0, 0, 0, 0, fmt.Errorf("%w: Unable to parse recovery blocks synced %q: %w", ErrFileParse, matches[1], err)
|
||||
}
|
||||
|
||||
blocksToBeSynced, err = strconv.ParseInt(blocks[1], 10, 64)
|
||||
if err != nil {
|
||||
return blocksSynced, 0, 0, 0, 0, fmt.Errorf("%w: Unable to parse recovery to be synced blocks %q: %w", ErrFileParse, matches[2], err)
|
||||
}
|
||||
|
||||
// Get percentage complete
|
||||
matches = recoveryLinePctRE.FindStringSubmatch(recoveryLine)
|
||||
if len(matches) != 2 {
|
||||
return syncedBlocks, 0, 0, 0, fmt.Errorf("unexpected recoveryLine matching percentage: %s", recoveryLine)
|
||||
return blocksSynced, blocksToBeSynced, 0, 0, 0, fmt.Errorf("%w: Unexpected recoveryLine matching percentage %s", ErrFileParse, recoveryLine)
|
||||
}
|
||||
pct, err = strconv.ParseFloat(strings.TrimSpace(matches[1]), 64)
|
||||
if err != nil {
|
||||
return syncedBlocks, 0, 0, 0, fmt.Errorf("error parsing float from recoveryLine %q: %w", recoveryLine, err)
|
||||
return blocksSynced, blocksToBeSynced, 0, 0, 0, fmt.Errorf("%w: Error parsing float from recoveryLine %q", ErrFileParse, recoveryLine)
|
||||
}
|
||||
|
||||
// Get time expected left to complete
|
||||
matches = recoveryLineFinishRE.FindStringSubmatch(recoveryLine)
|
||||
if len(matches) != 2 {
|
||||
return syncedBlocks, pct, 0, 0, fmt.Errorf("unexpected recoveryLine matching est. finish time: %s", recoveryLine)
|
||||
return blocksSynced, blocksToBeSynced, pct, 0, 0, fmt.Errorf("%w: Unexpected recoveryLine matching est. finish time: %s", ErrFileParse, recoveryLine)
|
||||
}
|
||||
finish, err = strconv.ParseFloat(matches[1], 64)
|
||||
if err != nil {
|
||||
return syncedBlocks, pct, 0, 0, fmt.Errorf("error parsing float from recoveryLine %q: %w", recoveryLine, err)
|
||||
return blocksSynced, blocksToBeSynced, pct, 0, 0, fmt.Errorf("%w: Unable to parse float from recoveryLine: %q", ErrFileParse, recoveryLine)
|
||||
}
|
||||
|
||||
// Get recovery speed
|
||||
matches = recoveryLineSpeedRE.FindStringSubmatch(recoveryLine)
|
||||
if len(matches) != 2 {
|
||||
return syncedBlocks, pct, finish, 0, fmt.Errorf("unexpected recoveryLine matching speed: %s", recoveryLine)
|
||||
return blocksSynced, blocksToBeSynced, pct, finish, 0, fmt.Errorf("%w: Unexpected recoveryLine value: %s", ErrFileParse, recoveryLine)
|
||||
}
|
||||
speed, err = strconv.ParseFloat(matches[1], 64)
|
||||
if err != nil {
|
||||
return syncedBlocks, pct, finish, 0, fmt.Errorf("error parsing float from recoveryLine %q: %w", recoveryLine, err)
|
||||
return blocksSynced, blocksToBeSynced, pct, finish, 0, fmt.Errorf("%w: Error parsing float from recoveryLine: %q: %w", ErrFileParse, recoveryLine, err)
|
||||
}
|
||||
|
||||
return syncedBlocks, pct, finish, speed, nil
|
||||
return blocksSynced, blocksToBeSynced, pct, finish, speed, nil
|
||||
}
|
||||
|
||||
func evalComponentDevices(deviceFields []string) []string {
|
||||
mdComponentDevices := make([]string, 0)
|
||||
if len(deviceFields) > 3 {
|
||||
for _, field := range deviceFields[4:] {
|
||||
match := componentDeviceRE.FindStringSubmatch(field)
|
||||
if match == nil {
|
||||
continue
|
||||
}
|
||||
mdComponentDevices = append(mdComponentDevices, match[1])
|
||||
func evalComponentDevices(deviceFields []string) ([]MDStatComponent, error) {
|
||||
mdComponentDevices := make([]MDStatComponent, 0)
|
||||
for _, field := range deviceFields {
|
||||
match := componentDeviceRE.FindStringSubmatch(field)
|
||||
if match == nil {
|
||||
continue
|
||||
}
|
||||
descriptorIndex, err := strconv.ParseInt(match[2], 10, 32)
|
||||
if err != nil {
|
||||
return mdComponentDevices, fmt.Errorf("error parsing int from device %q: %w", match[2], err)
|
||||
}
|
||||
mdComponentDevices = append(mdComponentDevices, MDStatComponent{
|
||||
Name: match[1],
|
||||
DescriptorIndex: int32(descriptorIndex),
|
||||
// match may contain one or more of these
|
||||
// https://github.com/torvalds/linux/blob/7ec462100ef9142344ddbf86f2c3008b97acddbe/drivers/md/md.c#L8376-L8392
|
||||
Faulty: strings.Contains(match[3], "(F)"),
|
||||
Spare: strings.Contains(match[3], "(S)"),
|
||||
Journal: strings.Contains(match[3], "(J)"),
|
||||
Replacement: strings.Contains(match[3], "(R)"),
|
||||
WriteMostly: strings.Contains(match[3], "(W)"),
|
||||
})
|
||||
}
|
||||
|
||||
return mdComponentDevices
|
||||
return mdComponentDevices, nil
|
||||
}
|
||||
|
||||
255
vendor/github.com/prometheus/procfs/meminfo.go
generated
vendored
255
vendor/github.com/prometheus/procfs/meminfo.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -66,6 +66,10 @@ type Meminfo struct {
|
||||
// Memory which has been evicted from RAM, and is temporarily
|
||||
// on the disk
|
||||
SwapFree *uint64
|
||||
// Memory consumed by the zswap backend (compressed size)
|
||||
Zswap *uint64
|
||||
// Amount of anonymous memory stored in zswap (original size)
|
||||
Zswapped *uint64
|
||||
// Memory which is waiting to get written back to the disk
|
||||
Dirty *uint64
|
||||
// Memory which is actively being written back to the disk
|
||||
@@ -85,6 +89,8 @@ type Meminfo struct {
|
||||
// amount of memory dedicated to the lowest level of page
|
||||
// tables.
|
||||
PageTables *uint64
|
||||
// secondary page tables.
|
||||
SecPageTables *uint64
|
||||
// NFS pages sent to the server, but not yet committed to
|
||||
// stable storage
|
||||
NFSUnstable *uint64
|
||||
@@ -126,20 +132,79 @@ type Meminfo struct {
|
||||
VmallocUsed *uint64
|
||||
// largest contiguous block of vmalloc area which is free
|
||||
VmallocChunk *uint64
|
||||
Percpu *uint64
|
||||
HardwareCorrupted *uint64
|
||||
AnonHugePages *uint64
|
||||
FileHugePages *uint64
|
||||
ShmemHugePages *uint64
|
||||
ShmemPmdMapped *uint64
|
||||
CmaTotal *uint64
|
||||
CmaFree *uint64
|
||||
Unaccepted *uint64
|
||||
HugePagesTotal *uint64
|
||||
HugePagesFree *uint64
|
||||
HugePagesRsvd *uint64
|
||||
HugePagesSurp *uint64
|
||||
Hugepagesize *uint64
|
||||
Hugetlb *uint64
|
||||
DirectMap4k *uint64
|
||||
DirectMap2M *uint64
|
||||
DirectMap1G *uint64
|
||||
|
||||
// The struct fields below are the byte-normalized counterparts to the
|
||||
// existing struct fields. Values are normalized using the optional
|
||||
// unit field in the meminfo line.
|
||||
MemTotalBytes *uint64
|
||||
MemFreeBytes *uint64
|
||||
MemAvailableBytes *uint64
|
||||
BuffersBytes *uint64
|
||||
CachedBytes *uint64
|
||||
SwapCachedBytes *uint64
|
||||
ActiveBytes *uint64
|
||||
InactiveBytes *uint64
|
||||
ActiveAnonBytes *uint64
|
||||
InactiveAnonBytes *uint64
|
||||
ActiveFileBytes *uint64
|
||||
InactiveFileBytes *uint64
|
||||
UnevictableBytes *uint64
|
||||
MlockedBytes *uint64
|
||||
SwapTotalBytes *uint64
|
||||
SwapFreeBytes *uint64
|
||||
ZswapBytes *uint64
|
||||
ZswappedBytes *uint64
|
||||
DirtyBytes *uint64
|
||||
WritebackBytes *uint64
|
||||
AnonPagesBytes *uint64
|
||||
MappedBytes *uint64
|
||||
ShmemBytes *uint64
|
||||
SlabBytes *uint64
|
||||
SReclaimableBytes *uint64
|
||||
SUnreclaimBytes *uint64
|
||||
KernelStackBytes *uint64
|
||||
PageTablesBytes *uint64
|
||||
SecPageTablesBytes *uint64
|
||||
NFSUnstableBytes *uint64
|
||||
BounceBytes *uint64
|
||||
WritebackTmpBytes *uint64
|
||||
CommitLimitBytes *uint64
|
||||
CommittedASBytes *uint64
|
||||
VmallocTotalBytes *uint64
|
||||
VmallocUsedBytes *uint64
|
||||
VmallocChunkBytes *uint64
|
||||
PercpuBytes *uint64
|
||||
HardwareCorruptedBytes *uint64
|
||||
AnonHugePagesBytes *uint64
|
||||
FileHugePagesBytes *uint64
|
||||
ShmemHugePagesBytes *uint64
|
||||
ShmemPmdMappedBytes *uint64
|
||||
CmaTotalBytes *uint64
|
||||
CmaFreeBytes *uint64
|
||||
UnacceptedBytes *uint64
|
||||
HugepagesizeBytes *uint64
|
||||
HugetlbBytes *uint64
|
||||
DirectMap4kBytes *uint64
|
||||
DirectMap2MBytes *uint64
|
||||
DirectMap1GBytes *uint64
|
||||
}
|
||||
|
||||
// Meminfo returns an information about current kernel/system memory statistics.
|
||||
@@ -152,7 +217,7 @@ func (fs FS) Meminfo() (Meminfo, error) {
|
||||
|
||||
m, err := parseMemInfo(bytes.NewReader(b))
|
||||
if err != nil {
|
||||
return Meminfo{}, fmt.Errorf("failed to parse meminfo: %w", err)
|
||||
return Meminfo{}, fmt.Errorf("%w: %w", ErrFileParse, err)
|
||||
}
|
||||
|
||||
return *m, nil
|
||||
@@ -162,114 +227,194 @@ func parseMemInfo(r io.Reader) (*Meminfo, error) {
|
||||
var m Meminfo
|
||||
s := bufio.NewScanner(r)
|
||||
for s.Scan() {
|
||||
// Each line has at least a name and value; we ignore the unit.
|
||||
fields := strings.Fields(s.Text())
|
||||
if len(fields) < 2 {
|
||||
return nil, fmt.Errorf("malformed meminfo line: %q", s.Text())
|
||||
}
|
||||
var val, valBytes uint64
|
||||
|
||||
v, err := strconv.ParseUint(fields[1], 0, 64)
|
||||
val, err := strconv.ParseUint(fields[1], 0, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch len(fields) {
|
||||
case 2:
|
||||
// No unit present, use the parsed the value as bytes directly.
|
||||
valBytes = val
|
||||
case 3:
|
||||
// Unit present in optional 3rd field, convert it to
|
||||
// bytes. The only unit supported within the Linux
|
||||
// kernel is `kB`.
|
||||
if fields[2] != "kB" {
|
||||
return nil, fmt.Errorf("%w: Unsupported unit in optional 3rd field %q", ErrFileParse, fields[2])
|
||||
}
|
||||
|
||||
valBytes = 1024 * val
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("%w: Malformed line %q", ErrFileParse, s.Text())
|
||||
}
|
||||
|
||||
switch fields[0] {
|
||||
case "MemTotal:":
|
||||
m.MemTotal = &v
|
||||
m.MemTotal = &val
|
||||
m.MemTotalBytes = &valBytes
|
||||
case "MemFree:":
|
||||
m.MemFree = &v
|
||||
m.MemFree = &val
|
||||
m.MemFreeBytes = &valBytes
|
||||
case "MemAvailable:":
|
||||
m.MemAvailable = &v
|
||||
m.MemAvailable = &val
|
||||
m.MemAvailableBytes = &valBytes
|
||||
case "Buffers:":
|
||||
m.Buffers = &v
|
||||
m.Buffers = &val
|
||||
m.BuffersBytes = &valBytes
|
||||
case "Cached:":
|
||||
m.Cached = &v
|
||||
m.Cached = &val
|
||||
m.CachedBytes = &valBytes
|
||||
case "SwapCached:":
|
||||
m.SwapCached = &v
|
||||
m.SwapCached = &val
|
||||
m.SwapCachedBytes = &valBytes
|
||||
case "Active:":
|
||||
m.Active = &v
|
||||
m.Active = &val
|
||||
m.ActiveBytes = &valBytes
|
||||
case "Inactive:":
|
||||
m.Inactive = &v
|
||||
m.Inactive = &val
|
||||
m.InactiveBytes = &valBytes
|
||||
case "Active(anon):":
|
||||
m.ActiveAnon = &v
|
||||
m.ActiveAnon = &val
|
||||
m.ActiveAnonBytes = &valBytes
|
||||
case "Inactive(anon):":
|
||||
m.InactiveAnon = &v
|
||||
m.InactiveAnon = &val
|
||||
m.InactiveAnonBytes = &valBytes
|
||||
case "Active(file):":
|
||||
m.ActiveFile = &v
|
||||
m.ActiveFile = &val
|
||||
m.ActiveFileBytes = &valBytes
|
||||
case "Inactive(file):":
|
||||
m.InactiveFile = &v
|
||||
m.InactiveFile = &val
|
||||
m.InactiveFileBytes = &valBytes
|
||||
case "Unevictable:":
|
||||
m.Unevictable = &v
|
||||
m.Unevictable = &val
|
||||
m.UnevictableBytes = &valBytes
|
||||
case "Mlocked:":
|
||||
m.Mlocked = &v
|
||||
m.Mlocked = &val
|
||||
m.MlockedBytes = &valBytes
|
||||
case "SwapTotal:":
|
||||
m.SwapTotal = &v
|
||||
m.SwapTotal = &val
|
||||
m.SwapTotalBytes = &valBytes
|
||||
case "SwapFree:":
|
||||
m.SwapFree = &v
|
||||
m.SwapFree = &val
|
||||
m.SwapFreeBytes = &valBytes
|
||||
case "Zswap:":
|
||||
m.Zswap = &val
|
||||
m.ZswapBytes = &valBytes
|
||||
case "Zswapped:":
|
||||
m.Zswapped = &val
|
||||
m.ZswappedBytes = &valBytes
|
||||
case "Dirty:":
|
||||
m.Dirty = &v
|
||||
m.Dirty = &val
|
||||
m.DirtyBytes = &valBytes
|
||||
case "Writeback:":
|
||||
m.Writeback = &v
|
||||
m.Writeback = &val
|
||||
m.WritebackBytes = &valBytes
|
||||
case "AnonPages:":
|
||||
m.AnonPages = &v
|
||||
m.AnonPages = &val
|
||||
m.AnonPagesBytes = &valBytes
|
||||
case "Mapped:":
|
||||
m.Mapped = &v
|
||||
m.Mapped = &val
|
||||
m.MappedBytes = &valBytes
|
||||
case "Shmem:":
|
||||
m.Shmem = &v
|
||||
m.Shmem = &val
|
||||
m.ShmemBytes = &valBytes
|
||||
case "Slab:":
|
||||
m.Slab = &v
|
||||
m.Slab = &val
|
||||
m.SlabBytes = &valBytes
|
||||
case "SReclaimable:":
|
||||
m.SReclaimable = &v
|
||||
m.SReclaimable = &val
|
||||
m.SReclaimableBytes = &valBytes
|
||||
case "SUnreclaim:":
|
||||
m.SUnreclaim = &v
|
||||
m.SUnreclaim = &val
|
||||
m.SUnreclaimBytes = &valBytes
|
||||
case "KernelStack:":
|
||||
m.KernelStack = &v
|
||||
m.KernelStack = &val
|
||||
m.KernelStackBytes = &valBytes
|
||||
case "PageTables:":
|
||||
m.PageTables = &v
|
||||
m.PageTables = &val
|
||||
m.PageTablesBytes = &valBytes
|
||||
case "SecPageTables:":
|
||||
m.SecPageTables = &val
|
||||
m.SecPageTablesBytes = &valBytes
|
||||
case "NFS_Unstable:":
|
||||
m.NFSUnstable = &v
|
||||
m.NFSUnstable = &val
|
||||
m.NFSUnstableBytes = &valBytes
|
||||
case "Bounce:":
|
||||
m.Bounce = &v
|
||||
m.Bounce = &val
|
||||
m.BounceBytes = &valBytes
|
||||
case "WritebackTmp:":
|
||||
m.WritebackTmp = &v
|
||||
m.WritebackTmp = &val
|
||||
m.WritebackTmpBytes = &valBytes
|
||||
case "CommitLimit:":
|
||||
m.CommitLimit = &v
|
||||
m.CommitLimit = &val
|
||||
m.CommitLimitBytes = &valBytes
|
||||
case "Committed_AS:":
|
||||
m.CommittedAS = &v
|
||||
m.CommittedAS = &val
|
||||
m.CommittedASBytes = &valBytes
|
||||
case "VmallocTotal:":
|
||||
m.VmallocTotal = &v
|
||||
m.VmallocTotal = &val
|
||||
m.VmallocTotalBytes = &valBytes
|
||||
case "VmallocUsed:":
|
||||
m.VmallocUsed = &v
|
||||
m.VmallocUsed = &val
|
||||
m.VmallocUsedBytes = &valBytes
|
||||
case "VmallocChunk:":
|
||||
m.VmallocChunk = &v
|
||||
m.VmallocChunk = &val
|
||||
m.VmallocChunkBytes = &valBytes
|
||||
case "Percpu:":
|
||||
m.Percpu = &val
|
||||
m.PercpuBytes = &valBytes
|
||||
case "HardwareCorrupted:":
|
||||
m.HardwareCorrupted = &v
|
||||
m.HardwareCorrupted = &val
|
||||
m.HardwareCorruptedBytes = &valBytes
|
||||
case "AnonHugePages:":
|
||||
m.AnonHugePages = &v
|
||||
m.AnonHugePages = &val
|
||||
m.AnonHugePagesBytes = &valBytes
|
||||
case "FileHugePages:":
|
||||
m.FileHugePages = &val
|
||||
m.FileHugePagesBytes = &valBytes
|
||||
case "ShmemHugePages:":
|
||||
m.ShmemHugePages = &v
|
||||
m.ShmemHugePages = &val
|
||||
m.ShmemHugePagesBytes = &valBytes
|
||||
case "ShmemPmdMapped:":
|
||||
m.ShmemPmdMapped = &v
|
||||
m.ShmemPmdMapped = &val
|
||||
m.ShmemPmdMappedBytes = &valBytes
|
||||
case "CmaTotal:":
|
||||
m.CmaTotal = &v
|
||||
m.CmaTotal = &val
|
||||
m.CmaTotalBytes = &valBytes
|
||||
case "CmaFree:":
|
||||
m.CmaFree = &v
|
||||
m.CmaFree = &val
|
||||
m.CmaFreeBytes = &valBytes
|
||||
case "Unaccepted:":
|
||||
m.Unaccepted = &val
|
||||
m.UnacceptedBytes = &valBytes
|
||||
case "HugePages_Total:":
|
||||
m.HugePagesTotal = &v
|
||||
m.HugePagesTotal = &val
|
||||
case "HugePages_Free:":
|
||||
m.HugePagesFree = &v
|
||||
m.HugePagesFree = &val
|
||||
case "HugePages_Rsvd:":
|
||||
m.HugePagesRsvd = &v
|
||||
m.HugePagesRsvd = &val
|
||||
case "HugePages_Surp:":
|
||||
m.HugePagesSurp = &v
|
||||
m.HugePagesSurp = &val
|
||||
case "Hugepagesize:":
|
||||
m.Hugepagesize = &v
|
||||
m.Hugepagesize = &val
|
||||
m.HugepagesizeBytes = &valBytes
|
||||
case "Hugetlb:":
|
||||
m.Hugetlb = &val
|
||||
m.HugetlbBytes = &valBytes
|
||||
case "DirectMap4k:":
|
||||
m.DirectMap4k = &v
|
||||
m.DirectMap4k = &val
|
||||
m.DirectMap4kBytes = &valBytes
|
||||
case "DirectMap2M:":
|
||||
m.DirectMap2M = &v
|
||||
m.DirectMap2M = &val
|
||||
m.DirectMap2MBytes = &valBytes
|
||||
case "DirectMap1G:":
|
||||
m.DirectMap1G = &v
|
||||
m.DirectMap1G = &val
|
||||
m.DirectMap1GBytes = &valBytes
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
33
vendor/github.com/prometheus/procfs/mountinfo.go
generated
vendored
33
vendor/github.com/prometheus/procfs/mountinfo.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -78,11 +78,11 @@ func parseMountInfoString(mountString string) (*MountInfo, error) {
|
||||
mountInfo := strings.Split(mountString, " ")
|
||||
mountInfoLength := len(mountInfo)
|
||||
if mountInfoLength < 10 {
|
||||
return nil, fmt.Errorf("couldn't find enough fields in mount string: %s", mountString)
|
||||
return nil, fmt.Errorf("%w: Too few fields in mount string: %s", ErrFileParse, mountString)
|
||||
}
|
||||
|
||||
if mountInfo[mountInfoLength-4] != "-" {
|
||||
return nil, fmt.Errorf("couldn't find separator in expected field: %s", mountInfo[mountInfoLength-4])
|
||||
return nil, fmt.Errorf("%w: couldn't find separator in expected field: %s", ErrFileParse, mountInfo[mountInfoLength-4])
|
||||
}
|
||||
|
||||
mount := &MountInfo{
|
||||
@@ -98,18 +98,18 @@ func parseMountInfoString(mountString string) (*MountInfo, error) {
|
||||
|
||||
mount.MountID, err = strconv.Atoi(mountInfo[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse mount ID")
|
||||
return nil, fmt.Errorf("%w: mount ID: %q", ErrFileParse, mount.MountID)
|
||||
}
|
||||
mount.ParentID, err = strconv.Atoi(mountInfo[1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse parent ID")
|
||||
return nil, fmt.Errorf("%w: parent ID: %q", ErrFileParse, mount.ParentID)
|
||||
}
|
||||
// Has optional fields, which is a space separated list of values.
|
||||
// Example: shared:2 master:7
|
||||
if mountInfo[6] != "" {
|
||||
mount.OptionalFields, err = mountOptionsParseOptionalFields(mountInfo[6 : mountInfoLength-4])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("%w: %w", ErrFileParse, err)
|
||||
}
|
||||
}
|
||||
return mount, nil
|
||||
@@ -147,8 +147,7 @@ func mountOptionsParseOptionalFields(o []string) (map[string]string, error) {
|
||||
// mountOptionsParser parses the mount options, superblock options.
|
||||
func mountOptionsParser(mountOptions string) map[string]string {
|
||||
opts := make(map[string]string)
|
||||
options := strings.Split(mountOptions, ",")
|
||||
for _, opt := range options {
|
||||
for opt := range strings.SplitSeq(mountOptions, ",") {
|
||||
splitOption := strings.Split(opt, "=")
|
||||
if len(splitOption) < 2 {
|
||||
key := splitOption[0]
|
||||
@@ -178,3 +177,21 @@ func GetProcMounts(pid int) ([]*MountInfo, error) {
|
||||
}
|
||||
return parseMountInfo(data)
|
||||
}
|
||||
|
||||
// GetMounts retrieves mountinfo information from `/proc/self/mountinfo`.
|
||||
func (fs FS) GetMounts() ([]*MountInfo, error) {
|
||||
data, err := util.ReadFileNoStat(fs.proc.Path("self/mountinfo"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return parseMountInfo(data)
|
||||
}
|
||||
|
||||
// GetProcMounts retrieves mountinfo information from a processes' `/proc/<pid>/mountinfo`.
|
||||
func (fs FS) GetProcMounts(pid int) ([]*MountInfo, error) {
|
||||
data, err := util.ReadFileNoStat(fs.proc.Path(fmt.Sprintf("%d/mountinfo", pid)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return parseMountInfo(data)
|
||||
}
|
||||
|
||||
137
vendor/github.com/prometheus/procfs/mountstats.go
generated
vendored
137
vendor/github.com/prometheus/procfs/mountstats.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2018 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -44,6 +44,14 @@ const (
|
||||
|
||||
fieldTransport11TCPLen = 13
|
||||
fieldTransport11UDPLen = 10
|
||||
|
||||
// Kernel version >= 4.14 MaxLen
|
||||
// See: https://elixir.bootlin.com/linux/v6.4.8/source/net/sunrpc/xprtrdma/xprt_rdma.h#L393
|
||||
fieldTransport11RDMAMaxLen = 28
|
||||
|
||||
// Kernel version <= 4.2 MinLen
|
||||
// See: https://elixir.bootlin.com/linux/v4.2.8/source/net/sunrpc/xprtrdma/xprt_rdma.h#L331
|
||||
fieldTransport11RDMAMinLen = 20
|
||||
)
|
||||
|
||||
// A Mount is a device mount parsed from /proc/[pid]/mountstats.
|
||||
@@ -80,7 +88,7 @@ type MountStatsNFS struct {
|
||||
// Statistics broken down by filesystem operation.
|
||||
Operations []NFSOperationStats
|
||||
// Statistics about the NFS RPC transport.
|
||||
Transport NFSTransportStats
|
||||
Transport []NFSTransportStats
|
||||
}
|
||||
|
||||
// mountStats implements MountStats.
|
||||
@@ -231,6 +239,33 @@ type NFSTransportStats struct {
|
||||
// A running counter, incremented on each request as the current size of the
|
||||
// pending queue.
|
||||
CumulativePendingQueue uint64
|
||||
|
||||
// Stats below only available with stat version 1.1.
|
||||
// Transport over RDMA
|
||||
|
||||
// accessed when sending a call
|
||||
ReadChunkCount uint64
|
||||
WriteChunkCount uint64
|
||||
ReplyChunkCount uint64
|
||||
TotalRdmaRequest uint64
|
||||
|
||||
// rarely accessed error counters
|
||||
PullupCopyCount uint64
|
||||
HardwayRegisterCount uint64
|
||||
FailedMarshalCount uint64
|
||||
BadReplyCount uint64
|
||||
MrsRecovered uint64
|
||||
MrsOrphaned uint64
|
||||
MrsAllocated uint64
|
||||
EmptySendctxQ uint64
|
||||
|
||||
// accessed when receiving a reply
|
||||
TotalRdmaReply uint64
|
||||
FixupCopyCount uint64
|
||||
ReplyWaitsForSend uint64
|
||||
LocalInvNeeded uint64
|
||||
NomsgCallCount uint64
|
||||
BcallCount uint64
|
||||
}
|
||||
|
||||
// parseMountStats parses a /proc/[pid]/mountstats file and returns a slice
|
||||
@@ -264,7 +299,7 @@ func parseMountStats(r io.Reader) ([]*Mount, error) {
|
||||
if len(ss) > deviceEntryLen {
|
||||
// Only NFSv3 and v4 are supported for parsing statistics
|
||||
if m.Type != nfs3Type && m.Type != nfs4Type {
|
||||
return nil, fmt.Errorf("cannot parse MountStats for fstype %q", m.Type)
|
||||
return nil, fmt.Errorf("%w: Cannot parse MountStats for %q", ErrFileParse, m.Type)
|
||||
}
|
||||
|
||||
statVersion := strings.TrimPrefix(ss[8], statVersionPrefix)
|
||||
@@ -288,7 +323,7 @@ func parseMountStats(r io.Reader) ([]*Mount, error) {
|
||||
// device [device] mounted on [mount] with fstype [type]
|
||||
func parseMount(ss []string) (*Mount, error) {
|
||||
if len(ss) < deviceEntryLen {
|
||||
return nil, fmt.Errorf("invalid device entry: %v", ss)
|
||||
return nil, fmt.Errorf("%w: Invalid device %q", ErrFileParse, ss)
|
||||
}
|
||||
|
||||
// Check for specific words appearing at specific indices to ensure
|
||||
@@ -306,7 +341,7 @@ func parseMount(ss []string) (*Mount, error) {
|
||||
|
||||
for _, f := range format {
|
||||
if ss[f.i] != f.s {
|
||||
return nil, fmt.Errorf("invalid device entry: %v", ss)
|
||||
return nil, fmt.Errorf("%w: Invalid device %q", ErrFileParse, ss)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,12 +378,12 @@ func parseMountStatsNFS(s *bufio.Scanner, statVersion string) (*MountStatsNFS, e
|
||||
switch ss[0] {
|
||||
case fieldOpts:
|
||||
if len(ss) < 2 {
|
||||
return nil, fmt.Errorf("not enough information for NFS stats: %v", ss)
|
||||
return nil, fmt.Errorf("%w: Incomplete information for NFS stats: %v", ErrFileParse, ss)
|
||||
}
|
||||
if stats.Opts == nil {
|
||||
stats.Opts = map[string]string{}
|
||||
}
|
||||
for _, opt := range strings.Split(ss[1], ",") {
|
||||
for opt := range strings.SplitSeq(ss[1], ",") {
|
||||
split := strings.Split(opt, "=")
|
||||
if len(split) == 2 {
|
||||
stats.Opts[split[0]] = split[1]
|
||||
@@ -358,7 +393,7 @@ func parseMountStatsNFS(s *bufio.Scanner, statVersion string) (*MountStatsNFS, e
|
||||
}
|
||||
case fieldAge:
|
||||
if len(ss) < 2 {
|
||||
return nil, fmt.Errorf("not enough information for NFS stats: %v", ss)
|
||||
return nil, fmt.Errorf("%w: Incomplete information for NFS stats: %v", ErrFileParse, ss)
|
||||
}
|
||||
// Age integer is in seconds
|
||||
d, err := time.ParseDuration(ss[1] + "s")
|
||||
@@ -369,7 +404,7 @@ func parseMountStatsNFS(s *bufio.Scanner, statVersion string) (*MountStatsNFS, e
|
||||
stats.Age = d
|
||||
case fieldBytes:
|
||||
if len(ss) < 2 {
|
||||
return nil, fmt.Errorf("not enough information for NFS stats: %v", ss)
|
||||
return nil, fmt.Errorf("%w: Incomplete information for NFS stats: %v", ErrFileParse, ss)
|
||||
}
|
||||
bstats, err := parseNFSBytesStats(ss[1:])
|
||||
if err != nil {
|
||||
@@ -379,7 +414,7 @@ func parseMountStatsNFS(s *bufio.Scanner, statVersion string) (*MountStatsNFS, e
|
||||
stats.Bytes = *bstats
|
||||
case fieldEvents:
|
||||
if len(ss) < 2 {
|
||||
return nil, fmt.Errorf("not enough information for NFS stats: %v", ss)
|
||||
return nil, fmt.Errorf("%w: Incomplete information for NFS events: %v", ErrFileParse, ss)
|
||||
}
|
||||
estats, err := parseNFSEventsStats(ss[1:])
|
||||
if err != nil {
|
||||
@@ -389,7 +424,7 @@ func parseMountStatsNFS(s *bufio.Scanner, statVersion string) (*MountStatsNFS, e
|
||||
stats.Events = *estats
|
||||
case fieldTransport:
|
||||
if len(ss) < 3 {
|
||||
return nil, fmt.Errorf("not enough information for NFS transport stats: %v", ss)
|
||||
return nil, fmt.Errorf("%w: Incomplete information for NFS transport stats: %v", ErrFileParse, ss)
|
||||
}
|
||||
|
||||
tstats, err := parseNFSTransportStats(ss[1:], statVersion)
|
||||
@@ -397,7 +432,7 @@ func parseMountStatsNFS(s *bufio.Scanner, statVersion string) (*MountStatsNFS, e
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stats.Transport = *tstats
|
||||
stats.Transport = append(stats.Transport, *tstats)
|
||||
}
|
||||
|
||||
// When encountering "per-operation statistics", we must break this
|
||||
@@ -428,7 +463,7 @@ func parseMountStatsNFS(s *bufio.Scanner, statVersion string) (*MountStatsNFS, e
|
||||
// integer fields.
|
||||
func parseNFSBytesStats(ss []string) (*NFSBytesStats, error) {
|
||||
if len(ss) != fieldBytesLen {
|
||||
return nil, fmt.Errorf("invalid NFS bytes stats: %v", ss)
|
||||
return nil, fmt.Errorf("%w: Invalid NFS bytes stats: %v", ErrFileParse, ss)
|
||||
}
|
||||
|
||||
ns := make([]uint64, 0, fieldBytesLen)
|
||||
@@ -457,7 +492,7 @@ func parseNFSBytesStats(ss []string) (*NFSBytesStats, error) {
|
||||
// integer fields.
|
||||
func parseNFSEventsStats(ss []string) (*NFSEventsStats, error) {
|
||||
if len(ss) != fieldEventsLen {
|
||||
return nil, fmt.Errorf("invalid NFS events stats: %v", ss)
|
||||
return nil, fmt.Errorf("%w: invalid NFS events stats: %v", ErrFileParse, ss)
|
||||
}
|
||||
|
||||
ns := make([]uint64, 0, fieldEventsLen)
|
||||
@@ -521,7 +556,7 @@ func parseNFSOperationStats(s *bufio.Scanner) ([]NFSOperationStats, error) {
|
||||
}
|
||||
|
||||
if len(ss) < minFields {
|
||||
return nil, fmt.Errorf("invalid NFS per-operations stats: %v", ss)
|
||||
return nil, fmt.Errorf("%w: invalid NFS per-operations stats: %v", ErrFileParse, ss)
|
||||
}
|
||||
|
||||
// Skip string operation name for integers
|
||||
@@ -534,7 +569,6 @@ func parseNFSOperationStats(s *bufio.Scanner) ([]NFSOperationStats, error) {
|
||||
|
||||
ns = append(ns, n)
|
||||
}
|
||||
|
||||
opStats := NFSOperationStats{
|
||||
Operation: strings.TrimSuffix(ss[0], ":"),
|
||||
Requests: ns[0],
|
||||
@@ -567,30 +601,35 @@ func parseNFSTransportStats(ss []string, statVersion string) (*NFSTransportStats
|
||||
switch statVersion {
|
||||
case statVersion10:
|
||||
var expectedLength int
|
||||
if protocol == "tcp" {
|
||||
switch protocol {
|
||||
case "tcp":
|
||||
expectedLength = fieldTransport10TCPLen
|
||||
} else if protocol == "udp" {
|
||||
case "udp":
|
||||
expectedLength = fieldTransport10UDPLen
|
||||
} else {
|
||||
return nil, fmt.Errorf("invalid NFS protocol \"%s\" in stats 1.0 statement: %v", protocol, ss)
|
||||
default:
|
||||
return nil, fmt.Errorf("%w: Invalid NFS protocol \"%s\" in stats 1.0 statement: %v", ErrFileParse, protocol, ss)
|
||||
}
|
||||
if len(ss) != expectedLength {
|
||||
return nil, fmt.Errorf("invalid NFS transport stats 1.0 statement: %v", ss)
|
||||
return nil, fmt.Errorf("%w: Invalid NFS transport stats 1.0 statement: %v", ErrFileParse, ss)
|
||||
}
|
||||
case statVersion11:
|
||||
var expectedLength int
|
||||
if protocol == "tcp" {
|
||||
switch protocol {
|
||||
case "tcp":
|
||||
expectedLength = fieldTransport11TCPLen
|
||||
} else if protocol == "udp" {
|
||||
case "udp":
|
||||
expectedLength = fieldTransport11UDPLen
|
||||
} else {
|
||||
return nil, fmt.Errorf("invalid NFS protocol \"%s\" in stats 1.1 statement: %v", protocol, ss)
|
||||
case "rdma":
|
||||
expectedLength = fieldTransport11RDMAMinLen
|
||||
default:
|
||||
return nil, fmt.Errorf("%w: invalid NFS protocol \"%s\" in stats 1.1 statement: %v", ErrFileParse, protocol, ss)
|
||||
}
|
||||
if len(ss) != expectedLength {
|
||||
return nil, fmt.Errorf("invalid NFS transport stats 1.1 statement: %v", ss)
|
||||
if (len(ss) != expectedLength && (protocol == "tcp" || protocol == "udp")) ||
|
||||
(protocol == "rdma" && len(ss) < expectedLength) {
|
||||
return nil, fmt.Errorf("%w: invalid NFS transport stats 1.1 statement: %v, protocol: %v", ErrFileParse, ss, protocol)
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("unrecognized NFS transport stats version: %q", statVersion)
|
||||
return nil, fmt.Errorf("%w: Unrecognized NFS transport stats version: %q, protocol: %v", ErrFileParse, statVersion, protocol)
|
||||
}
|
||||
|
||||
// Allocate enough for v1.1 stats since zero value for v1.1 stats will be okay
|
||||
@@ -600,7 +639,9 @@ func parseNFSTransportStats(ss []string, statVersion string) (*NFSTransportStats
|
||||
// Note: slice length must be set to length of v1.1 stats to avoid a panic when
|
||||
// only v1.0 stats are present.
|
||||
// See: https://github.com/prometheus/node_exporter/issues/571.
|
||||
ns := make([]uint64, fieldTransport11TCPLen)
|
||||
//
|
||||
// Note: NFS Over RDMA slice length is fieldTransport11RDMAMaxLen
|
||||
ns := make([]uint64, fieldTransport11RDMAMaxLen+3)
|
||||
for i, s := range ss {
|
||||
n, err := strconv.ParseUint(s, 10, 64)
|
||||
if err != nil {
|
||||
@@ -616,11 +657,17 @@ func parseNFSTransportStats(ss []string, statVersion string) (*NFSTransportStats
|
||||
// For the udp RPC transport there is no connection count, connect idle time,
|
||||
// or idle time (fields #3, #4, and #5); all other fields are the same. So
|
||||
// we set them to 0 here.
|
||||
if protocol == "udp" {
|
||||
switch protocol {
|
||||
case "udp":
|
||||
ns = append(ns[:2], append(make([]uint64, 3), ns[2:]...)...)
|
||||
case "tcp":
|
||||
ns = append(ns[:fieldTransport11TCPLen], make([]uint64, fieldTransport11RDMAMaxLen-fieldTransport11TCPLen+3)...)
|
||||
case "rdma":
|
||||
ns = append(ns[:fieldTransport10TCPLen], append(make([]uint64, 3), ns[fieldTransport10TCPLen:]...)...)
|
||||
}
|
||||
|
||||
return &NFSTransportStats{
|
||||
// NFS xprt over tcp or udp
|
||||
Protocol: protocol,
|
||||
Port: ns[0],
|
||||
Bind: ns[1],
|
||||
@@ -632,8 +679,32 @@ func parseNFSTransportStats(ss []string, statVersion string) (*NFSTransportStats
|
||||
BadTransactionIDs: ns[7],
|
||||
CumulativeActiveRequests: ns[8],
|
||||
CumulativeBacklog: ns[9],
|
||||
MaximumRPCSlotsUsed: ns[10],
|
||||
CumulativeSendingQueue: ns[11],
|
||||
CumulativePendingQueue: ns[12],
|
||||
|
||||
// NFS xprt over tcp or udp
|
||||
// And statVersion 1.1
|
||||
MaximumRPCSlotsUsed: ns[10],
|
||||
CumulativeSendingQueue: ns[11],
|
||||
CumulativePendingQueue: ns[12],
|
||||
|
||||
// NFS xprt over rdma
|
||||
// And stat Version 1.1
|
||||
ReadChunkCount: ns[13],
|
||||
WriteChunkCount: ns[14],
|
||||
ReplyChunkCount: ns[15],
|
||||
TotalRdmaRequest: ns[16],
|
||||
PullupCopyCount: ns[17],
|
||||
HardwayRegisterCount: ns[18],
|
||||
FailedMarshalCount: ns[19],
|
||||
BadReplyCount: ns[20],
|
||||
MrsRecovered: ns[21],
|
||||
MrsOrphaned: ns[22],
|
||||
MrsAllocated: ns[23],
|
||||
EmptySendctxQ: ns[24],
|
||||
TotalRdmaReply: ns[25],
|
||||
FixupCopyCount: ns[26],
|
||||
ReplyWaitsForSend: ns[27],
|
||||
LocalInvNeeded: ns[28],
|
||||
NomsgCallCount: ns[29],
|
||||
BcallCount: ns[30],
|
||||
}, nil
|
||||
}
|
||||
|
||||
93
vendor/github.com/prometheus/procfs/net_conntrackstat.go
generated
vendored
93
vendor/github.com/prometheus/procfs/net_conntrackstat.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus/procfs/internal/util"
|
||||
@@ -28,9 +27,13 @@ import (
|
||||
// and contains netfilter conntrack statistics at one CPU core.
|
||||
type ConntrackStatEntry struct {
|
||||
Entries uint64
|
||||
Searched uint64
|
||||
Found uint64
|
||||
New uint64
|
||||
Invalid uint64
|
||||
Ignore uint64
|
||||
Delete uint64
|
||||
DeleteList uint64
|
||||
Insert uint64
|
||||
InsertFailed uint64
|
||||
Drop uint64
|
||||
@@ -55,7 +58,7 @@ func readConntrackStat(path string) ([]ConntrackStatEntry, error) {
|
||||
|
||||
stat, err := parseConntrackStat(bytes.NewReader(b))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read conntrack stats from %q: %w", path, err)
|
||||
return nil, fmt.Errorf("%w: Cannot read file: %v: %w", ErrFileRead, path, err)
|
||||
}
|
||||
|
||||
return stat, nil
|
||||
@@ -81,73 +84,35 @@ func parseConntrackStat(r io.Reader) ([]ConntrackStatEntry, error) {
|
||||
|
||||
// Parses a ConntrackStatEntry from given array of fields.
|
||||
func parseConntrackStatEntry(fields []string) (*ConntrackStatEntry, error) {
|
||||
if len(fields) != 17 {
|
||||
return nil, fmt.Errorf("invalid conntrackstat entry, missing fields")
|
||||
}
|
||||
entry := &ConntrackStatEntry{}
|
||||
|
||||
entries, err := parseConntrackStatField(fields[0])
|
||||
entries, err := util.ParseHexUint64s(fields)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("%w: Cannot parse entry: %d: %w", ErrFileParse, entries, err)
|
||||
}
|
||||
entry.Entries = entries
|
||||
|
||||
found, err := parseConntrackStatField(fields[2])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
numEntries := len(entries)
|
||||
if numEntries < 16 || numEntries > 17 {
|
||||
return nil,
|
||||
fmt.Errorf("%w: invalid conntrackstat entry, invalid number of fields: %d", ErrFileParse, numEntries)
|
||||
}
|
||||
entry.Found = found
|
||||
|
||||
invalid, err := parseConntrackStatField(fields[4])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
stats := &ConntrackStatEntry{
|
||||
Entries: *entries[0],
|
||||
Searched: *entries[1],
|
||||
Found: *entries[2],
|
||||
New: *entries[3],
|
||||
Invalid: *entries[4],
|
||||
Ignore: *entries[5],
|
||||
Delete: *entries[6],
|
||||
DeleteList: *entries[7],
|
||||
Insert: *entries[8],
|
||||
InsertFailed: *entries[9],
|
||||
Drop: *entries[10],
|
||||
EarlyDrop: *entries[11],
|
||||
}
|
||||
entry.Invalid = invalid
|
||||
|
||||
ignore, err := parseConntrackStatField(fields[5])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
// Ignore missing search_restart on Linux < 2.6.35.
|
||||
if numEntries == 17 {
|
||||
stats.SearchRestart = *entries[16]
|
||||
}
|
||||
entry.Ignore = ignore
|
||||
|
||||
insert, err := parseConntrackStatField(fields[8])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
entry.Insert = insert
|
||||
|
||||
insertFailed, err := parseConntrackStatField(fields[9])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
entry.InsertFailed = insertFailed
|
||||
|
||||
drop, err := parseConntrackStatField(fields[10])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
entry.Drop = drop
|
||||
|
||||
earlyDrop, err := parseConntrackStatField(fields[11])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
entry.EarlyDrop = earlyDrop
|
||||
|
||||
searchRestart, err := parseConntrackStatField(fields[16])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
entry.SearchRestart = searchRestart
|
||||
|
||||
return entry, nil
|
||||
}
|
||||
|
||||
// Parses a uint64 from given hex in string.
|
||||
func parseConntrackStatField(field string) (uint64, error) {
|
||||
val, err := strconv.ParseUint(field, 16, 64)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("couldn't parse %q field: %w", field, err)
|
||||
}
|
||||
return val, err
|
||||
return stats, nil
|
||||
}
|
||||
|
||||
2
vendor/github.com/prometheus/procfs/net_dev.go
generated
vendored
2
vendor/github.com/prometheus/procfs/net_dev.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2018 The Prometheus Authors
|
||||
// Copyright 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
|
||||
|
||||
99
vendor/github.com/prometheus/procfs/net_dev_snmp6.go
generated
vendored
Normal file
99
vendor/github.com/prometheus/procfs/net_dev_snmp6.go
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
// Copyright 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 procfs
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// NetDevSNMP6 is parsed from files in /proc/net/dev_snmp6/ or /proc/<PID>/net/dev_snmp6/.
|
||||
// The outer map's keys are interface names and the inner map's keys are stat names.
|
||||
//
|
||||
// If you'd like a total across all interfaces, please use the Snmp6() method of the Proc type.
|
||||
type NetDevSNMP6 map[string]map[string]uint64
|
||||
|
||||
// Returns kernel/system statistics read from interface files within the /proc/net/dev_snmp6/
|
||||
// directory.
|
||||
func (fs FS) NetDevSNMP6() (NetDevSNMP6, error) {
|
||||
return newNetDevSNMP6(fs.proc.Path("net/dev_snmp6"))
|
||||
}
|
||||
|
||||
// Returns kernel/system statistics read from interface files within the /proc/<PID>/net/dev_snmp6/
|
||||
// directory.
|
||||
func (p Proc) NetDevSNMP6() (NetDevSNMP6, error) {
|
||||
return newNetDevSNMP6(p.path("net/dev_snmp6"))
|
||||
}
|
||||
|
||||
// newNetDevSNMP6 creates a new NetDevSNMP6 from the contents of the given directory.
|
||||
func newNetDevSNMP6(dir string) (NetDevSNMP6, error) {
|
||||
netDevSNMP6 := make(NetDevSNMP6)
|
||||
|
||||
// The net/dev_snmp6 folders contain one file per interface
|
||||
ifaceFiles, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
// On systems with IPv6 disabled, this directory won't exist.
|
||||
// Do nothing.
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return netDevSNMP6, err
|
||||
}
|
||||
return netDevSNMP6, err
|
||||
}
|
||||
|
||||
for _, iFaceFile := range ifaceFiles {
|
||||
filePath := filepath.Join(dir, iFaceFile.Name())
|
||||
|
||||
f, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
return netDevSNMP6, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
netDevSNMP6[iFaceFile.Name()], err = parseNetDevSNMP6Stats(f)
|
||||
if err != nil {
|
||||
return netDevSNMP6, err
|
||||
}
|
||||
}
|
||||
|
||||
return netDevSNMP6, nil
|
||||
}
|
||||
|
||||
func parseNetDevSNMP6Stats(r io.Reader) (map[string]uint64, error) {
|
||||
m := make(map[string]uint64)
|
||||
|
||||
scanner := bufio.NewScanner(r)
|
||||
for scanner.Scan() {
|
||||
stat := strings.Fields(scanner.Text())
|
||||
if len(stat) < 2 {
|
||||
continue
|
||||
}
|
||||
key, val := stat[0], stat[1]
|
||||
|
||||
// Expect stat name to contain "6" or be "ifIndex"
|
||||
if strings.Contains(key, "6") || key == "ifIndex" {
|
||||
v, err := strconv.ParseUint(val, 10, 64)
|
||||
if err != nil {
|
||||
return m, err
|
||||
}
|
||||
|
||||
m[key] = v
|
||||
}
|
||||
}
|
||||
return m, scanner.Err()
|
||||
}
|
||||
66
vendor/github.com/prometheus/procfs/net_ip_socket.go
generated
vendored
66
vendor/github.com/prometheus/procfs/net_ip_socket.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -25,7 +25,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// readLimit is used by io.LimitReader while reading the content of the
|
||||
// Maximum size limit used by io.LimitReader while reading the content of the
|
||||
// /proc/net/udp{,6} files. The number of lines inside such a file is dynamic
|
||||
// as each line represents a single used socket.
|
||||
// In theory, the number of available sockets is 65535 (2^16 - 1) per IP.
|
||||
@@ -50,10 +50,13 @@ type (
|
||||
// UsedSockets shows the total number of parsed lines representing the
|
||||
// number of used sockets.
|
||||
UsedSockets uint64
|
||||
// Drops shows the total number of dropped packets of all UDP sockets.
|
||||
Drops *uint64
|
||||
}
|
||||
|
||||
// netIPSocketLine represents the fields parsed from a single line
|
||||
// in /proc/net/{t,u}dp{,6}. Fields which are not used by IPSocket are skipped.
|
||||
// A single line parser for fields from /proc/net/{t,u}dp{,6}.
|
||||
// Fields which are not used by IPSocket are skipped.
|
||||
// Drops is non-nil for udp{,6}, but nil for tcp{,6}.
|
||||
// For the proc file format details, see https://linux.die.net/man/5/proc.
|
||||
netIPSocketLine struct {
|
||||
Sl uint64
|
||||
@@ -66,6 +69,7 @@ type (
|
||||
RxQueue uint64
|
||||
UID uint64
|
||||
Inode uint64
|
||||
Drops *uint64
|
||||
}
|
||||
)
|
||||
|
||||
@@ -77,13 +81,14 @@ func newNetIPSocket(file string) (NetIPSocket, error) {
|
||||
defer f.Close()
|
||||
|
||||
var netIPSocket NetIPSocket
|
||||
isUDP := strings.Contains(file, "udp")
|
||||
|
||||
lr := io.LimitReader(f, readLimit)
|
||||
s := bufio.NewScanner(lr)
|
||||
s.Scan() // skip first line with headers
|
||||
for s.Scan() {
|
||||
fields := strings.Fields(s.Text())
|
||||
line, err := parseNetIPSocketLine(fields)
|
||||
line, err := parseNetIPSocketLine(fields, isUDP)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -104,19 +109,25 @@ func newNetIPSocketSummary(file string) (*NetIPSocketSummary, error) {
|
||||
defer f.Close()
|
||||
|
||||
var netIPSocketSummary NetIPSocketSummary
|
||||
var udpPacketDrops uint64
|
||||
isUDP := strings.Contains(file, "udp")
|
||||
|
||||
lr := io.LimitReader(f, readLimit)
|
||||
s := bufio.NewScanner(lr)
|
||||
s.Scan() // skip first line with headers
|
||||
for s.Scan() {
|
||||
fields := strings.Fields(s.Text())
|
||||
line, err := parseNetIPSocketLine(fields)
|
||||
line, err := parseNetIPSocketLine(fields, isUDP)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
netIPSocketSummary.TxQueueLength += line.TxQueue
|
||||
netIPSocketSummary.RxQueueLength += line.RxQueue
|
||||
netIPSocketSummary.UsedSockets++
|
||||
if isUDP {
|
||||
udpPacketDrops += *line.Drops
|
||||
netIPSocketSummary.Drops = &udpPacketDrops
|
||||
}
|
||||
}
|
||||
if err := s.Err(); err != nil {
|
||||
return nil, err
|
||||
@@ -130,7 +141,7 @@ func parseIP(hexIP string) (net.IP, error) {
|
||||
var byteIP []byte
|
||||
byteIP, err := hex.DecodeString(hexIP)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot parse address field in socket line %q", hexIP)
|
||||
return nil, fmt.Errorf("%w: Cannot parse socket field in %q: %w", ErrFileParse, hexIP, err)
|
||||
}
|
||||
switch len(byteIP) {
|
||||
case 4:
|
||||
@@ -144,16 +155,17 @@ func parseIP(hexIP string) (net.IP, error) {
|
||||
}
|
||||
return i, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("Unable to parse IP %s", hexIP)
|
||||
return nil, fmt.Errorf("%w: Unable to parse IP %s: %v", ErrFileParse, hexIP, nil)
|
||||
}
|
||||
}
|
||||
|
||||
// parseNetIPSocketLine parses a single line, represented by a list of fields.
|
||||
func parseNetIPSocketLine(fields []string) (*netIPSocketLine, error) {
|
||||
func parseNetIPSocketLine(fields []string, isUDP bool) (*netIPSocketLine, error) {
|
||||
line := &netIPSocketLine{}
|
||||
if len(fields) < 10 {
|
||||
return nil, fmt.Errorf(
|
||||
"cannot parse net socket line as it has less then 10 columns %q",
|
||||
"%w: Less than 10 columns found %q",
|
||||
ErrFileParse,
|
||||
strings.Join(fields, " "),
|
||||
)
|
||||
}
|
||||
@@ -162,64 +174,74 @@ func parseNetIPSocketLine(fields []string) (*netIPSocketLine, error) {
|
||||
// sl
|
||||
s := strings.Split(fields[0], ":")
|
||||
if len(s) != 2 {
|
||||
return nil, fmt.Errorf("cannot parse sl field in socket line %q", fields[0])
|
||||
return nil, fmt.Errorf("%w: Unable to parse sl field in line %q", ErrFileParse, fields[0])
|
||||
}
|
||||
|
||||
if line.Sl, err = strconv.ParseUint(s[0], 0, 64); err != nil {
|
||||
return nil, fmt.Errorf("cannot parse sl value in socket line: %w", err)
|
||||
return nil, fmt.Errorf("%w: Unable to parse sl field in %q: %w", ErrFileParse, line.Sl, err)
|
||||
}
|
||||
// local_address
|
||||
l := strings.Split(fields[1], ":")
|
||||
if len(l) != 2 {
|
||||
return nil, fmt.Errorf("cannot parse local_address field in socket line %q", fields[1])
|
||||
return nil, fmt.Errorf("%w: Unable to parse local_address field in %q", ErrFileParse, fields[1])
|
||||
}
|
||||
if line.LocalAddr, err = parseIP(l[0]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if line.LocalPort, err = strconv.ParseUint(l[1], 16, 64); err != nil {
|
||||
return nil, fmt.Errorf("cannot parse local_address port value in socket line: %w", err)
|
||||
return nil, fmt.Errorf("%w: Unable to parse local_address port value line %q: %w", ErrFileParse, line.LocalPort, err)
|
||||
}
|
||||
|
||||
// remote_address
|
||||
r := strings.Split(fields[2], ":")
|
||||
if len(r) != 2 {
|
||||
return nil, fmt.Errorf("cannot parse rem_address field in socket line %q", fields[1])
|
||||
return nil, fmt.Errorf("%w: Unable to parse rem_address field in %q", ErrFileParse, fields[1])
|
||||
}
|
||||
if line.RemAddr, err = parseIP(r[0]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if line.RemPort, err = strconv.ParseUint(r[1], 16, 64); err != nil {
|
||||
return nil, fmt.Errorf("cannot parse rem_address port value in socket line: %w", err)
|
||||
return nil, fmt.Errorf("%w: Cannot parse rem_address port value in %q: %w", ErrFileParse, line.RemPort, err)
|
||||
}
|
||||
|
||||
// st
|
||||
if line.St, err = strconv.ParseUint(fields[3], 16, 64); err != nil {
|
||||
return nil, fmt.Errorf("cannot parse st value in socket line: %w", err)
|
||||
return nil, fmt.Errorf("%w: Cannot parse st value in %q: %w", ErrFileParse, line.St, err)
|
||||
}
|
||||
|
||||
// tx_queue and rx_queue
|
||||
q := strings.Split(fields[4], ":")
|
||||
if len(q) != 2 {
|
||||
return nil, fmt.Errorf(
|
||||
"cannot parse tx/rx queues in socket line as it has a missing colon %q",
|
||||
"%w: Missing colon for tx/rx queues in socket line %q",
|
||||
ErrFileParse,
|
||||
fields[4],
|
||||
)
|
||||
}
|
||||
if line.TxQueue, err = strconv.ParseUint(q[0], 16, 64); err != nil {
|
||||
return nil, fmt.Errorf("cannot parse tx_queue value in socket line: %w", err)
|
||||
return nil, fmt.Errorf("%w: Cannot parse tx_queue value in %q: %w", ErrFileParse, line.TxQueue, err)
|
||||
}
|
||||
if line.RxQueue, err = strconv.ParseUint(q[1], 16, 64); err != nil {
|
||||
return nil, fmt.Errorf("cannot parse rx_queue value in socket line: %w", err)
|
||||
return nil, fmt.Errorf("%w: Cannot parse trx_queue value in %q: %w", ErrFileParse, line.RxQueue, err)
|
||||
}
|
||||
|
||||
// uid
|
||||
if line.UID, err = strconv.ParseUint(fields[7], 0, 64); err != nil {
|
||||
return nil, fmt.Errorf("cannot parse uid value in socket line: %w", err)
|
||||
return nil, fmt.Errorf("%w: Cannot parse UID value in %q: %w", ErrFileParse, line.UID, err)
|
||||
}
|
||||
|
||||
// inode
|
||||
if line.Inode, err = strconv.ParseUint(fields[9], 0, 64); err != nil {
|
||||
return nil, fmt.Errorf("cannot parse inode value in socket line: %w", err)
|
||||
return nil, fmt.Errorf("%w: Cannot parse inode value in %q: %w", ErrFileParse, line.Inode, err)
|
||||
}
|
||||
|
||||
// drops
|
||||
if isUDP {
|
||||
drops, err := strconv.ParseUint(fields[12], 0, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: Cannot parse drops value in %q: %w", ErrFileParse, drops, err)
|
||||
}
|
||||
line.Drops = &drops
|
||||
}
|
||||
|
||||
return line, nil
|
||||
|
||||
29
vendor/github.com/prometheus/procfs/net_protocols.go
generated
vendored
29
vendor/github.com/prometheus/procfs/net_protocols.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -115,23 +115,25 @@ func (ps NetProtocolStats) parseLine(rawLine string) (*NetProtocolStatLine, erro
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if fields[4] == enabled {
|
||||
switch fields[4] {
|
||||
case enabled:
|
||||
line.Pressure = 1
|
||||
} else if fields[4] == disabled {
|
||||
case disabled:
|
||||
line.Pressure = 0
|
||||
} else {
|
||||
default:
|
||||
line.Pressure = -1
|
||||
}
|
||||
line.MaxHeader, err = strconv.ParseUint(fields[5], 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if fields[6] == enabled {
|
||||
switch fields[6] {
|
||||
case enabled:
|
||||
line.Slab = true
|
||||
} else if fields[6] == disabled {
|
||||
case disabled:
|
||||
line.Slab = false
|
||||
} else {
|
||||
return nil, fmt.Errorf("unable to parse capability for protocol: %s", line.Name)
|
||||
default:
|
||||
return nil, fmt.Errorf("%w: capability for protocol: %s", ErrFileParse, line.Name)
|
||||
}
|
||||
line.ModuleName = fields[7]
|
||||
|
||||
@@ -167,13 +169,14 @@ func (pc *NetProtocolCapabilities) parseCapabilities(capabilities []string) erro
|
||||
&pc.EnterMemoryPressure,
|
||||
}
|
||||
|
||||
for i := 0; i < len(capabilities); i++ {
|
||||
if capabilities[i] == "y" {
|
||||
for i := range capabilities {
|
||||
switch capabilities[i] {
|
||||
case "y":
|
||||
*capabilityFields[i] = true
|
||||
} else if capabilities[i] == "n" {
|
||||
case "n":
|
||||
*capabilityFields[i] = false
|
||||
} else {
|
||||
return fmt.Errorf("unable to parse capability block for protocol: position %d", i)
|
||||
default:
|
||||
return fmt.Errorf("%w: capability block for protocol: position %d", ErrFileParse, i)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
143
vendor/github.com/prometheus/procfs/net_route.go
generated
vendored
Normal file
143
vendor/github.com/prometheus/procfs/net_route.go
generated
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
// Copyright 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 procfs
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus/procfs/internal/util"
|
||||
)
|
||||
|
||||
const (
|
||||
blackholeRepresentation string = "*"
|
||||
blackholeIfaceName string = "blackhole"
|
||||
routeLineColumns int = 11
|
||||
)
|
||||
|
||||
// A NetRouteLine represents one line from net/route.
|
||||
type NetRouteLine struct {
|
||||
Iface string
|
||||
Destination uint32
|
||||
Gateway uint32
|
||||
Flags uint32
|
||||
RefCnt uint32
|
||||
Use uint32
|
||||
Metric uint32
|
||||
Mask uint32
|
||||
MTU uint32
|
||||
Window uint32
|
||||
IRTT uint32
|
||||
}
|
||||
|
||||
func (fs FS) NetRoute() ([]NetRouteLine, error) {
|
||||
return readNetRoute(fs.proc.Path("net", "route"))
|
||||
}
|
||||
|
||||
func readNetRoute(path string) ([]NetRouteLine, error) {
|
||||
b, err := util.ReadFileNoStat(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
routelines, err := parseNetRoute(bytes.NewReader(b))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read net route from %s: %w", path, err)
|
||||
}
|
||||
return routelines, nil
|
||||
}
|
||||
|
||||
func parseNetRoute(r io.Reader) ([]NetRouteLine, error) {
|
||||
var routelines []NetRouteLine
|
||||
|
||||
scanner := bufio.NewScanner(r)
|
||||
scanner.Scan()
|
||||
for scanner.Scan() {
|
||||
fields := strings.Fields(scanner.Text())
|
||||
routeline, err := parseNetRouteLine(fields)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
routelines = append(routelines, *routeline)
|
||||
}
|
||||
return routelines, nil
|
||||
}
|
||||
|
||||
func parseNetRouteLine(fields []string) (*NetRouteLine, error) {
|
||||
if len(fields) != routeLineColumns {
|
||||
return nil, fmt.Errorf("invalid routeline, num of digits: %d", len(fields))
|
||||
}
|
||||
iface := fields[0]
|
||||
if iface == blackholeRepresentation {
|
||||
iface = blackholeIfaceName
|
||||
}
|
||||
destination, err := strconv.ParseUint(fields[1], 16, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
gateway, err := strconv.ParseUint(fields[2], 16, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
flags, err := strconv.ParseUint(fields[3], 10, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
refcnt, err := strconv.ParseUint(fields[4], 10, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
use, err := strconv.ParseUint(fields[5], 10, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
metric, err := strconv.ParseUint(fields[6], 10, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mask, err := strconv.ParseUint(fields[7], 16, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mtu, err := strconv.ParseUint(fields[8], 10, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
window, err := strconv.ParseUint(fields[9], 10, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
irtt, err := strconv.ParseUint(fields[10], 10, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
routeline := &NetRouteLine{
|
||||
Iface: iface,
|
||||
Destination: uint32(destination),
|
||||
Gateway: uint32(gateway),
|
||||
Flags: uint32(flags),
|
||||
RefCnt: uint32(refcnt),
|
||||
Use: uint32(use),
|
||||
Metric: uint32(metric),
|
||||
Mask: uint32(mask),
|
||||
MTU: uint32(mtu),
|
||||
Window: uint32(window),
|
||||
IRTT: uint32(irtt),
|
||||
}
|
||||
return routeline, nil
|
||||
}
|
||||
14
vendor/github.com/prometheus/procfs/net_sockstat.go
generated
vendored
14
vendor/github.com/prometheus/procfs/net_sockstat.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -16,7 +16,6 @@ package procfs
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
@@ -70,7 +69,7 @@ func readSockstat(name string) (*NetSockstat, error) {
|
||||
|
||||
stat, err := parseSockstat(bytes.NewReader(b))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read sockstats from %q: %w", name, err)
|
||||
return nil, fmt.Errorf("%w: sockstats from %q: %w", ErrFileRead, name, err)
|
||||
}
|
||||
|
||||
return stat, nil
|
||||
@@ -84,13 +83,13 @@ func parseSockstat(r io.Reader) (*NetSockstat, error) {
|
||||
// Expect a minimum of a protocol and one key/value pair.
|
||||
fields := strings.Split(s.Text(), " ")
|
||||
if len(fields) < 3 {
|
||||
return nil, fmt.Errorf("malformed sockstat line: %q", s.Text())
|
||||
return nil, fmt.Errorf("%w: Malformed sockstat line: %q", ErrFileParse, s.Text())
|
||||
}
|
||||
|
||||
// The remaining fields are key/value pairs.
|
||||
kvs, err := parseSockstatKVs(fields[1:])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing sockstat key/value pairs from %q: %w", s.Text(), err)
|
||||
return nil, fmt.Errorf("%w: sockstat key/value pairs from %q: %w", ErrFileParse, s.Text(), err)
|
||||
}
|
||||
|
||||
// The first field is the protocol. We must trim its colon suffix.
|
||||
@@ -119,7 +118,7 @@ func parseSockstat(r io.Reader) (*NetSockstat, error) {
|
||||
// parseSockstatKVs parses a string slice into a map of key/value pairs.
|
||||
func parseSockstatKVs(kvs []string) (map[string]int, error) {
|
||||
if len(kvs)%2 != 0 {
|
||||
return nil, errors.New("odd number of fields in key/value pairs")
|
||||
return nil, fmt.Errorf("%w:: Odd number of fields in key/value pairs %q", ErrFileParse, kvs)
|
||||
}
|
||||
|
||||
// Iterate two values at a time to gather key/value pairs.
|
||||
@@ -140,9 +139,6 @@ func parseSockstatKVs(kvs []string) (map[string]int, error) {
|
||||
func parseSockstatProtocol(kvs map[string]int) NetSockstatProtocol {
|
||||
var nsp NetSockstatProtocol
|
||||
for k, v := range kvs {
|
||||
// Capture the range variable to ensure we get unique pointers for
|
||||
// each of the optional fields.
|
||||
v := v
|
||||
switch k {
|
||||
case "inuse":
|
||||
nsp.InUse = v
|
||||
|
||||
11
vendor/github.com/prometheus/procfs/net_softnet.go
generated
vendored
11
vendor/github.com/prometheus/procfs/net_softnet.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -64,7 +64,7 @@ func (fs FS) NetSoftnetStat() ([]SoftnetStat, error) {
|
||||
|
||||
entries, err := parseSoftnet(bytes.NewReader(b))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse /proc/net/softnet_stat: %w", err)
|
||||
return nil, fmt.Errorf("%w: /proc/net/softnet_stat: %w", ErrFileParse, err)
|
||||
}
|
||||
|
||||
return entries, nil
|
||||
@@ -76,13 +76,14 @@ func parseSoftnet(r io.Reader) ([]SoftnetStat, error) {
|
||||
s := bufio.NewScanner(r)
|
||||
|
||||
var stats []SoftnetStat
|
||||
cpuIndex := 0
|
||||
for s.Scan() {
|
||||
columns := strings.Fields(s.Text())
|
||||
width := len(columns)
|
||||
softnetStat := SoftnetStat{}
|
||||
|
||||
if width < minColumns {
|
||||
return nil, fmt.Errorf("%d columns were detected, but at least %d were expected", width, minColumns)
|
||||
return nil, fmt.Errorf("%w: detected %d columns, but expected at least %d", ErrFileParse, width, minColumns)
|
||||
}
|
||||
|
||||
// Linux 2.6.23 https://elixir.bootlin.com/linux/v2.6.23/source/net/core/dev.c#L2347
|
||||
@@ -127,9 +128,13 @@ func parseSoftnet(r io.Reader) ([]SoftnetStat, error) {
|
||||
|
||||
softnetStat.SoftnetBacklogLen = us[0]
|
||||
softnetStat.Index = us[1]
|
||||
} else {
|
||||
// For older kernels, create the Index based on the scan line number.
|
||||
softnetStat.Index = uint32(cpuIndex)
|
||||
}
|
||||
softnetStat.Width = width
|
||||
stats = append(stats, softnetStat)
|
||||
cpuIndex++
|
||||
}
|
||||
|
||||
return stats, nil
|
||||
|
||||
6
vendor/github.com/prometheus/procfs/net_tcp.go
generated
vendored
6
vendor/github.com/prometheus/procfs/net_tcp.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -25,24 +25,28 @@ type (
|
||||
|
||||
// NetTCP returns the IPv4 kernel/networking statistics for TCP datagrams
|
||||
// read from /proc/net/tcp.
|
||||
// Deprecated: Use github.com/mdlayher/netlink#Conn (with syscall.AF_INET) instead.
|
||||
func (fs FS) NetTCP() (NetTCP, error) {
|
||||
return newNetTCP(fs.proc.Path("net/tcp"))
|
||||
}
|
||||
|
||||
// NetTCP6 returns the IPv6 kernel/networking statistics for TCP datagrams
|
||||
// read from /proc/net/tcp6.
|
||||
// Deprecated: Use github.com/mdlayher/netlink#Conn (with syscall.AF_INET6) instead.
|
||||
func (fs FS) NetTCP6() (NetTCP, error) {
|
||||
return newNetTCP(fs.proc.Path("net/tcp6"))
|
||||
}
|
||||
|
||||
// NetTCPSummary returns already computed statistics like the total queue lengths
|
||||
// for TCP datagrams read from /proc/net/tcp.
|
||||
// Deprecated: Use github.com/mdlayher/netlink#Conn (with syscall.AF_INET) instead.
|
||||
func (fs FS) NetTCPSummary() (*NetTCPSummary, error) {
|
||||
return newNetTCPSummary(fs.proc.Path("net/tcp"))
|
||||
}
|
||||
|
||||
// NetTCP6Summary returns already computed statistics like the total queue lengths
|
||||
// for TCP datagrams read from /proc/net/tcp6.
|
||||
// Deprecated: Use github.com/mdlayher/netlink#Conn (with syscall.AF_INET6) instead.
|
||||
func (fs FS) NetTCP6Summary() (*NetTCPSummary, error) {
|
||||
return newNetTCPSummary(fs.proc.Path("net/tcp6"))
|
||||
}
|
||||
|
||||
119
vendor/github.com/prometheus/procfs/net_tls_stat.go
generated
vendored
Normal file
119
vendor/github.com/prometheus/procfs/net_tls_stat.go
generated
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
// Copyright 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 procfs
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// TLSStat struct represents data in /proc/net/tls_stat.
|
||||
// See https://docs.kernel.org/networking/tls.html#statistics
|
||||
type TLSStat struct {
|
||||
// number of TX sessions currently installed where host handles cryptography
|
||||
TLSCurrTxSw int
|
||||
// number of RX sessions currently installed where host handles cryptography
|
||||
TLSCurrRxSw int
|
||||
// number of TX sessions currently installed where NIC handles cryptography
|
||||
TLSCurrTxDevice int
|
||||
// number of RX sessions currently installed where NIC handles cryptography
|
||||
TLSCurrRxDevice int
|
||||
//number of TX sessions opened with host cryptography
|
||||
TLSTxSw int
|
||||
//number of RX sessions opened with host cryptography
|
||||
TLSRxSw int
|
||||
// number of TX sessions opened with NIC cryptography
|
||||
TLSTxDevice int
|
||||
// number of RX sessions opened with NIC cryptography
|
||||
TLSRxDevice int
|
||||
// record decryption failed (e.g. due to incorrect authentication tag)
|
||||
TLSDecryptError int
|
||||
// number of RX resyncs sent to NICs handling cryptography
|
||||
TLSRxDeviceResync int
|
||||
// number of RX records which had to be re-decrypted due to TLS_RX_EXPECT_NO_PAD mis-prediction. Note that this counter will also increment for non-data records.
|
||||
TLSDecryptRetry int
|
||||
// number of data RX records which had to be re-decrypted due to TLS_RX_EXPECT_NO_PAD mis-prediction.
|
||||
TLSRxNoPadViolation int
|
||||
}
|
||||
|
||||
// NewTLSStat reads the tls_stat statistics.
|
||||
func NewTLSStat() (TLSStat, error) {
|
||||
fs, err := NewFS(DefaultMountPoint)
|
||||
if err != nil {
|
||||
return TLSStat{}, err
|
||||
}
|
||||
|
||||
return fs.NewTLSStat()
|
||||
}
|
||||
|
||||
// NewTLSStat reads the tls_stat statistics.
|
||||
func (fs FS) NewTLSStat() (TLSStat, error) {
|
||||
file, err := os.Open(fs.proc.Path("net/tls_stat"))
|
||||
if err != nil {
|
||||
return TLSStat{}, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var (
|
||||
tlsstat = TLSStat{}
|
||||
s = bufio.NewScanner(file)
|
||||
)
|
||||
|
||||
for s.Scan() {
|
||||
fields := strings.Fields(s.Text())
|
||||
|
||||
if len(fields) != 2 {
|
||||
return TLSStat{}, fmt.Errorf("%w: %q line %q", ErrFileParse, file.Name(), s.Text())
|
||||
}
|
||||
|
||||
name := fields[0]
|
||||
value, err := strconv.Atoi(fields[1])
|
||||
if err != nil {
|
||||
return TLSStat{}, err
|
||||
}
|
||||
|
||||
switch name {
|
||||
case "TlsCurrTxSw":
|
||||
tlsstat.TLSCurrTxSw = value
|
||||
case "TlsCurrRxSw":
|
||||
tlsstat.TLSCurrRxSw = value
|
||||
case "TlsCurrTxDevice":
|
||||
tlsstat.TLSCurrTxDevice = value
|
||||
case "TlsCurrRxDevice":
|
||||
tlsstat.TLSCurrRxDevice = value
|
||||
case "TlsTxSw":
|
||||
tlsstat.TLSTxSw = value
|
||||
case "TlsRxSw":
|
||||
tlsstat.TLSRxSw = value
|
||||
case "TlsTxDevice":
|
||||
tlsstat.TLSTxDevice = value
|
||||
case "TlsRxDevice":
|
||||
tlsstat.TLSRxDevice = value
|
||||
case "TlsDecryptError":
|
||||
tlsstat.TLSDecryptError = value
|
||||
case "TlsRxDeviceResync":
|
||||
tlsstat.TLSRxDeviceResync = value
|
||||
case "TlsDecryptRetry":
|
||||
tlsstat.TLSDecryptRetry = value
|
||||
case "TlsRxNoPadViolation":
|
||||
tlsstat.TLSRxNoPadViolation = value
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return tlsstat, s.Err()
|
||||
}
|
||||
2
vendor/github.com/prometheus/procfs/net_udp.go
generated
vendored
2
vendor/github.com/prometheus/procfs/net_udp.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020 The Prometheus Authors
|
||||
// Copyright 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
|
||||
|
||||
24
vendor/github.com/prometheus/procfs/net_unix.go
generated
vendored
24
vendor/github.com/prometheus/procfs/net_unix.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2018 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -108,25 +108,25 @@ func parseNetUNIX(r io.Reader) (*NetUNIX, error) {
|
||||
line := s.Text()
|
||||
item, err := nu.parseLine(line, hasInode, minFields)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse /proc/net/unix data %q: %w", line, err)
|
||||
return nil, fmt.Errorf("%w: /proc/net/unix encountered data %q: %w", ErrFileParse, line, err)
|
||||
}
|
||||
|
||||
nu.Rows = append(nu.Rows, item)
|
||||
}
|
||||
|
||||
if err := s.Err(); err != nil {
|
||||
return nil, fmt.Errorf("failed to scan /proc/net/unix data: %w", err)
|
||||
return nil, fmt.Errorf("%w: /proc/net/unix encountered data: %w", ErrFileParse, err)
|
||||
}
|
||||
|
||||
return &nu, nil
|
||||
}
|
||||
|
||||
func (u *NetUNIX) parseLine(line string, hasInode bool, min int) (*NetUNIXLine, error) {
|
||||
func (u *NetUNIX) parseLine(line string, hasInode bool, minFields int) (*NetUNIXLine, error) {
|
||||
fields := strings.Fields(line)
|
||||
|
||||
l := len(fields)
|
||||
if l < min {
|
||||
return nil, fmt.Errorf("expected at least %d fields but got %d", min, l)
|
||||
if l < minFields {
|
||||
return nil, fmt.Errorf("%w: expected at least %d fields but got %d", ErrFileParse, minFields, l)
|
||||
}
|
||||
|
||||
// Field offsets are as follows:
|
||||
@@ -136,29 +136,29 @@ func (u *NetUNIX) parseLine(line string, hasInode bool, min int) (*NetUNIXLine,
|
||||
|
||||
users, err := u.parseUsers(fields[1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse ref count %q: %w", fields[1], err)
|
||||
return nil, fmt.Errorf("%w: ref count %q: %w", ErrFileParse, fields[1], err)
|
||||
}
|
||||
|
||||
flags, err := u.parseFlags(fields[3])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse flags %q: %w", fields[3], err)
|
||||
return nil, fmt.Errorf("%w: Unable to parse flags %q: %w", ErrFileParse, fields[3], err)
|
||||
}
|
||||
|
||||
typ, err := u.parseType(fields[4])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse type %q: %w", fields[4], err)
|
||||
return nil, fmt.Errorf("%w: Failed to parse type %q: %w", ErrFileParse, fields[4], err)
|
||||
}
|
||||
|
||||
state, err := u.parseState(fields[5])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse state %q: %w", fields[5], err)
|
||||
return nil, fmt.Errorf("%w: Failed to parse state %q: %w", ErrFileParse, fields[5], err)
|
||||
}
|
||||
|
||||
var inode uint64
|
||||
if hasInode {
|
||||
inode, err = u.parseInode(fields[6])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse inode %q: %w", fields[6], err)
|
||||
return nil, fmt.Errorf("%w failed to parse inode %q: %w", ErrFileParse, fields[6], err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ func (u *NetUNIX) parseLine(line string, hasInode bool, min int) (*NetUNIXLine,
|
||||
}
|
||||
|
||||
// Path field is optional.
|
||||
if l > min {
|
||||
if l > minFields {
|
||||
// Path occurs at either index 6 or 7 depending on whether inode is
|
||||
// already present.
|
||||
pathIdx := 7
|
||||
|
||||
182
vendor/github.com/prometheus/procfs/net_wireless.go
generated
vendored
Normal file
182
vendor/github.com/prometheus/procfs/net_wireless.go
generated
vendored
Normal file
@@ -0,0 +1,182 @@
|
||||
// Copyright 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 procfs
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus/procfs/internal/util"
|
||||
)
|
||||
|
||||
// Wireless models the content of /proc/net/wireless.
|
||||
type Wireless struct {
|
||||
Name string
|
||||
|
||||
// Status is the current 4-digit hex value status of the interface.
|
||||
Status uint64
|
||||
|
||||
// QualityLink is the link quality.
|
||||
QualityLink int
|
||||
|
||||
// QualityLevel is the signal gain (dBm).
|
||||
QualityLevel int
|
||||
|
||||
// QualityNoise is the signal noise baseline (dBm).
|
||||
QualityNoise int
|
||||
|
||||
// DiscardedNwid is the number of discarded packets with wrong nwid/essid.
|
||||
DiscardedNwid int
|
||||
|
||||
// DiscardedCrypt is the number of discarded packets with wrong code/decode (WEP).
|
||||
DiscardedCrypt int
|
||||
|
||||
// DiscardedFrag is the number of discarded packets that can't perform MAC reassembly.
|
||||
DiscardedFrag int
|
||||
|
||||
// DiscardedRetry is the number of discarded packets that reached max MAC retries.
|
||||
DiscardedRetry int
|
||||
|
||||
// DiscardedMisc is the number of discarded packets for other reasons.
|
||||
DiscardedMisc int
|
||||
|
||||
// MissedBeacon is the number of missed beacons/superframe.
|
||||
MissedBeacon int
|
||||
}
|
||||
|
||||
// Wireless returns kernel wireless statistics.
|
||||
func (fs FS) Wireless() ([]*Wireless, error) {
|
||||
b, err := util.ReadFileNoStat(fs.proc.Path("net/wireless"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m, err := parseWireless(bytes.NewReader(b))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: wireless: %w", ErrFileParse, err)
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// parseWireless parses the contents of /proc/net/wireless.
|
||||
/*
|
||||
Inter-| sta-| Quality | Discarded packets | Missed | WE
|
||||
face | tus | link level noise | nwid crypt frag retry misc | beacon | 22
|
||||
eth1: 0000 5. -256. -10. 0 1 0 3 0 0
|
||||
eth2: 0000 5. -256. -20. 0 2 0 4 0 0
|
||||
*/
|
||||
func parseWireless(r io.Reader) ([]*Wireless, error) {
|
||||
var (
|
||||
interfaces []*Wireless
|
||||
scanner = bufio.NewScanner(r)
|
||||
)
|
||||
|
||||
for n := 0; scanner.Scan(); n++ {
|
||||
// Skip the 2 header lines.
|
||||
if n < 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
line := scanner.Text()
|
||||
|
||||
parts := strings.Split(line, ":")
|
||||
if len(parts) != 2 {
|
||||
return nil, fmt.Errorf("%w: expected 2 parts after splitting line by ':', got %d for line %q", ErrFileParse, len(parts), line)
|
||||
}
|
||||
|
||||
name := strings.TrimSpace(parts[0])
|
||||
stats := strings.Fields(parts[1])
|
||||
|
||||
if len(stats) < 10 {
|
||||
return nil, fmt.Errorf("%w: invalid number of fields in line %d, expected 10+, got %d: %q", ErrFileParse, n, len(stats), line)
|
||||
}
|
||||
|
||||
status, err := strconv.ParseUint(stats[0], 16, 16)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: invalid status in line %d: %q", ErrFileParse, n, line)
|
||||
}
|
||||
|
||||
qlink, err := strconv.Atoi(strings.TrimSuffix(stats[1], "."))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: parse Quality:link as integer %q: %w", ErrFileParse, qlink, err)
|
||||
}
|
||||
|
||||
qlevel, err := strconv.Atoi(strings.TrimSuffix(stats[2], "."))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: Quality:level as integer %q: %w", ErrFileParse, qlevel, err)
|
||||
}
|
||||
|
||||
qnoise, err := strconv.Atoi(strings.TrimSuffix(stats[3], "."))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: Quality:noise as integer %q: %w", ErrFileParse, qnoise, err)
|
||||
}
|
||||
|
||||
dnwid, err := strconv.Atoi(stats[4])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: Discarded:nwid as integer %q: %w", ErrFileParse, dnwid, err)
|
||||
}
|
||||
|
||||
dcrypt, err := strconv.Atoi(stats[5])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: Discarded:crypt as integer %q: %w", ErrFileParse, dcrypt, err)
|
||||
}
|
||||
|
||||
dfrag, err := strconv.Atoi(stats[6])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: Discarded:frag as integer %q: %w", ErrFileParse, dfrag, err)
|
||||
}
|
||||
|
||||
dretry, err := strconv.Atoi(stats[7])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: Discarded:retry as integer %q: %w", ErrFileParse, dretry, err)
|
||||
}
|
||||
|
||||
dmisc, err := strconv.Atoi(stats[8])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: Discarded:misc as integer %q: %w", ErrFileParse, dmisc, err)
|
||||
}
|
||||
|
||||
mbeacon, err := strconv.Atoi(stats[9])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: Missed:beacon as integer %q: %w", ErrFileParse, mbeacon, err)
|
||||
}
|
||||
|
||||
w := &Wireless{
|
||||
Name: name,
|
||||
Status: status,
|
||||
QualityLink: qlink,
|
||||
QualityLevel: qlevel,
|
||||
QualityNoise: qnoise,
|
||||
DiscardedNwid: dnwid,
|
||||
DiscardedCrypt: dcrypt,
|
||||
DiscardedFrag: dfrag,
|
||||
DiscardedRetry: dretry,
|
||||
DiscardedMisc: dmisc,
|
||||
MissedBeacon: mbeacon,
|
||||
}
|
||||
|
||||
interfaces = append(interfaces, w)
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return nil, fmt.Errorf("%w: Failed to scan /proc/net/wireless: %w", ErrFileRead, err)
|
||||
}
|
||||
|
||||
return interfaces, nil
|
||||
}
|
||||
4
vendor/github.com/prometheus/procfs/net_xfrm.go
generated
vendored
4
vendor/github.com/prometheus/procfs/net_xfrm.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2017 Prometheus Team
|
||||
// Copyright 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
|
||||
@@ -115,7 +115,7 @@ func (fs FS) NewXfrmStat() (XfrmStat, error) {
|
||||
fields := strings.Fields(s.Text())
|
||||
|
||||
if len(fields) != 2 {
|
||||
return XfrmStat{}, fmt.Errorf("couldn't parse %q line %q", file.Name(), s.Text())
|
||||
return XfrmStat{}, fmt.Errorf("%w: %q line %q", ErrFileParse, file.Name(), s.Text())
|
||||
}
|
||||
|
||||
name := fields[0]
|
||||
|
||||
27
vendor/github.com/prometheus/procfs/netstat.go
generated
vendored
27
vendor/github.com/prometheus/procfs/netstat.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -15,7 +15,6 @@ package procfs
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
@@ -38,12 +37,7 @@ func (fs FS) NetStat() ([]NetStat, error) {
|
||||
var netStatsTotal []NetStat
|
||||
|
||||
for _, filePath := range statFiles {
|
||||
file, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
procNetstat, err := parseNetstat(file)
|
||||
procNetstat, err := parseNetstat(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -56,14 +50,17 @@ func (fs FS) NetStat() ([]NetStat, error) {
|
||||
|
||||
// parseNetstat parses the metrics from `/proc/net/stat/` file
|
||||
// and returns a NetStat structure.
|
||||
func parseNetstat(r io.Reader) (NetStat, error) {
|
||||
var (
|
||||
scanner = bufio.NewScanner(r)
|
||||
netStat = NetStat{
|
||||
Stats: make(map[string][]uint64),
|
||||
}
|
||||
)
|
||||
func parseNetstat(filePath string) (NetStat, error) {
|
||||
netStat := NetStat{
|
||||
Stats: make(map[string][]uint64),
|
||||
}
|
||||
file, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
return netStat, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
scanner.Scan()
|
||||
|
||||
// First string is always a header for stats
|
||||
|
||||
85
vendor/github.com/prometheus/procfs/nfnetlink_queue.go
generated
vendored
Normal file
85
vendor/github.com/prometheus/procfs/nfnetlink_queue.go
generated
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
// Copyright 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 procfs
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"github.com/prometheus/procfs/internal/util"
|
||||
)
|
||||
|
||||
const nfNetLinkQueueFormat = "%d %d %d %d %d %d %d %d %d"
|
||||
|
||||
// NFNetLinkQueue contains general information about netfilter queues found in /proc/net/netfilter/nfnetlink_queue.
|
||||
type NFNetLinkQueue struct {
|
||||
// id of the queue
|
||||
QueueID uint
|
||||
// pid of process handling the queue
|
||||
PeerPID uint
|
||||
// number of packets waiting for a decision
|
||||
QueueTotal uint
|
||||
// indicate how userspace receive packets
|
||||
CopyMode uint
|
||||
// size of copy
|
||||
CopyRange uint
|
||||
// number of items dropped by the kernel because too many packets were waiting a decision.
|
||||
// It queue_total is superior to queue_max_len (1024 per default) the packets are dropped.
|
||||
QueueDropped uint
|
||||
// number of packets dropped by userspace (due to kernel send failure on the netlink socket)
|
||||
QueueUserDropped uint
|
||||
// sequence number of packets queued. It gives a correct approximation of the number of queued packets.
|
||||
SequenceID uint
|
||||
// internal value (number of entity using the queue)
|
||||
Use uint
|
||||
}
|
||||
|
||||
// NFNetLinkQueue returns information about current state of netfilter queues.
|
||||
func (fs FS) NFNetLinkQueue() ([]NFNetLinkQueue, error) {
|
||||
data, err := util.ReadFileNoStat(fs.proc.Path("net/netfilter/nfnetlink_queue"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
queue := []NFNetLinkQueue{}
|
||||
if len(data) == 0 {
|
||||
return queue, nil
|
||||
}
|
||||
|
||||
scanner := bufio.NewScanner(bytes.NewReader(data))
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
nFNetLinkQueue, err := parseNFNetLinkQueueLine(line)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
queue = append(queue, *nFNetLinkQueue)
|
||||
}
|
||||
return queue, nil
|
||||
}
|
||||
|
||||
// parseNFNetLinkQueueLine parses each line of the /proc/net/netfilter/nfnetlink_queue file.
|
||||
func parseNFNetLinkQueueLine(line string) (*NFNetLinkQueue, error) {
|
||||
nFNetLinkQueue := NFNetLinkQueue{}
|
||||
_, err := fmt.Sscanf(
|
||||
line, nfNetLinkQueueFormat,
|
||||
&nFNetLinkQueue.QueueID, &nFNetLinkQueue.PeerPID, &nFNetLinkQueue.QueueTotal, &nFNetLinkQueue.CopyMode,
|
||||
&nFNetLinkQueue.CopyRange, &nFNetLinkQueue.QueueDropped, &nFNetLinkQueue.QueueUserDropped, &nFNetLinkQueue.SequenceID, &nFNetLinkQueue.Use,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &nFNetLinkQueue, nil
|
||||
}
|
||||
43
vendor/github.com/prometheus/procfs/proc.go
generated
vendored
43
vendor/github.com/prometheus/procfs/proc.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2018 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -15,13 +15,13 @@ package procfs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus/procfs/internal/fs"
|
||||
"github.com/prometheus/procfs/internal/util"
|
||||
)
|
||||
|
||||
@@ -30,12 +30,18 @@ type Proc struct {
|
||||
// The process ID.
|
||||
PID int
|
||||
|
||||
fs fs.FS
|
||||
fs FS
|
||||
}
|
||||
|
||||
// Procs represents a list of Proc structs.
|
||||
type Procs []Proc
|
||||
|
||||
var (
|
||||
ErrFileParse = errors.New("error parsing file")
|
||||
ErrFileRead = errors.New("error reading file")
|
||||
ErrMountPoint = errors.New("error accessing mount point")
|
||||
)
|
||||
|
||||
func (p Procs) Len() int { return len(p) }
|
||||
func (p Procs) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||
func (p Procs) Less(i, j int) bool { return p[i].PID < p[j].PID }
|
||||
@@ -43,7 +49,7 @@ func (p Procs) Less(i, j int) bool { return p[i].PID < p[j].PID }
|
||||
// Self returns a process for the current process read via /proc/self.
|
||||
func Self() (Proc, error) {
|
||||
fs, err := NewFS(DefaultMountPoint)
|
||||
if err != nil {
|
||||
if err != nil || errors.Is(err, ErrMountPoint) {
|
||||
return Proc{}, err
|
||||
}
|
||||
return fs.Self()
|
||||
@@ -73,7 +79,7 @@ func (fs FS) Self() (Proc, error) {
|
||||
if err != nil {
|
||||
return Proc{}, err
|
||||
}
|
||||
pid, err := strconv.Atoi(strings.Replace(p, string(fs.proc), "", -1))
|
||||
pid, err := strconv.Atoi(strings.ReplaceAll(p, string(fs.proc), ""))
|
||||
if err != nil {
|
||||
return Proc{}, err
|
||||
}
|
||||
@@ -92,7 +98,7 @@ func (fs FS) Proc(pid int) (Proc, error) {
|
||||
if _, err := os.Stat(fs.proc.Path(strconv.Itoa(pid))); err != nil {
|
||||
return Proc{}, err
|
||||
}
|
||||
return Proc{PID: pid, fs: fs.proc}, nil
|
||||
return Proc{PID: pid, fs: fs}, nil
|
||||
}
|
||||
|
||||
// AllProcs returns a list of all currently available processes.
|
||||
@@ -105,7 +111,7 @@ func (fs FS) AllProcs() (Procs, error) {
|
||||
|
||||
names, err := d.Readdirnames(-1)
|
||||
if err != nil {
|
||||
return Procs{}, fmt.Errorf("could not read %q: %w", d.Name(), err)
|
||||
return Procs{}, fmt.Errorf("%w: Cannot read file: %v: %w", ErrFileRead, names, err)
|
||||
}
|
||||
|
||||
p := Procs{}
|
||||
@@ -114,7 +120,7 @@ func (fs FS) AllProcs() (Procs, error) {
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
p = append(p, Proc{PID: int(pid), fs: fs.proc})
|
||||
p = append(p, Proc{PID: int(pid), fs: fs})
|
||||
}
|
||||
|
||||
return p, nil
|
||||
@@ -131,7 +137,7 @@ func (p Proc) CmdLine() ([]string, error) {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
return strings.Split(string(bytes.TrimRight(data, string("\x00"))), string(byte(0))), nil
|
||||
return strings.Split(string(bytes.TrimRight(data, "\x00")), "\x00"), nil
|
||||
}
|
||||
|
||||
// Wchan returns the wchan (wait channel) of a process.
|
||||
@@ -206,7 +212,7 @@ func (p Proc) FileDescriptors() ([]uintptr, error) {
|
||||
for i, n := range names {
|
||||
fd, err := strconv.ParseInt(n, 10, 32)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse fd %q: %w", n, err)
|
||||
return nil, fmt.Errorf("%w: Cannot parse line: %v: %w", ErrFileParse, i, err)
|
||||
}
|
||||
fds[i] = uintptr(fd)
|
||||
}
|
||||
@@ -237,6 +243,19 @@ func (p Proc) FileDescriptorTargets() ([]string, error) {
|
||||
// FileDescriptorsLen returns the number of currently open file descriptors of
|
||||
// a process.
|
||||
func (p Proc) FileDescriptorsLen() (int, error) {
|
||||
// Use fast path if available (Linux v6.2): https://github.com/torvalds/linux/commit/f1f1f2569901
|
||||
if p.fs.isReal {
|
||||
stat, err := os.Stat(p.path("fd"))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
size := stat.Size()
|
||||
if size > 0 {
|
||||
return int(size), nil
|
||||
}
|
||||
}
|
||||
|
||||
fds, err := p.fileDescriptors()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -278,14 +297,14 @@ func (p Proc) fileDescriptors() ([]string, error) {
|
||||
|
||||
names, err := d.Readdirnames(-1)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not read %q: %w", d.Name(), err)
|
||||
return nil, fmt.Errorf("%w: Cannot read file: %v: %w", ErrFileRead, names, err)
|
||||
}
|
||||
|
||||
return names, nil
|
||||
}
|
||||
|
||||
func (p Proc) path(pa ...string) string {
|
||||
return p.fs.Path(append([]string{strconv.Itoa(p.PID)}, pa...)...)
|
||||
return p.fs.proc.Path(append([]string{strconv.Itoa(p.PID)}, pa...)...)
|
||||
}
|
||||
|
||||
// FileDescriptorsInfo retrieves information about all file descriptors of
|
||||
|
||||
8
vendor/github.com/prometheus/procfs/proc_cgroup.go
generated
vendored
8
vendor/github.com/prometheus/procfs/proc_cgroup.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
)
|
||||
|
||||
// Cgroup models one line from /proc/[pid]/cgroup. Each Cgroup struct describes the placement of a PID inside a
|
||||
// specific control hierarchy. The kernel has two cgroup APIs, v1 and v2. v1 has one hierarchy per available resource
|
||||
// specific control hierarchy. The kernel has two cgroup APIs, v1 and v2. The v1 has one hierarchy per available resource
|
||||
// controller, while v2 has one unified hierarchy shared by all controllers. Regardless of v1 or v2, all hierarchies
|
||||
// contain all running processes, so the question answerable with a Cgroup struct is 'where is this process in
|
||||
// this hierarchy' (where==what path on the specific cgroupfs). By prefixing this path with the mount point of
|
||||
@@ -51,7 +51,7 @@ func parseCgroupString(cgroupStr string) (*Cgroup, error) {
|
||||
|
||||
fields := strings.SplitN(cgroupStr, ":", 3)
|
||||
if len(fields) < 3 {
|
||||
return nil, fmt.Errorf("at least 3 fields required, found %d fields in cgroup string: %s", len(fields), cgroupStr)
|
||||
return nil, fmt.Errorf("%w: 3+ fields required, found %d fields in cgroup string: %s", ErrFileParse, len(fields), cgroupStr)
|
||||
}
|
||||
|
||||
cgroup := &Cgroup{
|
||||
@@ -60,7 +60,7 @@ func parseCgroupString(cgroupStr string) (*Cgroup, error) {
|
||||
}
|
||||
cgroup.HierarchyID, err = strconv.Atoi(fields[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse hierarchy ID")
|
||||
return nil, fmt.Errorf("%w: hierarchy ID: %q", ErrFileParse, cgroup.HierarchyID)
|
||||
}
|
||||
if fields[1] != "" {
|
||||
ssNames := strings.Split(fields[1], ",")
|
||||
|
||||
14
vendor/github.com/prometheus/procfs/proc_cgroups.go
generated
vendored
14
vendor/github.com/prometheus/procfs/proc_cgroups.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -40,13 +40,13 @@ type CgroupSummary struct {
|
||||
|
||||
// parseCgroupSummary parses each line of the /proc/cgroup file
|
||||
// Line format is `subsys_name hierarchy num_cgroups enabled`.
|
||||
func parseCgroupSummaryString(CgroupSummaryStr string) (*CgroupSummary, error) {
|
||||
func parseCgroupSummaryString(cgroupSummaryStr string) (*CgroupSummary, error) {
|
||||
var err error
|
||||
|
||||
fields := strings.Fields(CgroupSummaryStr)
|
||||
fields := strings.Fields(cgroupSummaryStr)
|
||||
// require at least 4 fields
|
||||
if len(fields) < 4 {
|
||||
return nil, fmt.Errorf("at least 4 fields required, found %d fields in cgroup info string: %s", len(fields), CgroupSummaryStr)
|
||||
return nil, fmt.Errorf("%w: 4+ fields required, found %d fields in cgroup info string: %s", ErrFileParse, len(fields), cgroupSummaryStr)
|
||||
}
|
||||
|
||||
CgroupSummary := &CgroupSummary{
|
||||
@@ -54,15 +54,15 @@ func parseCgroupSummaryString(CgroupSummaryStr string) (*CgroupSummary, error) {
|
||||
}
|
||||
CgroupSummary.Hierarchy, err = strconv.Atoi(fields[1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse hierarchy ID")
|
||||
return nil, fmt.Errorf("%w: Unable to parse hierarchy ID from %q", ErrFileParse, fields[1])
|
||||
}
|
||||
CgroupSummary.Cgroups, err = strconv.Atoi(fields[2])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse Cgroup Num")
|
||||
return nil, fmt.Errorf("%w: Unable to parse Cgroup Num from %q", ErrFileParse, fields[2])
|
||||
}
|
||||
CgroupSummary.Enabled, err = strconv.Atoi(fields[3])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse Enabled")
|
||||
return nil, fmt.Errorf("%w: Unable to parse Enabled from %q", ErrFileParse, fields[3])
|
||||
}
|
||||
return CgroupSummary, nil
|
||||
}
|
||||
|
||||
2
vendor/github.com/prometheus/procfs/proc_environ.go
generated
vendored
2
vendor/github.com/prometheus/procfs/proc_environ.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019 The Prometheus Authors
|
||||
// Copyright 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
|
||||
|
||||
21
vendor/github.com/prometheus/procfs/proc_fdinfo.go
generated
vendored
21
vendor/github.com/prometheus/procfs/proc_fdinfo.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -26,6 +26,7 @@ var (
|
||||
rPos = regexp.MustCompile(`^pos:\s+(\d+)$`)
|
||||
rFlags = regexp.MustCompile(`^flags:\s+(\d+)$`)
|
||||
rMntID = regexp.MustCompile(`^mnt_id:\s+(\d+)$`)
|
||||
rIno = regexp.MustCompile(`^ino:\s+(\d+)$`)
|
||||
rInotify = regexp.MustCompile(`^inotify`)
|
||||
rInotifyParts = regexp.MustCompile(`^inotify\s+wd:([0-9a-f]+)\s+ino:([0-9a-f]+)\s+sdev:([0-9a-f]+)(?:\s+mask:([0-9a-f]+))?`)
|
||||
)
|
||||
@@ -40,6 +41,8 @@ type ProcFDInfo struct {
|
||||
Flags string
|
||||
// Mount point ID
|
||||
MntID string
|
||||
// Inode number
|
||||
Ino string
|
||||
// List of inotify lines (structured) in the fdinfo file (kernel 3.8+ only)
|
||||
InotifyInfos []InotifyInfo
|
||||
}
|
||||
@@ -51,19 +54,22 @@ func (p Proc) FDInfo(fd string) (*ProcFDInfo, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var text, pos, flags, mntid string
|
||||
var text, pos, flags, mntid, ino string
|
||||
var inotify []InotifyInfo
|
||||
|
||||
scanner := bufio.NewScanner(bytes.NewReader(data))
|
||||
for scanner.Scan() {
|
||||
text = scanner.Text()
|
||||
if rPos.MatchString(text) {
|
||||
switch {
|
||||
case rPos.MatchString(text):
|
||||
pos = rPos.FindStringSubmatch(text)[1]
|
||||
} else if rFlags.MatchString(text) {
|
||||
case rFlags.MatchString(text):
|
||||
flags = rFlags.FindStringSubmatch(text)[1]
|
||||
} else if rMntID.MatchString(text) {
|
||||
case rMntID.MatchString(text):
|
||||
mntid = rMntID.FindStringSubmatch(text)[1]
|
||||
} else if rInotify.MatchString(text) {
|
||||
case rIno.MatchString(text):
|
||||
ino = rIno.FindStringSubmatch(text)[1]
|
||||
case rInotify.MatchString(text):
|
||||
newInotify, err := parseInotifyInfo(text)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -77,6 +83,7 @@ func (p Proc) FDInfo(fd string) (*ProcFDInfo, error) {
|
||||
Pos: pos,
|
||||
Flags: flags,
|
||||
MntID: mntid,
|
||||
Ino: ino,
|
||||
InotifyInfos: inotify,
|
||||
}
|
||||
|
||||
@@ -111,7 +118,7 @@ func parseInotifyInfo(line string) (*InotifyInfo, error) {
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
return nil, fmt.Errorf("invalid inode entry: %q", line)
|
||||
return nil, fmt.Errorf("%w: invalid inode entry: %q", ErrFileParse, line)
|
||||
}
|
||||
|
||||
// ProcFDInfos represents a list of ProcFDInfo structs.
|
||||
|
||||
4
vendor/github.com/prometheus/procfs/proc_interrupts.go
generated
vendored
4
vendor/github.com/prometheus/procfs/proc_interrupts.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -66,7 +66,7 @@ func parseInterrupts(r io.Reader) (Interrupts, error) {
|
||||
continue
|
||||
}
|
||||
if len(parts) < 2 {
|
||||
return nil, fmt.Errorf("not enough fields in interrupts (expected at least 2 fields but got %d): %s", len(parts), parts)
|
||||
return nil, fmt.Errorf("%w: Not enough fields in interrupts (expected 2+ fields but got %d): %s", ErrFileParse, len(parts), parts)
|
||||
}
|
||||
intName := parts[0][:len(parts[0])-1] // remove trailing :
|
||||
|
||||
|
||||
4
vendor/github.com/prometheus/procfs/proc_io.go
generated
vendored
4
vendor/github.com/prometheus/procfs/proc_io.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2018 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -50,7 +50,7 @@ func (p Proc) IO() (ProcIO, error) {
|
||||
|
||||
ioFormat := "rchar: %d\nwchar: %d\nsyscr: %d\nsyscw: %d\n" +
|
||||
"read_bytes: %d\nwrite_bytes: %d\n" +
|
||||
"cancelled_write_bytes: %d\n"
|
||||
"cancelled_write_bytes: %d\n" //nolint:misspell
|
||||
|
||||
_, err = fmt.Sscanf(string(data), ioFormat, &pio.RChar, &pio.WChar, &pio.SyscR,
|
||||
&pio.SyscW, &pio.ReadBytes, &pio.WriteBytes, &pio.CancelledWriteBytes)
|
||||
|
||||
11
vendor/github.com/prometheus/procfs/proc_limits.go
generated
vendored
11
vendor/github.com/prometheus/procfs/proc_limits.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2018 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ProcLimits represents the soft limits for each of the process's resource
|
||||
@@ -74,7 +75,7 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
limitsMatch = regexp.MustCompile(`(Max \w+\s{0,1}?\w*\s{0,1}\w*)\s{2,}(\w+)\s+(\w+)`)
|
||||
limitsMatch = regexp.MustCompile(`(Max \w+\s??\w*\s?\w*)\s{2,}(\w+)\s+(\w+)`)
|
||||
)
|
||||
|
||||
// NewLimits returns the current soft limits of the process.
|
||||
@@ -103,10 +104,10 @@ func (p Proc) Limits() (ProcLimits, error) {
|
||||
//fields := limitsMatch.Split(s.Text(), limitsFields)
|
||||
fields := limitsMatch.FindStringSubmatch(s.Text())
|
||||
if len(fields) != limitsFields {
|
||||
return ProcLimits{}, fmt.Errorf("couldn't parse %q line %q", f.Name(), s.Text())
|
||||
return ProcLimits{}, fmt.Errorf("%w: couldn't parse %q line %q", ErrFileParse, f.Name(), s.Text())
|
||||
}
|
||||
|
||||
switch fields[1] {
|
||||
switch strings.TrimSpace(fields[1]) {
|
||||
case "Max cpu time":
|
||||
l.CPUTime, err = parseUint(fields[2])
|
||||
case "Max file size":
|
||||
@@ -154,7 +155,7 @@ func parseUint(s string) (uint64, error) {
|
||||
}
|
||||
i, err := strconv.ParseUint(s, 10, 64)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("couldn't parse value %q: %w", s, err)
|
||||
return 0, fmt.Errorf("%w: couldn't parse value %q: %w", ErrFileParse, s, err)
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
26
vendor/github.com/prometheus/procfs/proc_maps.go
generated
vendored
26
vendor/github.com/prometheus/procfs/proc_maps.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -63,17 +63,17 @@ type ProcMap struct {
|
||||
// parseDevice parses the device token of a line and converts it to a dev_t
|
||||
// (mkdev) like structure.
|
||||
func parseDevice(s string) (uint64, error) {
|
||||
toks := strings.Split(s, ":")
|
||||
if len(toks) < 2 {
|
||||
return 0, fmt.Errorf("unexpected number of fields")
|
||||
i := strings.Index(s, ":")
|
||||
if i == -1 {
|
||||
return 0, fmt.Errorf("%w: expected separator `:` in %s", ErrFileParse, s)
|
||||
}
|
||||
|
||||
major, err := strconv.ParseUint(toks[0], 16, 0)
|
||||
major, err := strconv.ParseUint(s[0:i], 16, 0)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
minor, err := strconv.ParseUint(toks[1], 16, 0)
|
||||
minor, err := strconv.ParseUint(s[i+1:], 16, 0)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -93,17 +93,17 @@ func parseAddress(s string) (uintptr, error) {
|
||||
|
||||
// parseAddresses parses the start-end address.
|
||||
func parseAddresses(s string) (uintptr, uintptr, error) {
|
||||
toks := strings.Split(s, "-")
|
||||
if len(toks) < 2 {
|
||||
return 0, 0, fmt.Errorf("invalid address")
|
||||
idx := strings.Index(s, "-")
|
||||
if idx == -1 {
|
||||
return 0, 0, fmt.Errorf("%w: expected separator `-` in %s", ErrFileParse, s)
|
||||
}
|
||||
|
||||
saddr, err := parseAddress(toks[0])
|
||||
saddr, err := parseAddress(s[0:idx])
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
eaddr, err := parseAddress(toks[1])
|
||||
eaddr, err := parseAddress(s[idx+1:])
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
@@ -114,7 +114,7 @@ func parseAddresses(s string) (uintptr, uintptr, error) {
|
||||
// parsePermissions parses a token and returns any that are set.
|
||||
func parsePermissions(s string) (*ProcMapPermissions, error) {
|
||||
if len(s) < 4 {
|
||||
return nil, fmt.Errorf("invalid permissions token")
|
||||
return nil, fmt.Errorf("%w: invalid permissions token", ErrFileParse)
|
||||
}
|
||||
|
||||
perms := ProcMapPermissions{}
|
||||
@@ -141,7 +141,7 @@ func parsePermissions(s string) (*ProcMapPermissions, error) {
|
||||
func parseProcMap(text string) (*ProcMap, error) {
|
||||
fields := strings.Fields(text)
|
||||
if len(fields) < 5 {
|
||||
return nil, fmt.Errorf("truncated procmap entry")
|
||||
return nil, fmt.Errorf("%w: truncated procmap entry", ErrFileParse)
|
||||
}
|
||||
|
||||
saddr, eaddr, err := parseAddresses(fields[0])
|
||||
|
||||
230
vendor/github.com/prometheus/procfs/proc_netstat.go
generated
vendored
230
vendor/github.com/prometheus/procfs/proc_netstat.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -195,8 +195,8 @@ func parseProcNetstat(r io.Reader, fileName string) (ProcNetstat, error) {
|
||||
// Remove trailing :.
|
||||
protocol := strings.TrimSuffix(nameParts[0], ":")
|
||||
if len(nameParts) != len(valueParts) {
|
||||
return procNetstat, fmt.Errorf("mismatch field count mismatch in %s: %s",
|
||||
fileName, protocol)
|
||||
return procNetstat, fmt.Errorf("%w: mismatch field count mismatch in %s: %s",
|
||||
ErrFileParse, fileName, protocol)
|
||||
}
|
||||
for i := 1; i < len(nameParts); i++ {
|
||||
value, err := strconv.ParseFloat(valueParts[i], 64)
|
||||
@@ -209,232 +209,232 @@ func parseProcNetstat(r io.Reader, fileName string) (ProcNetstat, error) {
|
||||
case "TcpExt":
|
||||
switch key {
|
||||
case "SyncookiesSent":
|
||||
procNetstat.TcpExt.SyncookiesSent = &value
|
||||
procNetstat.SyncookiesSent = &value
|
||||
case "SyncookiesRecv":
|
||||
procNetstat.TcpExt.SyncookiesRecv = &value
|
||||
procNetstat.SyncookiesRecv = &value
|
||||
case "SyncookiesFailed":
|
||||
procNetstat.TcpExt.SyncookiesFailed = &value
|
||||
procNetstat.SyncookiesFailed = &value
|
||||
case "EmbryonicRsts":
|
||||
procNetstat.TcpExt.EmbryonicRsts = &value
|
||||
procNetstat.EmbryonicRsts = &value
|
||||
case "PruneCalled":
|
||||
procNetstat.TcpExt.PruneCalled = &value
|
||||
procNetstat.PruneCalled = &value
|
||||
case "RcvPruned":
|
||||
procNetstat.TcpExt.RcvPruned = &value
|
||||
procNetstat.RcvPruned = &value
|
||||
case "OfoPruned":
|
||||
procNetstat.TcpExt.OfoPruned = &value
|
||||
procNetstat.OfoPruned = &value
|
||||
case "OutOfWindowIcmps":
|
||||
procNetstat.TcpExt.OutOfWindowIcmps = &value
|
||||
procNetstat.OutOfWindowIcmps = &value
|
||||
case "LockDroppedIcmps":
|
||||
procNetstat.TcpExt.LockDroppedIcmps = &value
|
||||
procNetstat.LockDroppedIcmps = &value
|
||||
case "ArpFilter":
|
||||
procNetstat.TcpExt.ArpFilter = &value
|
||||
procNetstat.ArpFilter = &value
|
||||
case "TW":
|
||||
procNetstat.TcpExt.TW = &value
|
||||
procNetstat.TW = &value
|
||||
case "TWRecycled":
|
||||
procNetstat.TcpExt.TWRecycled = &value
|
||||
procNetstat.TWRecycled = &value
|
||||
case "TWKilled":
|
||||
procNetstat.TcpExt.TWKilled = &value
|
||||
procNetstat.TWKilled = &value
|
||||
case "PAWSActive":
|
||||
procNetstat.TcpExt.PAWSActive = &value
|
||||
procNetstat.PAWSActive = &value
|
||||
case "PAWSEstab":
|
||||
procNetstat.TcpExt.PAWSEstab = &value
|
||||
procNetstat.PAWSEstab = &value
|
||||
case "DelayedACKs":
|
||||
procNetstat.TcpExt.DelayedACKs = &value
|
||||
procNetstat.DelayedACKs = &value
|
||||
case "DelayedACKLocked":
|
||||
procNetstat.TcpExt.DelayedACKLocked = &value
|
||||
procNetstat.DelayedACKLocked = &value
|
||||
case "DelayedACKLost":
|
||||
procNetstat.TcpExt.DelayedACKLost = &value
|
||||
procNetstat.DelayedACKLost = &value
|
||||
case "ListenOverflows":
|
||||
procNetstat.TcpExt.ListenOverflows = &value
|
||||
procNetstat.ListenOverflows = &value
|
||||
case "ListenDrops":
|
||||
procNetstat.TcpExt.ListenDrops = &value
|
||||
procNetstat.ListenDrops = &value
|
||||
case "TCPHPHits":
|
||||
procNetstat.TcpExt.TCPHPHits = &value
|
||||
procNetstat.TCPHPHits = &value
|
||||
case "TCPPureAcks":
|
||||
procNetstat.TcpExt.TCPPureAcks = &value
|
||||
procNetstat.TCPPureAcks = &value
|
||||
case "TCPHPAcks":
|
||||
procNetstat.TcpExt.TCPHPAcks = &value
|
||||
procNetstat.TCPHPAcks = &value
|
||||
case "TCPRenoRecovery":
|
||||
procNetstat.TcpExt.TCPRenoRecovery = &value
|
||||
procNetstat.TCPRenoRecovery = &value
|
||||
case "TCPSackRecovery":
|
||||
procNetstat.TcpExt.TCPSackRecovery = &value
|
||||
procNetstat.TCPSackRecovery = &value
|
||||
case "TCPSACKReneging":
|
||||
procNetstat.TcpExt.TCPSACKReneging = &value
|
||||
procNetstat.TCPSACKReneging = &value
|
||||
case "TCPSACKReorder":
|
||||
procNetstat.TcpExt.TCPSACKReorder = &value
|
||||
procNetstat.TCPSACKReorder = &value
|
||||
case "TCPRenoReorder":
|
||||
procNetstat.TcpExt.TCPRenoReorder = &value
|
||||
procNetstat.TCPRenoReorder = &value
|
||||
case "TCPTSReorder":
|
||||
procNetstat.TcpExt.TCPTSReorder = &value
|
||||
procNetstat.TCPTSReorder = &value
|
||||
case "TCPFullUndo":
|
||||
procNetstat.TcpExt.TCPFullUndo = &value
|
||||
procNetstat.TCPFullUndo = &value
|
||||
case "TCPPartialUndo":
|
||||
procNetstat.TcpExt.TCPPartialUndo = &value
|
||||
procNetstat.TCPPartialUndo = &value
|
||||
case "TCPDSACKUndo":
|
||||
procNetstat.TcpExt.TCPDSACKUndo = &value
|
||||
procNetstat.TCPDSACKUndo = &value
|
||||
case "TCPLossUndo":
|
||||
procNetstat.TcpExt.TCPLossUndo = &value
|
||||
procNetstat.TCPLossUndo = &value
|
||||
case "TCPLostRetransmit":
|
||||
procNetstat.TcpExt.TCPLostRetransmit = &value
|
||||
procNetstat.TCPLostRetransmit = &value
|
||||
case "TCPRenoFailures":
|
||||
procNetstat.TcpExt.TCPRenoFailures = &value
|
||||
procNetstat.TCPRenoFailures = &value
|
||||
case "TCPSackFailures":
|
||||
procNetstat.TcpExt.TCPSackFailures = &value
|
||||
procNetstat.TCPSackFailures = &value
|
||||
case "TCPLossFailures":
|
||||
procNetstat.TcpExt.TCPLossFailures = &value
|
||||
procNetstat.TCPLossFailures = &value
|
||||
case "TCPFastRetrans":
|
||||
procNetstat.TcpExt.TCPFastRetrans = &value
|
||||
procNetstat.TCPFastRetrans = &value
|
||||
case "TCPSlowStartRetrans":
|
||||
procNetstat.TcpExt.TCPSlowStartRetrans = &value
|
||||
procNetstat.TCPSlowStartRetrans = &value
|
||||
case "TCPTimeouts":
|
||||
procNetstat.TcpExt.TCPTimeouts = &value
|
||||
procNetstat.TCPTimeouts = &value
|
||||
case "TCPLossProbes":
|
||||
procNetstat.TcpExt.TCPLossProbes = &value
|
||||
procNetstat.TCPLossProbes = &value
|
||||
case "TCPLossProbeRecovery":
|
||||
procNetstat.TcpExt.TCPLossProbeRecovery = &value
|
||||
procNetstat.TCPLossProbeRecovery = &value
|
||||
case "TCPRenoRecoveryFail":
|
||||
procNetstat.TcpExt.TCPRenoRecoveryFail = &value
|
||||
procNetstat.TCPRenoRecoveryFail = &value
|
||||
case "TCPSackRecoveryFail":
|
||||
procNetstat.TcpExt.TCPSackRecoveryFail = &value
|
||||
procNetstat.TCPSackRecoveryFail = &value
|
||||
case "TCPRcvCollapsed":
|
||||
procNetstat.TcpExt.TCPRcvCollapsed = &value
|
||||
procNetstat.TCPRcvCollapsed = &value
|
||||
case "TCPDSACKOldSent":
|
||||
procNetstat.TcpExt.TCPDSACKOldSent = &value
|
||||
procNetstat.TCPDSACKOldSent = &value
|
||||
case "TCPDSACKOfoSent":
|
||||
procNetstat.TcpExt.TCPDSACKOfoSent = &value
|
||||
procNetstat.TCPDSACKOfoSent = &value
|
||||
case "TCPDSACKRecv":
|
||||
procNetstat.TcpExt.TCPDSACKRecv = &value
|
||||
procNetstat.TCPDSACKRecv = &value
|
||||
case "TCPDSACKOfoRecv":
|
||||
procNetstat.TcpExt.TCPDSACKOfoRecv = &value
|
||||
procNetstat.TCPDSACKOfoRecv = &value
|
||||
case "TCPAbortOnData":
|
||||
procNetstat.TcpExt.TCPAbortOnData = &value
|
||||
procNetstat.TCPAbortOnData = &value
|
||||
case "TCPAbortOnClose":
|
||||
procNetstat.TcpExt.TCPAbortOnClose = &value
|
||||
procNetstat.TCPAbortOnClose = &value
|
||||
case "TCPDeferAcceptDrop":
|
||||
procNetstat.TcpExt.TCPDeferAcceptDrop = &value
|
||||
procNetstat.TCPDeferAcceptDrop = &value
|
||||
case "IPReversePathFilter":
|
||||
procNetstat.TcpExt.IPReversePathFilter = &value
|
||||
procNetstat.IPReversePathFilter = &value
|
||||
case "TCPTimeWaitOverflow":
|
||||
procNetstat.TcpExt.TCPTimeWaitOverflow = &value
|
||||
procNetstat.TCPTimeWaitOverflow = &value
|
||||
case "TCPReqQFullDoCookies":
|
||||
procNetstat.TcpExt.TCPReqQFullDoCookies = &value
|
||||
procNetstat.TCPReqQFullDoCookies = &value
|
||||
case "TCPReqQFullDrop":
|
||||
procNetstat.TcpExt.TCPReqQFullDrop = &value
|
||||
procNetstat.TCPReqQFullDrop = &value
|
||||
case "TCPRetransFail":
|
||||
procNetstat.TcpExt.TCPRetransFail = &value
|
||||
procNetstat.TCPRetransFail = &value
|
||||
case "TCPRcvCoalesce":
|
||||
procNetstat.TcpExt.TCPRcvCoalesce = &value
|
||||
procNetstat.TCPRcvCoalesce = &value
|
||||
case "TCPRcvQDrop":
|
||||
procNetstat.TcpExt.TCPRcvQDrop = &value
|
||||
procNetstat.TCPRcvQDrop = &value
|
||||
case "TCPOFOQueue":
|
||||
procNetstat.TcpExt.TCPOFOQueue = &value
|
||||
procNetstat.TCPOFOQueue = &value
|
||||
case "TCPOFODrop":
|
||||
procNetstat.TcpExt.TCPOFODrop = &value
|
||||
procNetstat.TCPOFODrop = &value
|
||||
case "TCPOFOMerge":
|
||||
procNetstat.TcpExt.TCPOFOMerge = &value
|
||||
procNetstat.TCPOFOMerge = &value
|
||||
case "TCPChallengeACK":
|
||||
procNetstat.TcpExt.TCPChallengeACK = &value
|
||||
procNetstat.TCPChallengeACK = &value
|
||||
case "TCPSYNChallenge":
|
||||
procNetstat.TcpExt.TCPSYNChallenge = &value
|
||||
procNetstat.TCPSYNChallenge = &value
|
||||
case "TCPFastOpenActive":
|
||||
procNetstat.TcpExt.TCPFastOpenActive = &value
|
||||
procNetstat.TCPFastOpenActive = &value
|
||||
case "TCPFastOpenActiveFail":
|
||||
procNetstat.TcpExt.TCPFastOpenActiveFail = &value
|
||||
procNetstat.TCPFastOpenActiveFail = &value
|
||||
case "TCPFastOpenPassive":
|
||||
procNetstat.TcpExt.TCPFastOpenPassive = &value
|
||||
procNetstat.TCPFastOpenPassive = &value
|
||||
case "TCPFastOpenPassiveFail":
|
||||
procNetstat.TcpExt.TCPFastOpenPassiveFail = &value
|
||||
procNetstat.TCPFastOpenPassiveFail = &value
|
||||
case "TCPFastOpenListenOverflow":
|
||||
procNetstat.TcpExt.TCPFastOpenListenOverflow = &value
|
||||
procNetstat.TCPFastOpenListenOverflow = &value
|
||||
case "TCPFastOpenCookieReqd":
|
||||
procNetstat.TcpExt.TCPFastOpenCookieReqd = &value
|
||||
procNetstat.TCPFastOpenCookieReqd = &value
|
||||
case "TCPFastOpenBlackhole":
|
||||
procNetstat.TcpExt.TCPFastOpenBlackhole = &value
|
||||
procNetstat.TCPFastOpenBlackhole = &value
|
||||
case "TCPSpuriousRtxHostQueues":
|
||||
procNetstat.TcpExt.TCPSpuriousRtxHostQueues = &value
|
||||
procNetstat.TCPSpuriousRtxHostQueues = &value
|
||||
case "BusyPollRxPackets":
|
||||
procNetstat.TcpExt.BusyPollRxPackets = &value
|
||||
procNetstat.BusyPollRxPackets = &value
|
||||
case "TCPAutoCorking":
|
||||
procNetstat.TcpExt.TCPAutoCorking = &value
|
||||
procNetstat.TCPAutoCorking = &value
|
||||
case "TCPFromZeroWindowAdv":
|
||||
procNetstat.TcpExt.TCPFromZeroWindowAdv = &value
|
||||
procNetstat.TCPFromZeroWindowAdv = &value
|
||||
case "TCPToZeroWindowAdv":
|
||||
procNetstat.TcpExt.TCPToZeroWindowAdv = &value
|
||||
procNetstat.TCPToZeroWindowAdv = &value
|
||||
case "TCPWantZeroWindowAdv":
|
||||
procNetstat.TcpExt.TCPWantZeroWindowAdv = &value
|
||||
procNetstat.TCPWantZeroWindowAdv = &value
|
||||
case "TCPSynRetrans":
|
||||
procNetstat.TcpExt.TCPSynRetrans = &value
|
||||
procNetstat.TCPSynRetrans = &value
|
||||
case "TCPOrigDataSent":
|
||||
procNetstat.TcpExt.TCPOrigDataSent = &value
|
||||
procNetstat.TCPOrigDataSent = &value
|
||||
case "TCPHystartTrainDetect":
|
||||
procNetstat.TcpExt.TCPHystartTrainDetect = &value
|
||||
procNetstat.TCPHystartTrainDetect = &value
|
||||
case "TCPHystartTrainCwnd":
|
||||
procNetstat.TcpExt.TCPHystartTrainCwnd = &value
|
||||
procNetstat.TCPHystartTrainCwnd = &value
|
||||
case "TCPHystartDelayDetect":
|
||||
procNetstat.TcpExt.TCPHystartDelayDetect = &value
|
||||
procNetstat.TCPHystartDelayDetect = &value
|
||||
case "TCPHystartDelayCwnd":
|
||||
procNetstat.TcpExt.TCPHystartDelayCwnd = &value
|
||||
procNetstat.TCPHystartDelayCwnd = &value
|
||||
case "TCPACKSkippedSynRecv":
|
||||
procNetstat.TcpExt.TCPACKSkippedSynRecv = &value
|
||||
procNetstat.TCPACKSkippedSynRecv = &value
|
||||
case "TCPACKSkippedPAWS":
|
||||
procNetstat.TcpExt.TCPACKSkippedPAWS = &value
|
||||
procNetstat.TCPACKSkippedPAWS = &value
|
||||
case "TCPACKSkippedSeq":
|
||||
procNetstat.TcpExt.TCPACKSkippedSeq = &value
|
||||
procNetstat.TCPACKSkippedSeq = &value
|
||||
case "TCPACKSkippedFinWait2":
|
||||
procNetstat.TcpExt.TCPACKSkippedFinWait2 = &value
|
||||
procNetstat.TCPACKSkippedFinWait2 = &value
|
||||
case "TCPACKSkippedTimeWait":
|
||||
procNetstat.TcpExt.TCPACKSkippedTimeWait = &value
|
||||
procNetstat.TCPACKSkippedTimeWait = &value
|
||||
case "TCPACKSkippedChallenge":
|
||||
procNetstat.TcpExt.TCPACKSkippedChallenge = &value
|
||||
procNetstat.TCPACKSkippedChallenge = &value
|
||||
case "TCPWinProbe":
|
||||
procNetstat.TcpExt.TCPWinProbe = &value
|
||||
procNetstat.TCPWinProbe = &value
|
||||
case "TCPKeepAlive":
|
||||
procNetstat.TcpExt.TCPKeepAlive = &value
|
||||
procNetstat.TCPKeepAlive = &value
|
||||
case "TCPMTUPFail":
|
||||
procNetstat.TcpExt.TCPMTUPFail = &value
|
||||
procNetstat.TCPMTUPFail = &value
|
||||
case "TCPMTUPSuccess":
|
||||
procNetstat.TcpExt.TCPMTUPSuccess = &value
|
||||
procNetstat.TCPMTUPSuccess = &value
|
||||
case "TCPWqueueTooBig":
|
||||
procNetstat.TcpExt.TCPWqueueTooBig = &value
|
||||
procNetstat.TCPWqueueTooBig = &value
|
||||
}
|
||||
case "IpExt":
|
||||
switch key {
|
||||
case "InNoRoutes":
|
||||
procNetstat.IpExt.InNoRoutes = &value
|
||||
procNetstat.InNoRoutes = &value
|
||||
case "InTruncatedPkts":
|
||||
procNetstat.IpExt.InTruncatedPkts = &value
|
||||
procNetstat.InTruncatedPkts = &value
|
||||
case "InMcastPkts":
|
||||
procNetstat.IpExt.InMcastPkts = &value
|
||||
procNetstat.InMcastPkts = &value
|
||||
case "OutMcastPkts":
|
||||
procNetstat.IpExt.OutMcastPkts = &value
|
||||
procNetstat.OutMcastPkts = &value
|
||||
case "InBcastPkts":
|
||||
procNetstat.IpExt.InBcastPkts = &value
|
||||
procNetstat.InBcastPkts = &value
|
||||
case "OutBcastPkts":
|
||||
procNetstat.IpExt.OutBcastPkts = &value
|
||||
procNetstat.OutBcastPkts = &value
|
||||
case "InOctets":
|
||||
procNetstat.IpExt.InOctets = &value
|
||||
procNetstat.InOctets = &value
|
||||
case "OutOctets":
|
||||
procNetstat.IpExt.OutOctets = &value
|
||||
procNetstat.OutOctets = &value
|
||||
case "InMcastOctets":
|
||||
procNetstat.IpExt.InMcastOctets = &value
|
||||
procNetstat.InMcastOctets = &value
|
||||
case "OutMcastOctets":
|
||||
procNetstat.IpExt.OutMcastOctets = &value
|
||||
procNetstat.OutMcastOctets = &value
|
||||
case "InBcastOctets":
|
||||
procNetstat.IpExt.InBcastOctets = &value
|
||||
procNetstat.InBcastOctets = &value
|
||||
case "OutBcastOctets":
|
||||
procNetstat.IpExt.OutBcastOctets = &value
|
||||
procNetstat.OutBcastOctets = &value
|
||||
case "InCsumErrors":
|
||||
procNetstat.IpExt.InCsumErrors = &value
|
||||
procNetstat.InCsumErrors = &value
|
||||
case "InNoECTPkts":
|
||||
procNetstat.IpExt.InNoECTPkts = &value
|
||||
procNetstat.InNoECTPkts = &value
|
||||
case "InECT1Pkts":
|
||||
procNetstat.IpExt.InECT1Pkts = &value
|
||||
procNetstat.InECT1Pkts = &value
|
||||
case "InECT0Pkts":
|
||||
procNetstat.IpExt.InECT0Pkts = &value
|
||||
procNetstat.InECT0Pkts = &value
|
||||
case "InCEPkts":
|
||||
procNetstat.IpExt.InCEPkts = &value
|
||||
procNetstat.InCEPkts = &value
|
||||
case "ReasmOverlaps":
|
||||
procNetstat.IpExt.ReasmOverlaps = &value
|
||||
procNetstat.ReasmOverlaps = &value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
8
vendor/github.com/prometheus/procfs/proc_ns.go
generated
vendored
8
vendor/github.com/prometheus/procfs/proc_ns.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2018 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -40,7 +40,7 @@ func (p Proc) Namespaces() (Namespaces, error) {
|
||||
|
||||
names, err := d.Readdirnames(-1)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read contents of ns dir: %w", err)
|
||||
return nil, fmt.Errorf("%w: failed to read contents of ns dir: %w", ErrFileRead, err)
|
||||
}
|
||||
|
||||
ns := make(Namespaces, len(names))
|
||||
@@ -52,13 +52,13 @@ func (p Proc) Namespaces() (Namespaces, error) {
|
||||
|
||||
fields := strings.SplitN(target, ":", 2)
|
||||
if len(fields) != 2 {
|
||||
return nil, fmt.Errorf("failed to parse namespace type and inode from %q", target)
|
||||
return nil, fmt.Errorf("%w: namespace type and inode from %q", ErrFileParse, target)
|
||||
}
|
||||
|
||||
typ := fields[0]
|
||||
inode, err := strconv.ParseUint(strings.Trim(fields[1], "[]"), 10, 32)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse inode from %q: %w", fields[1], err)
|
||||
return nil, fmt.Errorf("%w: inode from %q: %w", ErrFileParse, fields[1], err)
|
||||
}
|
||||
|
||||
ns[name] = Namespace{typ, uint32(inode)}
|
||||
|
||||
8
vendor/github.com/prometheus/procfs/proc_psi.go
generated
vendored
8
vendor/github.com/prometheus/procfs/proc_psi.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -61,14 +61,14 @@ type PSIStats struct {
|
||||
func (fs FS) PSIStatsForResource(resource string) (PSIStats, error) {
|
||||
data, err := util.ReadFileNoStat(fs.proc.Path(fmt.Sprintf("%s/%s", "pressure", resource)))
|
||||
if err != nil {
|
||||
return PSIStats{}, fmt.Errorf("psi_stats: unavailable for %q: %w", resource, err)
|
||||
return PSIStats{}, fmt.Errorf("%w: psi_stats: unavailable for %q: %w", ErrFileRead, resource, err)
|
||||
}
|
||||
|
||||
return parsePSIStats(resource, bytes.NewReader(data))
|
||||
return parsePSIStats(bytes.NewReader(data))
|
||||
}
|
||||
|
||||
// parsePSIStats parses the specified file for pressure stall information.
|
||||
func parsePSIStats(resource string, r io.Reader) (PSIStats, error) {
|
||||
func parsePSIStats(r io.Reader) (PSIStats, error) {
|
||||
psiStats := PSIStats{}
|
||||
|
||||
scanner := bufio.NewScanner(r)
|
||||
|
||||
12
vendor/github.com/prometheus/procfs/proc_smaps.go
generated
vendored
12
vendor/github.com/prometheus/procfs/proc_smaps.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -19,7 +19,6 @@ package procfs
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
@@ -29,7 +28,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
// match the header line before each mapped zone in `/proc/pid/smaps`.
|
||||
// Match the header line before each mapped zone in `/proc/pid/smaps`.
|
||||
procSMapsHeaderLine = regexp.MustCompile(`^[a-f0-9].*$`)
|
||||
)
|
||||
|
||||
@@ -117,7 +116,6 @@ func (p Proc) procSMapsRollupManual() (ProcSMapsRollup, error) {
|
||||
func (s *ProcSMapsRollup) parseLine(line string) error {
|
||||
kv := strings.SplitN(line, ":", 2)
|
||||
if len(kv) != 2 {
|
||||
fmt.Println(line)
|
||||
return errors.New("invalid net/dev line, missing colon")
|
||||
}
|
||||
|
||||
@@ -127,7 +125,7 @@ func (s *ProcSMapsRollup) parseLine(line string) error {
|
||||
}
|
||||
|
||||
v := strings.TrimSpace(kv[1])
|
||||
v = strings.TrimRight(v, " kB")
|
||||
v = strings.TrimSuffix(v, " kB")
|
||||
|
||||
vKBytes, err := strconv.ParseUint(v, 10, 64)
|
||||
if err != nil {
|
||||
@@ -135,12 +133,12 @@ func (s *ProcSMapsRollup) parseLine(line string) error {
|
||||
}
|
||||
vBytes := vKBytes * 1024
|
||||
|
||||
s.addValue(k, v, vKBytes, vBytes)
|
||||
s.addValue(k, vBytes)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ProcSMapsRollup) addValue(k string, vString string, vUint uint64, vUintBytes uint64) {
|
||||
func (s *ProcSMapsRollup) addValue(k string, vUintBytes uint64) {
|
||||
switch k {
|
||||
case "Rss":
|
||||
s.Rss += vUintBytes
|
||||
|
||||
126
vendor/github.com/prometheus/procfs/proc_snmp.go
generated
vendored
126
vendor/github.com/prometheus/procfs/proc_snmp.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -159,8 +159,8 @@ func parseSnmp(r io.Reader, fileName string) (ProcSnmp, error) {
|
||||
// Remove trailing :.
|
||||
protocol := strings.TrimSuffix(nameParts[0], ":")
|
||||
if len(nameParts) != len(valueParts) {
|
||||
return procSnmp, fmt.Errorf("mismatch field count mismatch in %s: %s",
|
||||
fileName, protocol)
|
||||
return procSnmp, fmt.Errorf("%w: mismatch field count mismatch in %s: %s",
|
||||
ErrFileParse, fileName, protocol)
|
||||
}
|
||||
for i := 1; i < len(nameParts); i++ {
|
||||
value, err := strconv.ParseFloat(valueParts[i], 64)
|
||||
@@ -173,138 +173,138 @@ func parseSnmp(r io.Reader, fileName string) (ProcSnmp, error) {
|
||||
case "Ip":
|
||||
switch key {
|
||||
case "Forwarding":
|
||||
procSnmp.Ip.Forwarding = &value
|
||||
procSnmp.Forwarding = &value
|
||||
case "DefaultTTL":
|
||||
procSnmp.Ip.DefaultTTL = &value
|
||||
procSnmp.DefaultTTL = &value
|
||||
case "InReceives":
|
||||
procSnmp.Ip.InReceives = &value
|
||||
procSnmp.InReceives = &value
|
||||
case "InHdrErrors":
|
||||
procSnmp.Ip.InHdrErrors = &value
|
||||
procSnmp.InHdrErrors = &value
|
||||
case "InAddrErrors":
|
||||
procSnmp.Ip.InAddrErrors = &value
|
||||
procSnmp.InAddrErrors = &value
|
||||
case "ForwDatagrams":
|
||||
procSnmp.Ip.ForwDatagrams = &value
|
||||
procSnmp.ForwDatagrams = &value
|
||||
case "InUnknownProtos":
|
||||
procSnmp.Ip.InUnknownProtos = &value
|
||||
procSnmp.InUnknownProtos = &value
|
||||
case "InDiscards":
|
||||
procSnmp.Ip.InDiscards = &value
|
||||
procSnmp.InDiscards = &value
|
||||
case "InDelivers":
|
||||
procSnmp.Ip.InDelivers = &value
|
||||
procSnmp.InDelivers = &value
|
||||
case "OutRequests":
|
||||
procSnmp.Ip.OutRequests = &value
|
||||
procSnmp.OutRequests = &value
|
||||
case "OutDiscards":
|
||||
procSnmp.Ip.OutDiscards = &value
|
||||
procSnmp.OutDiscards = &value
|
||||
case "OutNoRoutes":
|
||||
procSnmp.Ip.OutNoRoutes = &value
|
||||
procSnmp.OutNoRoutes = &value
|
||||
case "ReasmTimeout":
|
||||
procSnmp.Ip.ReasmTimeout = &value
|
||||
procSnmp.ReasmTimeout = &value
|
||||
case "ReasmReqds":
|
||||
procSnmp.Ip.ReasmReqds = &value
|
||||
procSnmp.ReasmReqds = &value
|
||||
case "ReasmOKs":
|
||||
procSnmp.Ip.ReasmOKs = &value
|
||||
procSnmp.ReasmOKs = &value
|
||||
case "ReasmFails":
|
||||
procSnmp.Ip.ReasmFails = &value
|
||||
procSnmp.ReasmFails = &value
|
||||
case "FragOKs":
|
||||
procSnmp.Ip.FragOKs = &value
|
||||
procSnmp.FragOKs = &value
|
||||
case "FragFails":
|
||||
procSnmp.Ip.FragFails = &value
|
||||
procSnmp.FragFails = &value
|
||||
case "FragCreates":
|
||||
procSnmp.Ip.FragCreates = &value
|
||||
procSnmp.FragCreates = &value
|
||||
}
|
||||
case "Icmp":
|
||||
switch key {
|
||||
case "InMsgs":
|
||||
procSnmp.Icmp.InMsgs = &value
|
||||
procSnmp.InMsgs = &value
|
||||
case "InErrors":
|
||||
procSnmp.Icmp.InErrors = &value
|
||||
case "InCsumErrors":
|
||||
procSnmp.Icmp.InCsumErrors = &value
|
||||
case "InDestUnreachs":
|
||||
procSnmp.Icmp.InDestUnreachs = &value
|
||||
procSnmp.InDestUnreachs = &value
|
||||
case "InTimeExcds":
|
||||
procSnmp.Icmp.InTimeExcds = &value
|
||||
procSnmp.InTimeExcds = &value
|
||||
case "InParmProbs":
|
||||
procSnmp.Icmp.InParmProbs = &value
|
||||
procSnmp.InParmProbs = &value
|
||||
case "InSrcQuenchs":
|
||||
procSnmp.Icmp.InSrcQuenchs = &value
|
||||
procSnmp.InSrcQuenchs = &value
|
||||
case "InRedirects":
|
||||
procSnmp.Icmp.InRedirects = &value
|
||||
procSnmp.InRedirects = &value
|
||||
case "InEchos":
|
||||
procSnmp.Icmp.InEchos = &value
|
||||
procSnmp.InEchos = &value
|
||||
case "InEchoReps":
|
||||
procSnmp.Icmp.InEchoReps = &value
|
||||
procSnmp.InEchoReps = &value
|
||||
case "InTimestamps":
|
||||
procSnmp.Icmp.InTimestamps = &value
|
||||
procSnmp.InTimestamps = &value
|
||||
case "InTimestampReps":
|
||||
procSnmp.Icmp.InTimestampReps = &value
|
||||
procSnmp.InTimestampReps = &value
|
||||
case "InAddrMasks":
|
||||
procSnmp.Icmp.InAddrMasks = &value
|
||||
procSnmp.InAddrMasks = &value
|
||||
case "InAddrMaskReps":
|
||||
procSnmp.Icmp.InAddrMaskReps = &value
|
||||
procSnmp.InAddrMaskReps = &value
|
||||
case "OutMsgs":
|
||||
procSnmp.Icmp.OutMsgs = &value
|
||||
procSnmp.OutMsgs = &value
|
||||
case "OutErrors":
|
||||
procSnmp.Icmp.OutErrors = &value
|
||||
procSnmp.OutErrors = &value
|
||||
case "OutDestUnreachs":
|
||||
procSnmp.Icmp.OutDestUnreachs = &value
|
||||
procSnmp.OutDestUnreachs = &value
|
||||
case "OutTimeExcds":
|
||||
procSnmp.Icmp.OutTimeExcds = &value
|
||||
procSnmp.OutTimeExcds = &value
|
||||
case "OutParmProbs":
|
||||
procSnmp.Icmp.OutParmProbs = &value
|
||||
procSnmp.OutParmProbs = &value
|
||||
case "OutSrcQuenchs":
|
||||
procSnmp.Icmp.OutSrcQuenchs = &value
|
||||
procSnmp.OutSrcQuenchs = &value
|
||||
case "OutRedirects":
|
||||
procSnmp.Icmp.OutRedirects = &value
|
||||
procSnmp.OutRedirects = &value
|
||||
case "OutEchos":
|
||||
procSnmp.Icmp.OutEchos = &value
|
||||
procSnmp.OutEchos = &value
|
||||
case "OutEchoReps":
|
||||
procSnmp.Icmp.OutEchoReps = &value
|
||||
procSnmp.OutEchoReps = &value
|
||||
case "OutTimestamps":
|
||||
procSnmp.Icmp.OutTimestamps = &value
|
||||
procSnmp.OutTimestamps = &value
|
||||
case "OutTimestampReps":
|
||||
procSnmp.Icmp.OutTimestampReps = &value
|
||||
procSnmp.OutTimestampReps = &value
|
||||
case "OutAddrMasks":
|
||||
procSnmp.Icmp.OutAddrMasks = &value
|
||||
procSnmp.OutAddrMasks = &value
|
||||
case "OutAddrMaskReps":
|
||||
procSnmp.Icmp.OutAddrMaskReps = &value
|
||||
procSnmp.OutAddrMaskReps = &value
|
||||
}
|
||||
case "IcmpMsg":
|
||||
switch key {
|
||||
case "InType3":
|
||||
procSnmp.IcmpMsg.InType3 = &value
|
||||
procSnmp.InType3 = &value
|
||||
case "OutType3":
|
||||
procSnmp.IcmpMsg.OutType3 = &value
|
||||
procSnmp.OutType3 = &value
|
||||
}
|
||||
case "Tcp":
|
||||
switch key {
|
||||
case "RtoAlgorithm":
|
||||
procSnmp.Tcp.RtoAlgorithm = &value
|
||||
procSnmp.RtoAlgorithm = &value
|
||||
case "RtoMin":
|
||||
procSnmp.Tcp.RtoMin = &value
|
||||
procSnmp.RtoMin = &value
|
||||
case "RtoMax":
|
||||
procSnmp.Tcp.RtoMax = &value
|
||||
procSnmp.RtoMax = &value
|
||||
case "MaxConn":
|
||||
procSnmp.Tcp.MaxConn = &value
|
||||
procSnmp.MaxConn = &value
|
||||
case "ActiveOpens":
|
||||
procSnmp.Tcp.ActiveOpens = &value
|
||||
procSnmp.ActiveOpens = &value
|
||||
case "PassiveOpens":
|
||||
procSnmp.Tcp.PassiveOpens = &value
|
||||
procSnmp.PassiveOpens = &value
|
||||
case "AttemptFails":
|
||||
procSnmp.Tcp.AttemptFails = &value
|
||||
procSnmp.AttemptFails = &value
|
||||
case "EstabResets":
|
||||
procSnmp.Tcp.EstabResets = &value
|
||||
procSnmp.EstabResets = &value
|
||||
case "CurrEstab":
|
||||
procSnmp.Tcp.CurrEstab = &value
|
||||
procSnmp.CurrEstab = &value
|
||||
case "InSegs":
|
||||
procSnmp.Tcp.InSegs = &value
|
||||
procSnmp.InSegs = &value
|
||||
case "OutSegs":
|
||||
procSnmp.Tcp.OutSegs = &value
|
||||
procSnmp.OutSegs = &value
|
||||
case "RetransSegs":
|
||||
procSnmp.Tcp.RetransSegs = &value
|
||||
procSnmp.RetransSegs = &value
|
||||
case "InErrs":
|
||||
procSnmp.Tcp.InErrs = &value
|
||||
procSnmp.InErrs = &value
|
||||
case "OutRsts":
|
||||
procSnmp.Tcp.OutRsts = &value
|
||||
procSnmp.OutRsts = &value
|
||||
case "InCsumErrors":
|
||||
procSnmp.Tcp.InCsumErrors = &value
|
||||
}
|
||||
|
||||
152
vendor/github.com/prometheus/procfs/proc_snmp6.go
generated
vendored
152
vendor/github.com/prometheus/procfs/proc_snmp6.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -182,161 +182,161 @@ func parseSNMP6Stats(r io.Reader) (ProcSnmp6, error) {
|
||||
case "Ip6":
|
||||
switch key {
|
||||
case "InReceives":
|
||||
procSnmp6.Ip6.InReceives = &value
|
||||
procSnmp6.InReceives = &value
|
||||
case "InHdrErrors":
|
||||
procSnmp6.Ip6.InHdrErrors = &value
|
||||
procSnmp6.InHdrErrors = &value
|
||||
case "InTooBigErrors":
|
||||
procSnmp6.Ip6.InTooBigErrors = &value
|
||||
procSnmp6.InTooBigErrors = &value
|
||||
case "InNoRoutes":
|
||||
procSnmp6.Ip6.InNoRoutes = &value
|
||||
procSnmp6.InNoRoutes = &value
|
||||
case "InAddrErrors":
|
||||
procSnmp6.Ip6.InAddrErrors = &value
|
||||
procSnmp6.InAddrErrors = &value
|
||||
case "InUnknownProtos":
|
||||
procSnmp6.Ip6.InUnknownProtos = &value
|
||||
procSnmp6.InUnknownProtos = &value
|
||||
case "InTruncatedPkts":
|
||||
procSnmp6.Ip6.InTruncatedPkts = &value
|
||||
procSnmp6.InTruncatedPkts = &value
|
||||
case "InDiscards":
|
||||
procSnmp6.Ip6.InDiscards = &value
|
||||
procSnmp6.InDiscards = &value
|
||||
case "InDelivers":
|
||||
procSnmp6.Ip6.InDelivers = &value
|
||||
procSnmp6.InDelivers = &value
|
||||
case "OutForwDatagrams":
|
||||
procSnmp6.Ip6.OutForwDatagrams = &value
|
||||
procSnmp6.OutForwDatagrams = &value
|
||||
case "OutRequests":
|
||||
procSnmp6.Ip6.OutRequests = &value
|
||||
procSnmp6.OutRequests = &value
|
||||
case "OutDiscards":
|
||||
procSnmp6.Ip6.OutDiscards = &value
|
||||
procSnmp6.OutDiscards = &value
|
||||
case "OutNoRoutes":
|
||||
procSnmp6.Ip6.OutNoRoutes = &value
|
||||
procSnmp6.OutNoRoutes = &value
|
||||
case "ReasmTimeout":
|
||||
procSnmp6.Ip6.ReasmTimeout = &value
|
||||
procSnmp6.ReasmTimeout = &value
|
||||
case "ReasmReqds":
|
||||
procSnmp6.Ip6.ReasmReqds = &value
|
||||
procSnmp6.ReasmReqds = &value
|
||||
case "ReasmOKs":
|
||||
procSnmp6.Ip6.ReasmOKs = &value
|
||||
procSnmp6.ReasmOKs = &value
|
||||
case "ReasmFails":
|
||||
procSnmp6.Ip6.ReasmFails = &value
|
||||
procSnmp6.ReasmFails = &value
|
||||
case "FragOKs":
|
||||
procSnmp6.Ip6.FragOKs = &value
|
||||
procSnmp6.FragOKs = &value
|
||||
case "FragFails":
|
||||
procSnmp6.Ip6.FragFails = &value
|
||||
procSnmp6.FragFails = &value
|
||||
case "FragCreates":
|
||||
procSnmp6.Ip6.FragCreates = &value
|
||||
procSnmp6.FragCreates = &value
|
||||
case "InMcastPkts":
|
||||
procSnmp6.Ip6.InMcastPkts = &value
|
||||
procSnmp6.InMcastPkts = &value
|
||||
case "OutMcastPkts":
|
||||
procSnmp6.Ip6.OutMcastPkts = &value
|
||||
procSnmp6.OutMcastPkts = &value
|
||||
case "InOctets":
|
||||
procSnmp6.Ip6.InOctets = &value
|
||||
procSnmp6.InOctets = &value
|
||||
case "OutOctets":
|
||||
procSnmp6.Ip6.OutOctets = &value
|
||||
procSnmp6.OutOctets = &value
|
||||
case "InMcastOctets":
|
||||
procSnmp6.Ip6.InMcastOctets = &value
|
||||
procSnmp6.InMcastOctets = &value
|
||||
case "OutMcastOctets":
|
||||
procSnmp6.Ip6.OutMcastOctets = &value
|
||||
procSnmp6.OutMcastOctets = &value
|
||||
case "InBcastOctets":
|
||||
procSnmp6.Ip6.InBcastOctets = &value
|
||||
procSnmp6.InBcastOctets = &value
|
||||
case "OutBcastOctets":
|
||||
procSnmp6.Ip6.OutBcastOctets = &value
|
||||
procSnmp6.OutBcastOctets = &value
|
||||
case "InNoECTPkts":
|
||||
procSnmp6.Ip6.InNoECTPkts = &value
|
||||
procSnmp6.InNoECTPkts = &value
|
||||
case "InECT1Pkts":
|
||||
procSnmp6.Ip6.InECT1Pkts = &value
|
||||
procSnmp6.InECT1Pkts = &value
|
||||
case "InECT0Pkts":
|
||||
procSnmp6.Ip6.InECT0Pkts = &value
|
||||
procSnmp6.InECT0Pkts = &value
|
||||
case "InCEPkts":
|
||||
procSnmp6.Ip6.InCEPkts = &value
|
||||
procSnmp6.InCEPkts = &value
|
||||
|
||||
}
|
||||
case "Icmp6":
|
||||
switch key {
|
||||
case "InMsgs":
|
||||
procSnmp6.Icmp6.InMsgs = &value
|
||||
procSnmp6.InMsgs = &value
|
||||
case "InErrors":
|
||||
procSnmp6.Icmp6.InErrors = &value
|
||||
case "OutMsgs":
|
||||
procSnmp6.Icmp6.OutMsgs = &value
|
||||
procSnmp6.OutMsgs = &value
|
||||
case "OutErrors":
|
||||
procSnmp6.Icmp6.OutErrors = &value
|
||||
procSnmp6.OutErrors = &value
|
||||
case "InCsumErrors":
|
||||
procSnmp6.Icmp6.InCsumErrors = &value
|
||||
case "InDestUnreachs":
|
||||
procSnmp6.Icmp6.InDestUnreachs = &value
|
||||
procSnmp6.InDestUnreachs = &value
|
||||
case "InPktTooBigs":
|
||||
procSnmp6.Icmp6.InPktTooBigs = &value
|
||||
procSnmp6.InPktTooBigs = &value
|
||||
case "InTimeExcds":
|
||||
procSnmp6.Icmp6.InTimeExcds = &value
|
||||
procSnmp6.InTimeExcds = &value
|
||||
case "InParmProblems":
|
||||
procSnmp6.Icmp6.InParmProblems = &value
|
||||
procSnmp6.InParmProblems = &value
|
||||
case "InEchos":
|
||||
procSnmp6.Icmp6.InEchos = &value
|
||||
procSnmp6.InEchos = &value
|
||||
case "InEchoReplies":
|
||||
procSnmp6.Icmp6.InEchoReplies = &value
|
||||
procSnmp6.InEchoReplies = &value
|
||||
case "InGroupMembQueries":
|
||||
procSnmp6.Icmp6.InGroupMembQueries = &value
|
||||
procSnmp6.InGroupMembQueries = &value
|
||||
case "InGroupMembResponses":
|
||||
procSnmp6.Icmp6.InGroupMembResponses = &value
|
||||
procSnmp6.InGroupMembResponses = &value
|
||||
case "InGroupMembReductions":
|
||||
procSnmp6.Icmp6.InGroupMembReductions = &value
|
||||
procSnmp6.InGroupMembReductions = &value
|
||||
case "InRouterSolicits":
|
||||
procSnmp6.Icmp6.InRouterSolicits = &value
|
||||
procSnmp6.InRouterSolicits = &value
|
||||
case "InRouterAdvertisements":
|
||||
procSnmp6.Icmp6.InRouterAdvertisements = &value
|
||||
procSnmp6.InRouterAdvertisements = &value
|
||||
case "InNeighborSolicits":
|
||||
procSnmp6.Icmp6.InNeighborSolicits = &value
|
||||
procSnmp6.InNeighborSolicits = &value
|
||||
case "InNeighborAdvertisements":
|
||||
procSnmp6.Icmp6.InNeighborAdvertisements = &value
|
||||
procSnmp6.InNeighborAdvertisements = &value
|
||||
case "InRedirects":
|
||||
procSnmp6.Icmp6.InRedirects = &value
|
||||
procSnmp6.InRedirects = &value
|
||||
case "InMLDv2Reports":
|
||||
procSnmp6.Icmp6.InMLDv2Reports = &value
|
||||
procSnmp6.InMLDv2Reports = &value
|
||||
case "OutDestUnreachs":
|
||||
procSnmp6.Icmp6.OutDestUnreachs = &value
|
||||
procSnmp6.OutDestUnreachs = &value
|
||||
case "OutPktTooBigs":
|
||||
procSnmp6.Icmp6.OutPktTooBigs = &value
|
||||
procSnmp6.OutPktTooBigs = &value
|
||||
case "OutTimeExcds":
|
||||
procSnmp6.Icmp6.OutTimeExcds = &value
|
||||
procSnmp6.OutTimeExcds = &value
|
||||
case "OutParmProblems":
|
||||
procSnmp6.Icmp6.OutParmProblems = &value
|
||||
procSnmp6.OutParmProblems = &value
|
||||
case "OutEchos":
|
||||
procSnmp6.Icmp6.OutEchos = &value
|
||||
procSnmp6.OutEchos = &value
|
||||
case "OutEchoReplies":
|
||||
procSnmp6.Icmp6.OutEchoReplies = &value
|
||||
procSnmp6.OutEchoReplies = &value
|
||||
case "OutGroupMembQueries":
|
||||
procSnmp6.Icmp6.OutGroupMembQueries = &value
|
||||
procSnmp6.OutGroupMembQueries = &value
|
||||
case "OutGroupMembResponses":
|
||||
procSnmp6.Icmp6.OutGroupMembResponses = &value
|
||||
procSnmp6.OutGroupMembResponses = &value
|
||||
case "OutGroupMembReductions":
|
||||
procSnmp6.Icmp6.OutGroupMembReductions = &value
|
||||
procSnmp6.OutGroupMembReductions = &value
|
||||
case "OutRouterSolicits":
|
||||
procSnmp6.Icmp6.OutRouterSolicits = &value
|
||||
procSnmp6.OutRouterSolicits = &value
|
||||
case "OutRouterAdvertisements":
|
||||
procSnmp6.Icmp6.OutRouterAdvertisements = &value
|
||||
procSnmp6.OutRouterAdvertisements = &value
|
||||
case "OutNeighborSolicits":
|
||||
procSnmp6.Icmp6.OutNeighborSolicits = &value
|
||||
procSnmp6.OutNeighborSolicits = &value
|
||||
case "OutNeighborAdvertisements":
|
||||
procSnmp6.Icmp6.OutNeighborAdvertisements = &value
|
||||
procSnmp6.OutNeighborAdvertisements = &value
|
||||
case "OutRedirects":
|
||||
procSnmp6.Icmp6.OutRedirects = &value
|
||||
procSnmp6.OutRedirects = &value
|
||||
case "OutMLDv2Reports":
|
||||
procSnmp6.Icmp6.OutMLDv2Reports = &value
|
||||
procSnmp6.OutMLDv2Reports = &value
|
||||
case "InType1":
|
||||
procSnmp6.Icmp6.InType1 = &value
|
||||
procSnmp6.InType1 = &value
|
||||
case "InType134":
|
||||
procSnmp6.Icmp6.InType134 = &value
|
||||
procSnmp6.InType134 = &value
|
||||
case "InType135":
|
||||
procSnmp6.Icmp6.InType135 = &value
|
||||
procSnmp6.InType135 = &value
|
||||
case "InType136":
|
||||
procSnmp6.Icmp6.InType136 = &value
|
||||
procSnmp6.InType136 = &value
|
||||
case "InType143":
|
||||
procSnmp6.Icmp6.InType143 = &value
|
||||
procSnmp6.InType143 = &value
|
||||
case "OutType133":
|
||||
procSnmp6.Icmp6.OutType133 = &value
|
||||
procSnmp6.OutType133 = &value
|
||||
case "OutType135":
|
||||
procSnmp6.Icmp6.OutType135 = &value
|
||||
procSnmp6.OutType135 = &value
|
||||
case "OutType136":
|
||||
procSnmp6.Icmp6.OutType136 = &value
|
||||
procSnmp6.OutType136 = &value
|
||||
case "OutType143":
|
||||
procSnmp6.Icmp6.OutType143 = &value
|
||||
procSnmp6.OutType143 = &value
|
||||
}
|
||||
case "Udp6":
|
||||
switch key {
|
||||
@@ -355,7 +355,7 @@ func parseSNMP6Stats(r io.Reader) (ProcSnmp6, error) {
|
||||
case "InCsumErrors":
|
||||
procSnmp6.Udp6.InCsumErrors = &value
|
||||
case "IgnoredMulti":
|
||||
procSnmp6.Udp6.IgnoredMulti = &value
|
||||
procSnmp6.IgnoredMulti = &value
|
||||
}
|
||||
case "UdpLite6":
|
||||
switch key {
|
||||
|
||||
29
vendor/github.com/prometheus/procfs/proc_stat.go
generated
vendored
29
vendor/github.com/prometheus/procfs/proc_stat.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2018 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/prometheus/procfs/internal/fs"
|
||||
"github.com/prometheus/procfs/internal/util"
|
||||
)
|
||||
|
||||
@@ -102,6 +101,12 @@ type ProcStat struct {
|
||||
RSS int
|
||||
// Soft limit in bytes on the rss of the process.
|
||||
RSSLimit uint64
|
||||
// The address above which program text can run.
|
||||
StartCode uint64
|
||||
// The address below which program text can run.
|
||||
EndCode uint64
|
||||
// The address of the start (i.e., bottom) of the stack.
|
||||
StartStack uint64
|
||||
// CPU number last executed on.
|
||||
Processor uint
|
||||
// Real-time scheduling priority, a number in the range 1 to 99 for processes
|
||||
@@ -111,8 +116,13 @@ type ProcStat struct {
|
||||
Policy uint
|
||||
// Aggregated block I/O delays, measured in clock ticks (centiseconds).
|
||||
DelayAcctBlkIOTicks uint64
|
||||
// Guest time of the process (time spent running a virtual CPU for a guest
|
||||
// operating system), measured in clock ticks.
|
||||
GuestTime int
|
||||
// Guest time of the process's children, measured in clock ticks.
|
||||
CGuestTime int
|
||||
|
||||
proc fs.FS
|
||||
proc FS
|
||||
}
|
||||
|
||||
// NewStat returns the current status information of the process.
|
||||
@@ -139,7 +149,7 @@ func (p Proc) Stat() (ProcStat, error) {
|
||||
)
|
||||
|
||||
if l < 0 || r < 0 {
|
||||
return ProcStat{}, fmt.Errorf("unexpected format, couldn't extract comm %q", data)
|
||||
return ProcStat{}, fmt.Errorf("%w: unexpected format, couldn't extract comm %q", ErrFileParse, data)
|
||||
}
|
||||
|
||||
s.Comm = string(data[l+1 : r])
|
||||
@@ -173,9 +183,9 @@ func (p Proc) Stat() (ProcStat, error) {
|
||||
&s.VSize,
|
||||
&s.RSS,
|
||||
&s.RSSLimit,
|
||||
&ignoreUint64,
|
||||
&ignoreUint64,
|
||||
&ignoreUint64,
|
||||
&s.StartCode,
|
||||
&s.EndCode,
|
||||
&s.StartStack,
|
||||
&ignoreUint64,
|
||||
&ignoreUint64,
|
||||
&ignoreUint64,
|
||||
@@ -190,6 +200,8 @@ func (p Proc) Stat() (ProcStat, error) {
|
||||
&s.RTPriority,
|
||||
&s.Policy,
|
||||
&s.DelayAcctBlkIOTicks,
|
||||
&s.GuestTime,
|
||||
&s.CGuestTime,
|
||||
)
|
||||
if err != nil {
|
||||
return ProcStat{}, err
|
||||
@@ -210,8 +222,7 @@ func (s ProcStat) ResidentMemory() int {
|
||||
|
||||
// StartTime returns the unix timestamp of the process in seconds.
|
||||
func (s ProcStat) StartTime() (float64, error) {
|
||||
fs := FS{proc: s.proc}
|
||||
stat, err := fs.Stat()
|
||||
stat, err := s.proc.Stat()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
116
vendor/github.com/prometheus/procfs/proc_statm.go
generated
vendored
Normal file
116
vendor/github.com/prometheus/procfs/proc_statm.go
generated
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
// Copyright 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 procfs
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus/procfs/internal/util"
|
||||
)
|
||||
|
||||
// - https://man7.org/linux/man-pages/man5/proc_pid_statm.5.html
|
||||
|
||||
// ProcStatm Provides memory usage information for a process, measured in memory pages.
|
||||
// Read from /proc/[pid]/statm.
|
||||
type ProcStatm struct {
|
||||
// The process ID.
|
||||
PID int
|
||||
// total program size (same as VmSize in status)
|
||||
Size uint64
|
||||
// resident set size (same as VmRSS in status)
|
||||
Resident uint64
|
||||
// number of resident shared pages (i.e., backed by a file)
|
||||
Shared uint64
|
||||
// text (code)
|
||||
Text uint64
|
||||
// library (unused since Linux 2.6; always 0)
|
||||
Lib uint64
|
||||
// data + stack
|
||||
Data uint64
|
||||
// dirty pages (unused since Linux 2.6; always 0)
|
||||
Dt uint64
|
||||
}
|
||||
|
||||
// NewStatm returns the current status information of the process.
|
||||
// Deprecated: Use p.Statm() instead.
|
||||
func (p Proc) NewStatm() (ProcStatm, error) {
|
||||
return p.Statm()
|
||||
}
|
||||
|
||||
// Statm returns the current memory usage information of the process.
|
||||
func (p Proc) Statm() (ProcStatm, error) {
|
||||
data, err := util.ReadFileNoStat(p.path("statm"))
|
||||
if err != nil {
|
||||
return ProcStatm{}, err
|
||||
}
|
||||
|
||||
statmSlice, err := parseStatm(data)
|
||||
if err != nil {
|
||||
return ProcStatm{}, err
|
||||
}
|
||||
|
||||
procStatm := ProcStatm{
|
||||
PID: p.PID,
|
||||
Size: statmSlice[0],
|
||||
Resident: statmSlice[1],
|
||||
Shared: statmSlice[2],
|
||||
Text: statmSlice[3],
|
||||
Lib: statmSlice[4],
|
||||
Data: statmSlice[5],
|
||||
Dt: statmSlice[6],
|
||||
}
|
||||
|
||||
return procStatm, nil
|
||||
}
|
||||
|
||||
// parseStatm return /proc/[pid]/statm data to uint64 slice.
|
||||
func parseStatm(data []byte) ([]uint64, error) {
|
||||
var statmSlice []uint64
|
||||
statmItems := strings.Fields(string(data))
|
||||
for i := range statmItems {
|
||||
statmItem, err := strconv.ParseUint(statmItems[i], 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
statmSlice = append(statmSlice, statmItem)
|
||||
}
|
||||
return statmSlice, nil
|
||||
}
|
||||
|
||||
// SizeBytes returns the process of total program size in bytes.
|
||||
func (s ProcStatm) SizeBytes() uint64 {
|
||||
return s.Size * uint64(os.Getpagesize())
|
||||
}
|
||||
|
||||
// ResidentBytes returns the process of resident set size in bytes.
|
||||
func (s ProcStatm) ResidentBytes() uint64 {
|
||||
return s.Resident * uint64(os.Getpagesize())
|
||||
}
|
||||
|
||||
// SHRBytes returns the process of share memory size in bytes.
|
||||
func (s ProcStatm) SHRBytes() uint64 {
|
||||
return s.Shared * uint64(os.Getpagesize())
|
||||
}
|
||||
|
||||
// TextBytes returns the process of text (code) size in bytes.
|
||||
func (s ProcStatm) TextBytes() uint64 {
|
||||
return s.Text * uint64(os.Getpagesize())
|
||||
}
|
||||
|
||||
// DataBytes returns the process of data + stack size in bytes.
|
||||
func (s ProcStatm) DataBytes() uint64 {
|
||||
return s.Data * uint64(os.Getpagesize())
|
||||
}
|
||||
91
vendor/github.com/prometheus/procfs/proc_status.go
generated
vendored
91
vendor/github.com/prometheus/procfs/proc_status.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2018 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -15,6 +15,8 @@ package procfs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"math/bits"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -22,7 +24,7 @@ import (
|
||||
)
|
||||
|
||||
// ProcStatus provides status information about the process,
|
||||
// read from /proc/[pid]/stat.
|
||||
// read from /proc/[pid]/status.
|
||||
type ProcStatus struct {
|
||||
// The process ID.
|
||||
PID int
|
||||
@@ -31,6 +33,8 @@ type ProcStatus struct {
|
||||
|
||||
// Thread group ID.
|
||||
TGID int
|
||||
// List of Pid namespace.
|
||||
NSpids []uint64
|
||||
|
||||
// Peak virtual memory size.
|
||||
VmPeak uint64 // nolint:revive
|
||||
@@ -73,9 +77,12 @@ type ProcStatus struct {
|
||||
NonVoluntaryCtxtSwitches uint64
|
||||
|
||||
// UIDs of the process (Real, effective, saved set, and filesystem UIDs)
|
||||
UIDs [4]string
|
||||
UIDs [4]uint64
|
||||
// GIDs of the process (Real, effective, saved set, and filesystem GIDs)
|
||||
GIDs [4]string
|
||||
GIDs [4]uint64
|
||||
|
||||
// CpusAllowedList: List of cpu cores processes are allowed to run on.
|
||||
CpusAllowedList []uint64
|
||||
}
|
||||
|
||||
// NewStatus returns the current status information of the process.
|
||||
@@ -87,8 +94,7 @@ func (p Proc) NewStatus() (ProcStatus, error) {
|
||||
|
||||
s := ProcStatus{PID: p.PID}
|
||||
|
||||
lines := strings.Split(string(data), "\n")
|
||||
for _, line := range lines {
|
||||
for line := range strings.SplitSeq(string(data), "\n") {
|
||||
if !bytes.Contains([]byte(line), []byte(":")) {
|
||||
continue
|
||||
}
|
||||
@@ -107,22 +113,43 @@ func (p Proc) NewStatus() (ProcStatus, error) {
|
||||
// convert kB to B
|
||||
vBytes := vKBytes * 1024
|
||||
|
||||
s.fillStatus(k, v, vKBytes, vBytes)
|
||||
err = s.fillStatus(k, v, vKBytes, vBytes)
|
||||
if err != nil {
|
||||
return ProcStatus{}, err
|
||||
}
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (s *ProcStatus) fillStatus(k string, vString string, vUint uint64, vUintBytes uint64) {
|
||||
func (s *ProcStatus) fillStatus(k string, vString string, vUint uint64, vUintBytes uint64) error {
|
||||
switch k {
|
||||
case "Tgid":
|
||||
s.TGID = int(vUint)
|
||||
case "Name":
|
||||
s.Name = vString
|
||||
case "Uid":
|
||||
copy(s.UIDs[:], strings.Split(vString, "\t"))
|
||||
var err error
|
||||
for i, v := range strings.Split(vString, "\t") {
|
||||
s.UIDs[i], err = strconv.ParseUint(v, 10, bits.UintSize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
case "Gid":
|
||||
copy(s.GIDs[:], strings.Split(vString, "\t"))
|
||||
var err error
|
||||
for i, v := range strings.Split(vString, "\t") {
|
||||
s.GIDs[i], err = strconv.ParseUint(v, 10, bits.UintSize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
case "NSpid":
|
||||
nspids, err := calcNSPidsList(vString)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.NSpids = nspids
|
||||
case "VmPeak":
|
||||
s.VmPeak = vUintBytes
|
||||
case "VmSize":
|
||||
@@ -161,10 +188,54 @@ func (s *ProcStatus) fillStatus(k string, vString string, vUint uint64, vUintByt
|
||||
s.VoluntaryCtxtSwitches = vUint
|
||||
case "nonvoluntary_ctxt_switches":
|
||||
s.NonVoluntaryCtxtSwitches = vUint
|
||||
case "Cpus_allowed_list":
|
||||
s.CpusAllowedList = calcCpusAllowedList(vString)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// TotalCtxtSwitches returns the total context switch.
|
||||
func (s ProcStatus) TotalCtxtSwitches() uint64 {
|
||||
return s.VoluntaryCtxtSwitches + s.NonVoluntaryCtxtSwitches
|
||||
}
|
||||
|
||||
func calcCpusAllowedList(cpuString string) []uint64 {
|
||||
s := strings.Split(cpuString, ",")
|
||||
|
||||
var g []uint64
|
||||
|
||||
for _, cpu := range s {
|
||||
// parse cpu ranges, example: 1-3=[1,2,3]
|
||||
if l := strings.Split(strings.TrimSpace(cpu), "-"); len(l) > 1 {
|
||||
startCPU, _ := strconv.ParseUint(l[0], 10, 64)
|
||||
endCPU, _ := strconv.ParseUint(l[1], 10, 64)
|
||||
|
||||
for i := startCPU; i <= endCPU; i++ {
|
||||
g = append(g, i)
|
||||
}
|
||||
} else if len(l) == 1 {
|
||||
cpu, _ := strconv.ParseUint(l[0], 10, 64)
|
||||
g = append(g, cpu)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
slices.Sort(g)
|
||||
return g
|
||||
}
|
||||
|
||||
func calcNSPidsList(nspidsString string) ([]uint64, error) {
|
||||
s := strings.Split(nspidsString, "\t")
|
||||
var nspids []uint64
|
||||
|
||||
for _, nspid := range s {
|
||||
nspid, err := strconv.ParseUint(nspid, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nspids = append(nspids, nspid)
|
||||
}
|
||||
|
||||
return nspids, nil
|
||||
}
|
||||
|
||||
6
vendor/github.com/prometheus/procfs/proc_sys.go
generated
vendored
6
vendor/github.com/prometheus/procfs/proc_sys.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
)
|
||||
|
||||
func sysctlToPath(sysctl string) string {
|
||||
return strings.Replace(sysctl, ".", "/", -1)
|
||||
return strings.ReplaceAll(sysctl, ".", "/")
|
||||
}
|
||||
|
||||
func (fs FS) SysctlStrings(sysctl string) ([]string, error) {
|
||||
@@ -44,7 +44,7 @@ func (fs FS) SysctlInts(sysctl string) ([]int, error) {
|
||||
vp := util.NewValueParser(f)
|
||||
values[i] = vp.Int()
|
||||
if err := vp.Err(); err != nil {
|
||||
return nil, fmt.Errorf("field %d in sysctl %s is not a valid int: %w", i, sysctl, err)
|
||||
return nil, fmt.Errorf("%w: field %d in sysctl %s is not a valid int: %w", ErrFileParse, i, sysctl, err)
|
||||
}
|
||||
}
|
||||
return values, nil
|
||||
|
||||
2
vendor/github.com/prometheus/procfs/schedstat.go
generated
vendored
2
vendor/github.com/prometheus/procfs/schedstat.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019 The Prometheus Authors
|
||||
// Copyright 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
|
||||
|
||||
4
vendor/github.com/prometheus/procfs/slab.go
generated
vendored
4
vendor/github.com/prometheus/procfs/slab.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -68,7 +68,7 @@ func parseV21SlabEntry(line string) (*Slab, error) {
|
||||
l := slabSpace.ReplaceAllString(line, " ")
|
||||
s := strings.Split(l, " ")
|
||||
if len(s) != 16 {
|
||||
return nil, fmt.Errorf("unable to parse: %q", line)
|
||||
return nil, fmt.Errorf("%w: unable to parse: %q", ErrFileParse, line)
|
||||
}
|
||||
var err error
|
||||
i := &Slab{Name: s[0]}
|
||||
|
||||
48
vendor/github.com/prometheus/procfs/softirqs.go
generated
vendored
48
vendor/github.com/prometheus/procfs/softirqs.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -57,7 +57,7 @@ func parseSoftirqs(r io.Reader) (Softirqs, error) {
|
||||
)
|
||||
|
||||
if !scanner.Scan() {
|
||||
return Softirqs{}, fmt.Errorf("softirqs empty")
|
||||
return Softirqs{}, fmt.Errorf("%w: softirqs empty", ErrFileRead)
|
||||
}
|
||||
|
||||
for scanner.Scan() {
|
||||
@@ -68,92 +68,92 @@ func parseSoftirqs(r io.Reader) (Softirqs, error) {
|
||||
if len(parts) < 2 {
|
||||
continue
|
||||
}
|
||||
switch {
|
||||
case parts[0] == "HI:":
|
||||
switch parts[0] {
|
||||
case "HI:":
|
||||
perCPU := parts[1:]
|
||||
softirqs.Hi = make([]uint64, len(perCPU))
|
||||
for i, count := range perCPU {
|
||||
if softirqs.Hi[i], err = strconv.ParseUint(count, 10, 64); err != nil {
|
||||
return Softirqs{}, fmt.Errorf("couldn't parse %q (HI%d): %w", count, i, err)
|
||||
return Softirqs{}, fmt.Errorf("%w: couldn't parse %q (HI%d): %w", ErrFileParse, count, i, err)
|
||||
}
|
||||
}
|
||||
case parts[0] == "TIMER:":
|
||||
case "TIMER:":
|
||||
perCPU := parts[1:]
|
||||
softirqs.Timer = make([]uint64, len(perCPU))
|
||||
for i, count := range perCPU {
|
||||
if softirqs.Timer[i], err = strconv.ParseUint(count, 10, 64); err != nil {
|
||||
return Softirqs{}, fmt.Errorf("couldn't parse %q (TIMER%d): %w", count, i, err)
|
||||
return Softirqs{}, fmt.Errorf("%w: couldn't parse %q (TIMER%d): %w", ErrFileParse, count, i, err)
|
||||
}
|
||||
}
|
||||
case parts[0] == "NET_TX:":
|
||||
case "NET_TX:":
|
||||
perCPU := parts[1:]
|
||||
softirqs.NetTx = make([]uint64, len(perCPU))
|
||||
for i, count := range perCPU {
|
||||
if softirqs.NetTx[i], err = strconv.ParseUint(count, 10, 64); err != nil {
|
||||
return Softirqs{}, fmt.Errorf("couldn't parse %q (NET_TX%d): %w", count, i, err)
|
||||
return Softirqs{}, fmt.Errorf("%w: couldn't parse %q (NET_TX%d): %w", ErrFileParse, count, i, err)
|
||||
}
|
||||
}
|
||||
case parts[0] == "NET_RX:":
|
||||
case "NET_RX:":
|
||||
perCPU := parts[1:]
|
||||
softirqs.NetRx = make([]uint64, len(perCPU))
|
||||
for i, count := range perCPU {
|
||||
if softirqs.NetRx[i], err = strconv.ParseUint(count, 10, 64); err != nil {
|
||||
return Softirqs{}, fmt.Errorf("couldn't parse %q (NET_RX%d): %w", count, i, err)
|
||||
return Softirqs{}, fmt.Errorf("%w: couldn't parse %q (NET_RX%d): %w", ErrFileParse, count, i, err)
|
||||
}
|
||||
}
|
||||
case parts[0] == "BLOCK:":
|
||||
case "BLOCK:":
|
||||
perCPU := parts[1:]
|
||||
softirqs.Block = make([]uint64, len(perCPU))
|
||||
for i, count := range perCPU {
|
||||
if softirqs.Block[i], err = strconv.ParseUint(count, 10, 64); err != nil {
|
||||
return Softirqs{}, fmt.Errorf("couldn't parse %q (BLOCK%d): %w", count, i, err)
|
||||
return Softirqs{}, fmt.Errorf("%w: couldn't parse %q (BLOCK%d): %w", ErrFileParse, count, i, err)
|
||||
}
|
||||
}
|
||||
case parts[0] == "IRQ_POLL:":
|
||||
case "IRQ_POLL:":
|
||||
perCPU := parts[1:]
|
||||
softirqs.IRQPoll = make([]uint64, len(perCPU))
|
||||
for i, count := range perCPU {
|
||||
if softirqs.IRQPoll[i], err = strconv.ParseUint(count, 10, 64); err != nil {
|
||||
return Softirqs{}, fmt.Errorf("couldn't parse %q (IRQ_POLL%d): %w", count, i, err)
|
||||
return Softirqs{}, fmt.Errorf("%w: couldn't parse %q (IRQ_POLL%d): %w", ErrFileParse, count, i, err)
|
||||
}
|
||||
}
|
||||
case parts[0] == "TASKLET:":
|
||||
case "TASKLET:":
|
||||
perCPU := parts[1:]
|
||||
softirqs.Tasklet = make([]uint64, len(perCPU))
|
||||
for i, count := range perCPU {
|
||||
if softirqs.Tasklet[i], err = strconv.ParseUint(count, 10, 64); err != nil {
|
||||
return Softirqs{}, fmt.Errorf("couldn't parse %q (TASKLET%d): %w", count, i, err)
|
||||
return Softirqs{}, fmt.Errorf("%w: couldn't parse %q (TASKLET%d): %w", ErrFileParse, count, i, err)
|
||||
}
|
||||
}
|
||||
case parts[0] == "SCHED:":
|
||||
case "SCHED:":
|
||||
perCPU := parts[1:]
|
||||
softirqs.Sched = make([]uint64, len(perCPU))
|
||||
for i, count := range perCPU {
|
||||
if softirqs.Sched[i], err = strconv.ParseUint(count, 10, 64); err != nil {
|
||||
return Softirqs{}, fmt.Errorf("couldn't parse %q (SCHED%d): %w", count, i, err)
|
||||
return Softirqs{}, fmt.Errorf("%w: couldn't parse %q (SCHED%d): %w", ErrFileParse, count, i, err)
|
||||
}
|
||||
}
|
||||
case parts[0] == "HRTIMER:":
|
||||
case "HRTIMER:":
|
||||
perCPU := parts[1:]
|
||||
softirqs.HRTimer = make([]uint64, len(perCPU))
|
||||
for i, count := range perCPU {
|
||||
if softirqs.HRTimer[i], err = strconv.ParseUint(count, 10, 64); err != nil {
|
||||
return Softirqs{}, fmt.Errorf("couldn't parse %q (HRTIMER%d): %w", count, i, err)
|
||||
return Softirqs{}, fmt.Errorf("%w: couldn't parse %q (HRTIMER%d): %w", ErrFileParse, count, i, err)
|
||||
}
|
||||
}
|
||||
case parts[0] == "RCU:":
|
||||
case "RCU:":
|
||||
perCPU := parts[1:]
|
||||
softirqs.RCU = make([]uint64, len(perCPU))
|
||||
for i, count := range perCPU {
|
||||
if softirqs.RCU[i], err = strconv.ParseUint(count, 10, 64); err != nil {
|
||||
return Softirqs{}, fmt.Errorf("couldn't parse %q (RCU%d): %w", count, i, err)
|
||||
return Softirqs{}, fmt.Errorf("%w: couldn't parse %q (RCU%d): %w", ErrFileParse, count, i, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return Softirqs{}, fmt.Errorf("couldn't parse softirqs: %w", err)
|
||||
return Softirqs{}, fmt.Errorf("%w: couldn't parse softirqs: %w", ErrFileParse, err)
|
||||
}
|
||||
|
||||
return softirqs, scanner.Err()
|
||||
|
||||
33
vendor/github.com/prometheus/procfs/stat.go
generated
vendored
33
vendor/github.com/prometheus/procfs/stat.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2018 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -16,6 +16,7 @@ package procfs
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
@@ -92,11 +93,11 @@ func parseCPUStat(line string) (CPUStat, int64, error) {
|
||||
&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 %q (cpu): %w", line, err)
|
||||
if err != nil && !errors.Is(err, io.EOF) {
|
||||
return CPUStat{}, -1, fmt.Errorf("%w: couldn't parse %q (cpu): %w", ErrFileParse, line, err)
|
||||
}
|
||||
if count == 0 {
|
||||
return CPUStat{}, -1, fmt.Errorf("couldn't parse %q (cpu): 0 elements parsed", line)
|
||||
return CPUStat{}, -1, fmt.Errorf("%w: couldn't parse %q (cpu): 0 elements parsed", ErrFileParse, line)
|
||||
}
|
||||
|
||||
cpuStat.User /= userHZ
|
||||
@@ -116,7 +117,7 @@ func parseCPUStat(line string) (CPUStat, int64, error) {
|
||||
|
||||
cpuID, err := strconv.ParseInt(cpu[3:], 10, 64)
|
||||
if err != nil {
|
||||
return CPUStat{}, -1, fmt.Errorf("couldn't parse %q (cpu/cpuid): %w", line, err)
|
||||
return CPUStat{}, -1, fmt.Errorf("%w: couldn't parse %q (cpu/cpuid): %w", ErrFileParse, line, err)
|
||||
}
|
||||
|
||||
return cpuStat, cpuID, nil
|
||||
@@ -136,7 +137,7 @@ func parseSoftIRQStat(line string) (SoftIRQStat, uint64, error) {
|
||||
&softIRQStat.Hrtimer, &softIRQStat.Rcu)
|
||||
|
||||
if err != nil {
|
||||
return SoftIRQStat{}, 0, fmt.Errorf("couldn't parse %q (softirq): %w", line, err)
|
||||
return SoftIRQStat{}, 0, fmt.Errorf("%w: couldn't parse %q (softirq): %w", ErrFileParse, line, err)
|
||||
}
|
||||
|
||||
return softIRQStat, total, nil
|
||||
@@ -187,6 +188,10 @@ func parseStat(r io.Reader, fileName string) (Stat, error) {
|
||||
err error
|
||||
)
|
||||
|
||||
// Increase default scanner buffer to handle very long `intr` lines.
|
||||
buf := make([]byte, 0, 8*1024)
|
||||
scanner.Buffer(buf, 1024*1024)
|
||||
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
parts := strings.Fields(scanner.Text())
|
||||
@@ -197,34 +202,34 @@ func parseStat(r io.Reader, fileName string) (Stat, error) {
|
||||
switch {
|
||||
case parts[0] == "btime":
|
||||
if stat.BootTime, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
|
||||
return Stat{}, fmt.Errorf("couldn't parse %q (btime): %w", parts[1], err)
|
||||
return Stat{}, fmt.Errorf("%w: couldn't parse %q (btime): %w", ErrFileParse, 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 %q (intr): %w", parts[1], err)
|
||||
return Stat{}, fmt.Errorf("%w: couldn't parse %q (intr): %w", ErrFileParse, 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 %q (intr%d): %w", count, i, err)
|
||||
return Stat{}, fmt.Errorf("%w: couldn't parse %q (intr%d): %w", ErrFileParse, 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 %q (ctxt): %w", parts[1], err)
|
||||
return Stat{}, fmt.Errorf("%w: couldn't parse %q (ctxt): %w", ErrFileParse, 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 %q (processes): %w", parts[1], err)
|
||||
return Stat{}, fmt.Errorf("%w: couldn't parse %q (processes): %w", ErrFileParse, 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 %q (procs_running): %w", parts[1], err)
|
||||
return Stat{}, fmt.Errorf("%w: couldn't parse %q (procs_running): %w", ErrFileParse, 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 %q (procs_blocked): %w", parts[1], err)
|
||||
return Stat{}, fmt.Errorf("%w: couldn't parse %q (procs_blocked): %w", ErrFileParse, parts[1], err)
|
||||
}
|
||||
case parts[0] == "softirq":
|
||||
softIRQStats, total, err := parseSoftIRQStat(line)
|
||||
@@ -247,7 +252,7 @@ func parseStat(r io.Reader, fileName string) (Stat, error) {
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return Stat{}, fmt.Errorf("couldn't parse %q: %w", fileName, err)
|
||||
return Stat{}, fmt.Errorf("%w: couldn't parse %q: %w", ErrFileParse, fileName, err)
|
||||
}
|
||||
|
||||
return stat, nil
|
||||
|
||||
10
vendor/github.com/prometheus/procfs/swaps.go
generated
vendored
10
vendor/github.com/prometheus/procfs/swaps.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -64,7 +64,7 @@ func parseSwapString(swapString string) (*Swap, error) {
|
||||
swapFields := strings.Fields(swapString)
|
||||
swapLength := len(swapFields)
|
||||
if swapLength < 5 {
|
||||
return nil, fmt.Errorf("too few fields in swap string: %s", swapString)
|
||||
return nil, fmt.Errorf("%w: too few fields in swap string: %s", ErrFileParse, swapString)
|
||||
}
|
||||
|
||||
swap := &Swap{
|
||||
@@ -74,15 +74,15 @@ func parseSwapString(swapString string) (*Swap, error) {
|
||||
|
||||
swap.Size, err = strconv.Atoi(swapFields[2])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid swap size: %s", swapFields[2])
|
||||
return nil, fmt.Errorf("%w: invalid swap size: %s: %w", ErrFileParse, swapFields[2], err)
|
||||
}
|
||||
swap.Used, err = strconv.Atoi(swapFields[3])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid swap used: %s", swapFields[3])
|
||||
return nil, fmt.Errorf("%w: invalid swap used: %s: %w", ErrFileParse, swapFields[3], err)
|
||||
}
|
||||
swap.Priority, err = strconv.Atoi(swapFields[4])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid swap priority: %s", swapFields[4])
|
||||
return nil, fmt.Errorf("%w: invalid swap priority: %s: %w", ErrFileParse, swapFields[4], err)
|
||||
}
|
||||
|
||||
return swap, nil
|
||||
|
||||
13
vendor/github.com/prometheus/procfs/thread.go
generated
vendored
13
vendor/github.com/prometheus/procfs/thread.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -45,7 +45,7 @@ func (fs FS) AllThreads(pid int) (Procs, error) {
|
||||
|
||||
names, err := d.Readdirnames(-1)
|
||||
if err != nil {
|
||||
return Procs{}, fmt.Errorf("could not read %q: %w", d.Name(), err)
|
||||
return Procs{}, fmt.Errorf("%w: could not read %q: %w", ErrFileRead, d.Name(), err)
|
||||
}
|
||||
|
||||
t := Procs{}
|
||||
@@ -54,7 +54,8 @@ func (fs FS) AllThreads(pid int) (Procs, error) {
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
t = append(t, Proc{PID: int(tid), fs: fsi.FS(taskPath)})
|
||||
|
||||
t = append(t, Proc{PID: int(tid), fs: FS{fsi.FS(taskPath), fs.isReal}})
|
||||
}
|
||||
|
||||
return t, nil
|
||||
@@ -66,13 +67,13 @@ func (fs FS) Thread(pid, tid int) (Proc, error) {
|
||||
if _, err := os.Stat(taskPath); err != nil {
|
||||
return Proc{}, err
|
||||
}
|
||||
return Proc{PID: tid, fs: fsi.FS(taskPath)}, nil
|
||||
return Proc{PID: tid, fs: FS{fsi.FS(taskPath), fs.isReal}}, nil
|
||||
}
|
||||
|
||||
// Thread returns a process for a given TID of Proc.
|
||||
func (proc Proc) Thread(tid int) (Proc, error) {
|
||||
tfs := fsi.FS(proc.path("task"))
|
||||
if _, err := os.Stat(tfs.Path(strconv.Itoa(tid))); err != nil {
|
||||
tfs := FS{fsi.FS(proc.path("task")), proc.fs.isReal}
|
||||
if _, err := os.Stat(tfs.proc.Path(strconv.Itoa(tid))); err != nil {
|
||||
return Proc{}, err
|
||||
}
|
||||
return Proc{PID: tid, fs: tfs}, nil
|
||||
|
||||
4
vendor/github.com/prometheus/procfs/vm.go
generated
vendored
4
vendor/github.com/prometheus/procfs/vm.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -86,7 +86,7 @@ func (fs FS) VM() (*VM, error) {
|
||||
return nil, err
|
||||
}
|
||||
if !file.Mode().IsDir() {
|
||||
return nil, fmt.Errorf("%s is not a directory", path)
|
||||
return nil, fmt.Errorf("%w: %s is not a directory", ErrFileRead, path)
|
||||
}
|
||||
|
||||
files, err := os.ReadDir(path)
|
||||
|
||||
12
vendor/github.com/prometheus/procfs/zoneinfo.go
generated
vendored
12
vendor/github.com/prometheus/procfs/zoneinfo.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019 The Prometheus Authors
|
||||
// Copyright 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
|
||||
@@ -75,11 +75,11 @@ var nodeZoneRE = regexp.MustCompile(`(\d+), zone\s+(\w+)`)
|
||||
func (fs FS) Zoneinfo() ([]Zoneinfo, error) {
|
||||
data, err := os.ReadFile(fs.proc.Path("zoneinfo"))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading zoneinfo %q: %w", fs.proc.Path("zoneinfo"), err)
|
||||
return nil, fmt.Errorf("%w: error reading zoneinfo %q: %w", ErrFileRead, fs.proc.Path("zoneinfo"), err)
|
||||
}
|
||||
zoneinfo, err := parseZoneinfo(data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing zoneinfo %q: %w", fs.proc.Path("zoneinfo"), err)
|
||||
return nil, fmt.Errorf("%w: error parsing zoneinfo %q: %w", ErrFileParse, fs.proc.Path("zoneinfo"), err)
|
||||
}
|
||||
return zoneinfo, nil
|
||||
}
|
||||
@@ -88,11 +88,9 @@ func parseZoneinfo(zoneinfoData []byte) ([]Zoneinfo, error) {
|
||||
|
||||
zoneinfo := []Zoneinfo{}
|
||||
|
||||
zoneinfoBlocks := bytes.Split(zoneinfoData, []byte("\nNode"))
|
||||
for _, block := range zoneinfoBlocks {
|
||||
for block := range bytes.SplitSeq(zoneinfoData, []byte("\nNode")) {
|
||||
var zoneinfoElement Zoneinfo
|
||||
lines := strings.Split(string(block), "\n")
|
||||
for _, line := range lines {
|
||||
for line := range strings.SplitSeq(string(block), "\n") {
|
||||
|
||||
if nodeZone := nodeZoneRE.FindStringSubmatch(line); nodeZone != nil {
|
||||
zoneinfoElement.Node = nodeZone[1]
|
||||
|
||||
Reference in New Issue
Block a user