vendor: update docker/go-metrics v0.0.1
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
6b972e50fe
commit
98dcc5195e
216 changed files with 25458 additions and 3611 deletions
1
vendor/github.com/prometheus/procfs/.gitignore
generated
vendored
Normal file
1
vendor/github.com/prometheus/procfs/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/fixtures/
|
6
vendor/github.com/prometheus/procfs/.golangci.yml
generated
vendored
Normal file
6
vendor/github.com/prometheus/procfs/.golangci.yml
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Run only staticcheck for now. Additional linters will be enabled one-by-one.
|
||||
linters:
|
||||
enable:
|
||||
- staticcheck
|
||||
- govet
|
||||
disable-all: true
|
9
vendor/github.com/prometheus/procfs/.travis.yml
generated
vendored
9
vendor/github.com/prometheus/procfs/.travis.yml
generated
vendored
|
@ -1,9 +0,0 @@
|
|||
sudo: false
|
||||
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.9.x
|
||||
- 1.x
|
||||
|
||||
go_import_path: 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 +1,2 @@
|
|||
* Tobias Schmidt <tobidt@gmail.com>
|
||||
* Johannes 'fish' Ziemke <github@freigeist.org> @discordianfish
|
||||
* Paul Gier <pgier@redhat.com> @pgier
|
||||
|
|
39
vendor/github.com/prometheus/procfs/Makefile
generated
vendored
39
vendor/github.com/prometheus/procfs/Makefile
generated
vendored
|
@ -1,18 +1,29 @@
|
|||
ci: fmt lint test
|
||||
# Copyright 2018 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.
|
||||
|
||||
fmt:
|
||||
! gofmt -l *.go | read nothing
|
||||
go vet
|
||||
include Makefile.common
|
||||
|
||||
lint:
|
||||
go get github.com/golang/lint/golint
|
||||
golint *.go
|
||||
|
||||
test: sysfs/fixtures/.unpacked
|
||||
go test -v ./...
|
||||
|
||||
sysfs/fixtures/.unpacked: sysfs/fixtures.ttar
|
||||
./ttar -C sysfs -x -f sysfs/fixtures.ttar
|
||||
%/.unpacked: %.ttar
|
||||
@echo ">> extracting fixtures"
|
||||
./ttar -C $(dir $*) -x -f $*.ttar
|
||||
touch $@
|
||||
|
||||
.PHONY: fmt lint test ci
|
||||
update_fixtures:
|
||||
rm -vf fixtures/.unpacked
|
||||
./ttar -c -f fixtures.ttar fixtures/
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
|
||||
.PHONY: test
|
||||
test: fixtures/.unpacked common-test
|
||||
|
|
275
vendor/github.com/prometheus/procfs/Makefile.common
generated
vendored
Normal file
275
vendor/github.com/prometheus/procfs/Makefile.common
generated
vendored
Normal file
|
@ -0,0 +1,275 @@
|
|||
# Copyright 2018 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.
|
||||
|
||||
|
||||
# A common Makefile that includes rules to be reused in different prometheus projects.
|
||||
# !!! Open PRs only against the prometheus/prometheus/Makefile.common repository!
|
||||
|
||||
# Example usage :
|
||||
# Create the main Makefile in the root project directory.
|
||||
# include Makefile.common
|
||||
# customTarget:
|
||||
# @echo ">> Running customTarget"
|
||||
#
|
||||
|
||||
# Ensure GOBIN is not set during build so that promu is installed to the correct path
|
||||
unexport GOBIN
|
||||
|
||||
GO ?= go
|
||||
GOFMT ?= $(GO)fmt
|
||||
FIRST_GOPATH := $(firstword $(subst :, ,$(shell $(GO) env GOPATH)))
|
||||
GOOPTS ?=
|
||||
GOHOSTOS ?= $(shell $(GO) env GOHOSTOS)
|
||||
GOHOSTARCH ?= $(shell $(GO) env GOHOSTARCH)
|
||||
|
||||
GO_VERSION ?= $(shell $(GO) version)
|
||||
GO_VERSION_NUMBER ?= $(word 3, $(GO_VERSION))
|
||||
PRE_GO_111 ?= $(shell echo $(GO_VERSION_NUMBER) | grep -E 'go1\.(10|[0-9])\.')
|
||||
|
||||
GOVENDOR :=
|
||||
GO111MODULE :=
|
||||
ifeq (, $(PRE_GO_111))
|
||||
ifneq (,$(wildcard go.mod))
|
||||
# Enforce Go modules support just in case the directory is inside GOPATH (and for Travis CI).
|
||||
GO111MODULE := on
|
||||
|
||||
ifneq (,$(wildcard vendor))
|
||||
# Always use the local vendor/ directory to satisfy the dependencies.
|
||||
GOOPTS := $(GOOPTS) -mod=vendor
|
||||
endif
|
||||
endif
|
||||
else
|
||||
ifneq (,$(wildcard go.mod))
|
||||
ifneq (,$(wildcard vendor))
|
||||
$(warning This repository requires Go >= 1.11 because of Go modules)
|
||||
$(warning Some recipes may not work as expected as the current Go runtime is '$(GO_VERSION_NUMBER)')
|
||||
endif
|
||||
else
|
||||
# This repository isn't using Go modules (yet).
|
||||
GOVENDOR := $(FIRST_GOPATH)/bin/govendor
|
||||
endif
|
||||
endif
|
||||
PROMU := $(FIRST_GOPATH)/bin/promu
|
||||
pkgs = ./...
|
||||
|
||||
ifeq (arm, $(GOHOSTARCH))
|
||||
GOHOSTARM ?= $(shell GOARM= $(GO) env GOARM)
|
||||
GO_BUILD_PLATFORM ?= $(GOHOSTOS)-$(GOHOSTARCH)v$(GOHOSTARM)
|
||||
else
|
||||
GO_BUILD_PLATFORM ?= $(GOHOSTOS)-$(GOHOSTARCH)
|
||||
endif
|
||||
|
||||
PROMU_VERSION ?= 0.4.0
|
||||
PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz
|
||||
|
||||
GOLANGCI_LINT :=
|
||||
GOLANGCI_LINT_OPTS ?=
|
||||
GOLANGCI_LINT_VERSION ?= v1.16.0
|
||||
# golangci-lint only supports linux, darwin and windows platforms on i386/amd64.
|
||||
# windows isn't included here because of the path separator being different.
|
||||
ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin))
|
||||
ifeq ($(GOHOSTARCH),$(filter $(GOHOSTARCH),amd64 i386))
|
||||
GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint
|
||||
endif
|
||||
endif
|
||||
|
||||
PREFIX ?= $(shell pwd)
|
||||
BIN_DIR ?= $(shell pwd)
|
||||
DOCKER_IMAGE_TAG ?= $(subst /,-,$(shell git rev-parse --abbrev-ref HEAD))
|
||||
DOCKERFILE_PATH ?= ./
|
||||
DOCKER_REPO ?= prom
|
||||
|
||||
DOCKER_ARCHS ?= amd64
|
||||
|
||||
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))
|
||||
|
||||
ifeq ($(GOHOSTARCH),amd64)
|
||||
ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux freebsd darwin windows))
|
||||
# Only supported on amd64
|
||||
test-flags := -race
|
||||
endif
|
||||
endif
|
||||
|
||||
# This rule is used to forward a target like "build" to "common-build". This
|
||||
# allows a new "build" target to be defined in a Makefile which includes this
|
||||
# one and override "common-build" without override warnings.
|
||||
%: common-% ;
|
||||
|
||||
.PHONY: common-all
|
||||
common-all: precheck style check_license lint unused build test
|
||||
|
||||
.PHONY: common-style
|
||||
common-style:
|
||||
@echo ">> checking code style"
|
||||
@fmtRes=$$($(GOFMT) -d $$(find . -path ./vendor -prune -o -name '*.go' -print)); \
|
||||
if [ -n "$${fmtRes}" ]; then \
|
||||
echo "gofmt checking failed!"; echo "$${fmtRes}"; echo; \
|
||||
echo "Please ensure you are using $$($(GO) version) for formatting code."; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
.PHONY: common-check_license
|
||||
common-check_license:
|
||||
@echo ">> checking license header"
|
||||
@licRes=$$(for file in $$(find . -type f -iname '*.go' ! -path './vendor/*') ; do \
|
||||
awk 'NR<=3' $$file | grep -Eq "(Copyright|generated|GENERATED)" || echo $$file; \
|
||||
done); \
|
||||
if [ -n "$${licRes}" ]; then \
|
||||
echo "license header checking failed:"; echo "$${licRes}"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
.PHONY: common-deps
|
||||
common-deps:
|
||||
@echo ">> getting dependencies"
|
||||
ifdef GO111MODULE
|
||||
GO111MODULE=$(GO111MODULE) $(GO) mod download
|
||||
else
|
||||
$(GO) get $(GOOPTS) -t ./...
|
||||
endif
|
||||
|
||||
.PHONY: common-test-short
|
||||
common-test-short:
|
||||
@echo ">> running short tests"
|
||||
GO111MODULE=$(GO111MODULE) $(GO) test -short $(GOOPTS) $(pkgs)
|
||||
|
||||
.PHONY: common-test
|
||||
common-test:
|
||||
@echo ">> running all tests"
|
||||
GO111MODULE=$(GO111MODULE) $(GO) test $(test-flags) $(GOOPTS) $(pkgs)
|
||||
|
||||
.PHONY: common-format
|
||||
common-format:
|
||||
@echo ">> formatting code"
|
||||
GO111MODULE=$(GO111MODULE) $(GO) fmt $(pkgs)
|
||||
|
||||
.PHONY: common-vet
|
||||
common-vet:
|
||||
@echo ">> vetting code"
|
||||
GO111MODULE=$(GO111MODULE) $(GO) vet $(GOOPTS) $(pkgs)
|
||||
|
||||
.PHONY: common-lint
|
||||
common-lint: $(GOLANGCI_LINT)
|
||||
ifdef GOLANGCI_LINT
|
||||
@echo ">> running golangci-lint"
|
||||
ifdef GO111MODULE
|
||||
# 'go list' needs to be executed before staticcheck to prepopulate the modules cache.
|
||||
# Otherwise staticcheck might fail randomly for some reason not yet explained.
|
||||
GO111MODULE=$(GO111MODULE) $(GO) list -e -compiled -test=true -export=false -deps=true -find=false -tags= -- ./... > /dev/null
|
||||
GO111MODULE=$(GO111MODULE) $(GOLANGCI_LINT) run $(GOLANGCI_LINT_OPTS) $(pkgs)
|
||||
else
|
||||
$(GOLANGCI_LINT) run $(pkgs)
|
||||
endif
|
||||
endif
|
||||
|
||||
# For backward-compatibility.
|
||||
.PHONY: common-staticcheck
|
||||
common-staticcheck: lint
|
||||
|
||||
.PHONY: common-unused
|
||||
common-unused: $(GOVENDOR)
|
||||
ifdef GOVENDOR
|
||||
@echo ">> running check for unused packages"
|
||||
@$(GOVENDOR) list +unused | grep . && exit 1 || echo 'No unused packages'
|
||||
else
|
||||
ifdef GO111MODULE
|
||||
@echo ">> running check for unused/missing packages in go.mod"
|
||||
GO111MODULE=$(GO111MODULE) $(GO) mod tidy
|
||||
ifeq (,$(wildcard vendor))
|
||||
@git diff --exit-code -- go.sum go.mod
|
||||
else
|
||||
@echo ">> running check for unused packages in vendor/"
|
||||
GO111MODULE=$(GO111MODULE) $(GO) mod vendor
|
||||
@git diff --exit-code -- go.sum go.mod vendor/
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
.PHONY: common-build
|
||||
common-build: promu
|
||||
@echo ">> building binaries"
|
||||
GO111MODULE=$(GO111MODULE) $(PROMU) build --prefix $(PREFIX)
|
||||
|
||||
.PHONY: common-tarball
|
||||
common-tarball: promu
|
||||
@echo ">> building release tarball"
|
||||
$(PROMU) tarball --prefix $(PREFIX) $(BIN_DIR)
|
||||
|
||||
.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)" \
|
||||
--build-arg ARCH="$*" \
|
||||
--build-arg OS="linux" \
|
||||
$(DOCKERFILE_PATH)
|
||||
|
||||
.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)"
|
||||
|
||||
.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"
|
||||
|
||||
.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)"
|
||||
|
||||
.PHONY: promu
|
||||
promu: $(PROMU)
|
||||
|
||||
$(PROMU):
|
||||
$(eval PROMU_TMP := $(shell mktemp -d))
|
||||
curl -s -L $(PROMU_URL) | tar -xvzf - -C $(PROMU_TMP)
|
||||
mkdir -p $(FIRST_GOPATH)/bin
|
||||
cp $(PROMU_TMP)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM)/promu $(FIRST_GOPATH)/bin/promu
|
||||
rm -r $(PROMU_TMP)
|
||||
|
||||
.PHONY: proto
|
||||
proto:
|
||||
@echo ">> generating code from proto files"
|
||||
@./scripts/genproto.sh
|
||||
|
||||
ifdef GOLANGCI_LINT
|
||||
$(GOLANGCI_LINT):
|
||||
mkdir -p $(FIRST_GOPATH)/bin
|
||||
curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/$(GOLANGCI_LINT_VERSION)/install.sh \
|
||||
| sed -e '/install -d/d' \
|
||||
| sh -s -- -b $(FIRST_GOPATH)/bin $(GOLANGCI_LINT_VERSION)
|
||||
endif
|
||||
|
||||
ifdef GOVENDOR
|
||||
.PHONY: $(GOVENDOR)
|
||||
$(GOVENDOR):
|
||||
GOOS= GOARCH= $(GO) get -u github.com/kardianos/govendor
|
||||
endif
|
||||
|
||||
.PHONY: precheck
|
||||
precheck::
|
||||
|
||||
define PRECHECK_COMMAND_template =
|
||||
precheck:: $(1)_precheck
|
||||
|
||||
PRECHECK_COMMAND_$(1) ?= $(1) $$(strip $$(PRECHECK_OPTIONS_$(1)))
|
||||
.PHONY: $(1)_precheck
|
||||
$(1)_precheck:
|
||||
@if ! $$(PRECHECK_COMMAND_$(1)) 1>/dev/null 2>&1; then \
|
||||
echo "Execution of '$$(PRECHECK_COMMAND_$(1))' command failed. Is $(1) installed?"; \
|
||||
exit 1; \
|
||||
fi
|
||||
endef
|
44
vendor/github.com/prometheus/procfs/README.md
generated
vendored
44
vendor/github.com/prometheus/procfs/README.md
generated
vendored
|
@ -1,7 +1,7 @@
|
|||
# procfs
|
||||
|
||||
This procfs package provides functions to retrieve system, kernel and process
|
||||
metrics from the pseudo-filesystem proc.
|
||||
metrics from the pseudo-filesystems /proc and /sys.
|
||||
|
||||
*WARNING*: This package is a work in progress. Its API may still break in
|
||||
backwards-incompatible ways without warnings. Use it at your own risk.
|
||||
|
@ -9,3 +9,45 @@ backwards-incompatible ways without warnings. Use it at your own risk.
|
|||
[](https://godoc.org/github.com/prometheus/procfs)
|
||||
[](https://travis-ci.org/prometheus/procfs)
|
||||
[](https://goreportcard.com/report/github.com/prometheus/procfs)
|
||||
|
||||
## Usage
|
||||
|
||||
The procfs library is organized by packages based on whether the gathered data is coming from
|
||||
/proc, /sys, or both. Each package contains an `FS` type which represents the path to either /proc, /sys, or both. For example, current cpu statistics are gathered from
|
||||
`/proc/stat` and are available via the root procfs package. First, the proc filesystem mount
|
||||
point is initialized, and then the stat information is read.
|
||||
|
||||
```go
|
||||
fs, err := procfs.NewFS("/proc")
|
||||
stats, err := fs.Stat()
|
||||
```
|
||||
|
||||
Some sub-packages such as `blockdevice`, require access to both the proc and sys filesystems.
|
||||
|
||||
```go
|
||||
fs, err := blockdevice.NewFS("/proc", "/sys")
|
||||
stats, err := fs.ProcDiskstats()
|
||||
```
|
||||
|
||||
## Building and Testing
|
||||
|
||||
The procfs library is normally built as part of another application. However, when making
|
||||
changes to the library, the `make test` command can be used to run the API test suite.
|
||||
|
||||
### Updating Test Fixtures
|
||||
|
||||
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`.
|
||||
|
||||
```bash
|
||||
rm -rf fixtures
|
||||
make test
|
||||
```
|
||||
|
||||
Next, make the required changes to the extracted files in the `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`.
|
||||
|
|
14
vendor/github.com/prometheus/procfs/buddyinfo.go
generated
vendored
14
vendor/github.com/prometheus/procfs/buddyinfo.go
generated
vendored
|
@ -31,19 +31,9 @@ type BuddyInfo struct {
|
|||
Sizes []float64
|
||||
}
|
||||
|
||||
// NewBuddyInfo reads the buddyinfo statistics.
|
||||
func NewBuddyInfo() ([]BuddyInfo, error) {
|
||||
fs, err := NewFS(DefaultMountPoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return fs.NewBuddyInfo()
|
||||
}
|
||||
|
||||
// NewBuddyInfo reads the buddyinfo statistics from the specified `proc` filesystem.
|
||||
func (fs FS) NewBuddyInfo() ([]BuddyInfo, error) {
|
||||
file, err := os.Open(fs.Path("buddyinfo"))
|
||||
func (fs FS) BuddyInfo() ([]BuddyInfo, error) {
|
||||
file, err := os.Open(fs.proc.Path("buddyinfo"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
2343
vendor/github.com/prometheus/procfs/fixtures.ttar
generated
vendored
Normal file
2343
vendor/github.com/prometheus/procfs/fixtures.ttar
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
86
vendor/github.com/prometheus/procfs/fs.go
generated
vendored
86
vendor/github.com/prometheus/procfs/fs.go
generated
vendored
|
@ -1,69 +1,43 @@
|
|||
// Copyright 2018 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 (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/prometheus/procfs/nfs"
|
||||
"github.com/prometheus/procfs/xfs"
|
||||
"github.com/prometheus/procfs/internal/fs"
|
||||
)
|
||||
|
||||
// FS represents the pseudo-filesystem proc, which provides an interface to
|
||||
// FS represents the pseudo-filesystem sys, which provides an interface to
|
||||
// kernel data structures.
|
||||
type FS string
|
||||
type FS struct {
|
||||
proc fs.FS
|
||||
}
|
||||
|
||||
// DefaultMountPoint is the common mount point of the proc filesystem.
|
||||
const DefaultMountPoint = "/proc"
|
||||
const DefaultMountPoint = fs.DefaultProcMountPoint
|
||||
|
||||
// NewFS returns a new FS mounted under the given mountPoint. It will error
|
||||
// if the mount point can't be read.
|
||||
// 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.
|
||||
func NewDefaultFS() (FS, error) {
|
||||
return NewFS(DefaultMountPoint)
|
||||
}
|
||||
|
||||
// NewFS returns a new proc FS mounted under the given proc mountPoint. It will error
|
||||
// if the mount point directory can't be read or is a file.
|
||||
func NewFS(mountPoint string) (FS, error) {
|
||||
info, err := os.Stat(mountPoint)
|
||||
fs, err := fs.NewFS(mountPoint)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("could not read %s: %s", mountPoint, err)
|
||||
return FS{}, err
|
||||
}
|
||||
if !info.IsDir() {
|
||||
return "", fmt.Errorf("mount point %s is not a directory", mountPoint)
|
||||
}
|
||||
|
||||
return FS(mountPoint), nil
|
||||
}
|
||||
|
||||
// Path returns the path of the given subsystem relative to the procfs root.
|
||||
func (fs FS) Path(p ...string) string {
|
||||
return path.Join(append([]string{string(fs)}, p...)...)
|
||||
}
|
||||
|
||||
// XFSStats retrieves XFS filesystem runtime statistics.
|
||||
func (fs FS) XFSStats() (*xfs.Stats, error) {
|
||||
f, err := os.Open(fs.Path("fs/xfs/stat"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
return xfs.ParseStats(f)
|
||||
}
|
||||
|
||||
// NFSdClientRPCStats retrieves NFS daemon RPC statistics.
|
||||
func (fs FS) NFSdClientRPCStats() (*nfs.ClientRPCStats, error) {
|
||||
f, err := os.Open(fs.Path("net/rpc/nfs"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
return nfs.ParseClientRPCStats(f)
|
||||
}
|
||||
|
||||
// NFSdServerRPCStats retrieves NFS daemon RPC statistics.
|
||||
func (fs FS) NFSdServerRPCStats() (*nfs.ServerRPCStats, error) {
|
||||
f, err := os.Open(fs.Path("net/rpc/nfsd"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
return nfs.ParseServerRPCStats(f)
|
||||
return FS{fs}, nil
|
||||
}
|
||||
|
|
6
vendor/github.com/prometheus/procfs/go.mod
generated
vendored
Normal file
6
vendor/github.com/prometheus/procfs/go.mod
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
module github.com/prometheus/procfs
|
||||
|
||||
require (
|
||||
github.com/google/go-cmp v0.3.0
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4
|
||||
)
|
4
vendor/github.com/prometheus/procfs/go.sum
generated
vendored
Normal file
4
vendor/github.com/prometheus/procfs/go.sum
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
55
vendor/github.com/prometheus/procfs/internal/fs/fs.go
generated
vendored
Normal file
55
vendor/github.com/prometheus/procfs/internal/fs/fs.go
generated
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
// Copyright 2019 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 fs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultProcMountPoint is the common mount point of the proc filesystem.
|
||||
DefaultProcMountPoint = "/proc"
|
||||
|
||||
// DefaultSysMountPoint is the common mount point of the sys filesystem.
|
||||
DefaultSysMountPoint = "/sys"
|
||||
|
||||
// DefaultConfigfsMountPoint is the commont mount point of the configfs
|
||||
DefaultConfigfsMountPoint = "/sys/kernel/config"
|
||||
)
|
||||
|
||||
// FS represents a pseudo-filesystem, normally /proc or /sys, which provides an
|
||||
// interface to kernel data structures.
|
||||
type FS string
|
||||
|
||||
// NewFS returns a new FS mounted under the given mountPoint. It will error
|
||||
// if the mount point can't be read.
|
||||
func NewFS(mountPoint string) (FS, error) {
|
||||
info, err := os.Stat(mountPoint)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("could not read %s: %s", mountPoint, err)
|
||||
}
|
||||
if !info.IsDir() {
|
||||
return "", fmt.Errorf("mount point %s is not a directory", mountPoint)
|
||||
}
|
||||
|
||||
return FS(mountPoint), nil
|
||||
}
|
||||
|
||||
// Path appends the given path elements to the filesystem path, adding separators
|
||||
// as necessary.
|
||||
func (fs FS) Path(p ...string) string {
|
||||
return filepath.Join(append([]string{string(fs)}, p...)...)
|
||||
}
|
46
vendor/github.com/prometheus/procfs/internal/util/parse.go
generated
vendored
46
vendor/github.com/prometheus/procfs/internal/util/parse.go
generated
vendored
|
@ -1,46 +0,0 @@
|
|||
// Copyright 2018 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 util
|
||||
|
||||
import "strconv"
|
||||
|
||||
// ParseUint32s parses a slice of strings into a slice of uint32s.
|
||||
func ParseUint32s(ss []string) ([]uint32, error) {
|
||||
us := make([]uint32, 0, len(ss))
|
||||
for _, s := range ss {
|
||||
u, err := strconv.ParseUint(s, 10, 32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
us = append(us, uint32(u))
|
||||
}
|
||||
|
||||
return us, nil
|
||||
}
|
||||
|
||||
// ParseUint64s parses a slice of strings into a slice of uint64s.
|
||||
func ParseUint64s(ss []string) ([]uint64, error) {
|
||||
us := make([]uint64, 0, len(ss))
|
||||
for _, s := range ss {
|
||||
u, err := strconv.ParseUint(s, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
us = append(us, u)
|
||||
}
|
||||
|
||||
return us, nil
|
||||
}
|
45
vendor/github.com/prometheus/procfs/ipvs.go
generated
vendored
45
vendor/github.com/prometheus/procfs/ipvs.go
generated
vendored
|
@ -1,3 +1,16 @@
|
|||
// Copyright 2018 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 (
|
||||
|
@ -49,19 +62,9 @@ type IPVSBackendStatus struct {
|
|||
Weight uint64
|
||||
}
|
||||
|
||||
// NewIPVSStats reads the IPVS statistics.
|
||||
func NewIPVSStats() (IPVSStats, error) {
|
||||
fs, err := NewFS(DefaultMountPoint)
|
||||
if err != nil {
|
||||
return IPVSStats{}, err
|
||||
}
|
||||
|
||||
return fs.NewIPVSStats()
|
||||
}
|
||||
|
||||
// NewIPVSStats reads the IPVS statistics from the specified `proc` filesystem.
|
||||
func (fs FS) NewIPVSStats() (IPVSStats, error) {
|
||||
file, err := os.Open(fs.Path("net/ip_vs_stats"))
|
||||
// IPVSStats reads the IPVS statistics from the specified `proc` filesystem.
|
||||
func (fs FS) IPVSStats() (IPVSStats, error) {
|
||||
file, err := os.Open(fs.proc.Path("net/ip_vs_stats"))
|
||||
if err != nil {
|
||||
return IPVSStats{}, err
|
||||
}
|
||||
|
@ -118,19 +121,9 @@ func parseIPVSStats(file io.Reader) (IPVSStats, error) {
|
|||
return stats, nil
|
||||
}
|
||||
|
||||
// NewIPVSBackendStatus reads and returns the status of all (virtual,real) server pairs.
|
||||
func NewIPVSBackendStatus() ([]IPVSBackendStatus, error) {
|
||||
fs, err := NewFS(DefaultMountPoint)
|
||||
if err != nil {
|
||||
return []IPVSBackendStatus{}, err
|
||||
}
|
||||
|
||||
return fs.NewIPVSBackendStatus()
|
||||
}
|
||||
|
||||
// NewIPVSBackendStatus reads and returns the status of all (virtual,real) server pairs from the specified `proc` filesystem.
|
||||
func (fs FS) NewIPVSBackendStatus() ([]IPVSBackendStatus, error) {
|
||||
file, err := os.Open(fs.Path("net/ip_vs"))
|
||||
// IPVSBackendStatus reads and returns the status of all (virtual,real) server pairs from the specified `proc` filesystem.
|
||||
func (fs FS) IPVSBackendStatus() ([]IPVSBackendStatus, error) {
|
||||
file, err := os.Open(fs.proc.Path("net/ip_vs"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
158
vendor/github.com/prometheus/procfs/mdstat.go
generated
vendored
158
vendor/github.com/prometheus/procfs/mdstat.go
generated
vendored
|
@ -1,3 +1,16 @@
|
|||
// Copyright 2018 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 (
|
||||
|
@ -9,8 +22,8 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
statuslineRE = regexp.MustCompile(`(\d+) blocks .*\[(\d+)/(\d+)\] \[[U_]+\]`)
|
||||
buildlineRE = regexp.MustCompile(`\((\d+)/\d+\)`)
|
||||
statusLineRE = regexp.MustCompile(`(\d+) blocks .*\[(\d+)/(\d+)\] \[[U_]+\]`)
|
||||
recoveryLineRE = regexp.MustCompile(`\((\d+)/\d+\)`)
|
||||
)
|
||||
|
||||
// MDStat holds info parsed from /proc/mdstat.
|
||||
|
@ -21,117 +34,160 @@ type MDStat struct {
|
|||
ActivityState string
|
||||
// Number of active disks.
|
||||
DisksActive int64
|
||||
// Total number of disks the device consists of.
|
||||
// Total number of disks the device requires.
|
||||
DisksTotal int64
|
||||
// Number of failed disks.
|
||||
DisksFailed int64
|
||||
// Spare disks in the device.
|
||||
DisksSpare int64
|
||||
// Number of blocks the device holds.
|
||||
BlocksTotal int64
|
||||
// Number of blocks on the device that are in sync.
|
||||
BlocksSynced int64
|
||||
}
|
||||
|
||||
// ParseMDStat parses an mdstat-file and returns a struct with the relevant infos.
|
||||
func (fs FS) ParseMDStat() (mdstates []MDStat, err error) {
|
||||
mdStatusFilePath := fs.Path("mdstat")
|
||||
content, err := ioutil.ReadFile(mdStatusFilePath)
|
||||
// MDStat parses an mdstat-file (/proc/mdstat) and returns a slice of
|
||||
// structs containing the relevant info. More information available here:
|
||||
// https://raid.wiki.kernel.org/index.php/Mdstat
|
||||
func (fs FS) MDStat() ([]MDStat, error) {
|
||||
data, err := ioutil.ReadFile(fs.proc.Path("mdstat"))
|
||||
if err != nil {
|
||||
return []MDStat{}, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err)
|
||||
return nil, fmt.Errorf("error parsing mdstat %s: %s", fs.proc.Path("mdstat"), err)
|
||||
}
|
||||
mdstat, err := parseMDStat(data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing mdstat %s: %s", fs.proc.Path("mdstat"), err)
|
||||
}
|
||||
return mdstat, nil
|
||||
}
|
||||
|
||||
mdStates := []MDStat{}
|
||||
lines := strings.Split(string(content), "\n")
|
||||
for i, l := range lines {
|
||||
if l == "" {
|
||||
continue
|
||||
}
|
||||
if l[0] == ' ' {
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(l, "Personalities") || strings.HasPrefix(l, "unused") {
|
||||
// parseMDStat parses data from mdstat file (/proc/mdstat) and returns a slice of
|
||||
// structs containing the relevant info.
|
||||
func parseMDStat(mdStatData []byte) ([]MDStat, error) {
|
||||
mdStats := []MDStat{}
|
||||
lines := strings.Split(string(mdStatData), "\n")
|
||||
|
||||
for i, line := range lines {
|
||||
if strings.TrimSpace(line) == "" || line[0] == ' ' ||
|
||||
strings.HasPrefix(line, "Personalities") ||
|
||||
strings.HasPrefix(line, "unused") {
|
||||
continue
|
||||
}
|
||||
|
||||
mainLine := strings.Split(l, " ")
|
||||
if len(mainLine) < 3 {
|
||||
return mdStates, fmt.Errorf("error parsing mdline: %s", l)
|
||||
deviceFields := strings.Fields(line)
|
||||
if len(deviceFields) < 3 {
|
||||
return nil, fmt.Errorf("not enough fields in mdline (expected at least 3): %s", line)
|
||||
}
|
||||
mdName := mainLine[0]
|
||||
activityState := mainLine[2]
|
||||
mdName := deviceFields[0] // mdx
|
||||
state := deviceFields[2] // active or inactive
|
||||
|
||||
if len(lines) <= i+3 {
|
||||
return mdStates, fmt.Errorf(
|
||||
"error parsing %s: too few lines for md device %s",
|
||||
mdStatusFilePath,
|
||||
return nil, fmt.Errorf(
|
||||
"error parsing %s: too few lines for md device",
|
||||
mdName,
|
||||
)
|
||||
}
|
||||
|
||||
active, total, size, err := evalStatusline(lines[i+1])
|
||||
// Failed 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, size, err := evalStatusLine(lines[i], lines[i+1])
|
||||
|
||||
if err != nil {
|
||||
return mdStates, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err)
|
||||
return nil, fmt.Errorf("error parsing md device lines: %s", err)
|
||||
}
|
||||
|
||||
// j is the line number of the syncing-line.
|
||||
j := i + 2
|
||||
syncLineIdx := i + 2
|
||||
if strings.Contains(lines[i+2], "bitmap") { // skip bitmap line
|
||||
j = i + 3
|
||||
syncLineIdx++
|
||||
}
|
||||
|
||||
// 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
|
||||
if strings.Contains(lines[j], "recovery") || strings.Contains(lines[j], "resync") {
|
||||
syncedBlocks, err = evalBuildline(lines[j])
|
||||
if err != nil {
|
||||
return mdStates, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err)
|
||||
recovering := strings.Contains(lines[syncLineIdx], "recovery")
|
||||
resyncing := strings.Contains(lines[syncLineIdx], "resync")
|
||||
|
||||
// Append recovery and resyncing state info.
|
||||
if recovering || resyncing {
|
||||
if recovering {
|
||||
state = "recovering"
|
||||
} else {
|
||||
state = "resyncing"
|
||||
}
|
||||
|
||||
// Handle case when resync=PENDING or resync=DELAYED.
|
||||
if strings.Contains(lines[syncLineIdx], "PENDING") ||
|
||||
strings.Contains(lines[syncLineIdx], "DELAYED") {
|
||||
syncedBlocks = 0
|
||||
} else {
|
||||
syncedBlocks, err = evalRecoveryLine(lines[syncLineIdx])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing sync line in md device %s: %s", mdName, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mdStates = append(mdStates, MDStat{
|
||||
mdStats = append(mdStats, MDStat{
|
||||
Name: mdName,
|
||||
ActivityState: activityState,
|
||||
ActivityState: state,
|
||||
DisksActive: active,
|
||||
DisksFailed: fail,
|
||||
DisksSpare: spare,
|
||||
DisksTotal: total,
|
||||
BlocksTotal: size,
|
||||
BlocksSynced: syncedBlocks,
|
||||
})
|
||||
}
|
||||
|
||||
return mdStates, nil
|
||||
return mdStats, nil
|
||||
}
|
||||
|
||||
func evalStatusline(statusline string) (active, total, size int64, err error) {
|
||||
matches := statuslineRE.FindStringSubmatch(statusline)
|
||||
if len(matches) != 4 {
|
||||
return 0, 0, 0, fmt.Errorf("unexpected statusline: %s", statusline)
|
||||
func evalStatusLine(deviceLine, statusLine string) (active, total, size int64, err error) {
|
||||
|
||||
sizeStr := strings.Fields(statusLine)[0]
|
||||
size, err = strconv.ParseInt(sizeStr, 10, 64)
|
||||
if err != nil {
|
||||
return 0, 0, 0, fmt.Errorf("unexpected statusLine %s: %s", statusLine, err)
|
||||
}
|
||||
|
||||
size, err = strconv.ParseInt(matches[1], 10, 64)
|
||||
if err != nil {
|
||||
return 0, 0, 0, fmt.Errorf("unexpected statusline %s: %s", statusline, err)
|
||||
if strings.Contains(deviceLine, "raid0") || strings.Contains(deviceLine, "linear") {
|
||||
// In the device deviceLine, only disks have a number associated with them in [].
|
||||
total = int64(strings.Count(deviceLine, "["))
|
||||
return total, total, size, nil
|
||||
}
|
||||
|
||||
if strings.Contains(deviceLine, "inactive") {
|
||||
return 0, 0, size, nil
|
||||
}
|
||||
|
||||
matches := statusLineRE.FindStringSubmatch(statusLine)
|
||||
if len(matches) != 4 {
|
||||
return 0, 0, 0, fmt.Errorf("couldn't find all the substring matches: %s", statusLine)
|
||||
}
|
||||
|
||||
total, err = strconv.ParseInt(matches[2], 10, 64)
|
||||
if err != nil {
|
||||
return 0, 0, 0, fmt.Errorf("unexpected statusline %s: %s", statusline, err)
|
||||
return 0, 0, 0, fmt.Errorf("unexpected statusLine %s: %s", statusLine, err)
|
||||
}
|
||||
|
||||
active, err = strconv.ParseInt(matches[3], 10, 64)
|
||||
if err != nil {
|
||||
return 0, 0, 0, fmt.Errorf("unexpected statusline %s: %s", statusline, err)
|
||||
return 0, 0, 0, fmt.Errorf("unexpected statusLine %s: %s", statusLine, err)
|
||||
}
|
||||
|
||||
return active, total, size, nil
|
||||
}
|
||||
|
||||
func evalBuildline(buildline string) (syncedBlocks int64, err error) {
|
||||
matches := buildlineRE.FindStringSubmatch(buildline)
|
||||
func evalRecoveryLine(recoveryLine string) (syncedBlocks int64, err error) {
|
||||
matches := recoveryLineRE.FindStringSubmatch(recoveryLine)
|
||||
if len(matches) != 2 {
|
||||
return 0, fmt.Errorf("unexpected buildline: %s", buildline)
|
||||
return 0, fmt.Errorf("unexpected recoveryLine: %s", recoveryLine)
|
||||
}
|
||||
|
||||
syncedBlocks, err = strconv.ParseInt(matches[1], 10, 64)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("%s in buildline: %s", err, buildline)
|
||||
return 0, fmt.Errorf("%s in recoveryLine: %s", err, recoveryLine)
|
||||
}
|
||||
|
||||
return syncedBlocks, nil
|
||||
|
|
178
vendor/github.com/prometheus/procfs/mountinfo.go
generated
vendored
Normal file
178
vendor/github.com/prometheus/procfs/mountinfo.go
generated
vendored
Normal file
|
@ -0,0 +1,178 @@
|
|||
// Copyright 2019 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"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var validOptionalFields = map[string]bool{
|
||||
"shared": true,
|
||||
"master": true,
|
||||
"propagate_from": true,
|
||||
"unbindable": true,
|
||||
}
|
||||
|
||||
// A MountInfo is a type that describes the details, options
|
||||
// for each mount, parsed from /proc/self/mountinfo.
|
||||
// The fields described in each entry of /proc/self/mountinfo
|
||||
// is described in the following man page.
|
||||
// http://man7.org/linux/man-pages/man5/proc.5.html
|
||||
type MountInfo struct {
|
||||
// Unique Id for the mount
|
||||
MountId int
|
||||
// The Id of the parent mount
|
||||
ParentId int
|
||||
// The value of `st_dev` for the files on this FS
|
||||
MajorMinorVer string
|
||||
// The pathname of the directory in the FS that forms
|
||||
// the root for this mount
|
||||
Root string
|
||||
// The pathname of the mount point relative to the root
|
||||
MountPoint string
|
||||
// Mount options
|
||||
Options map[string]string
|
||||
// Zero or more optional fields
|
||||
OptionalFields map[string]string
|
||||
// The Filesystem type
|
||||
FSType string
|
||||
// FS specific information or "none"
|
||||
Source string
|
||||
// Superblock options
|
||||
SuperOptions map[string]string
|
||||
}
|
||||
|
||||
// Returns part of the mountinfo line, if it exists, else an empty string.
|
||||
func getStringSliceElement(parts []string, idx int, defaultValue string) string {
|
||||
if idx >= len(parts) {
|
||||
return defaultValue
|
||||
}
|
||||
return parts[idx]
|
||||
}
|
||||
|
||||
// Reads each line of the mountinfo file, and returns a list of formatted MountInfo structs.
|
||||
func parseMountInfo(r io.Reader) ([]*MountInfo, error) {
|
||||
mounts := []*MountInfo{}
|
||||
scanner := bufio.NewScanner(r)
|
||||
for scanner.Scan() {
|
||||
mountString := scanner.Text()
|
||||
parsedMounts, err := parseMountInfoString(mountString)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mounts = append(mounts, parsedMounts)
|
||||
}
|
||||
|
||||
err := scanner.Err()
|
||||
return mounts, err
|
||||
}
|
||||
|
||||
// Parses a mountinfo file line, and converts it to a MountInfo struct.
|
||||
// An important check here is to see if the hyphen separator, as if it does not exist,
|
||||
// it means that the line is malformed.
|
||||
func parseMountInfoString(mountString string) (*MountInfo, error) {
|
||||
var err error
|
||||
|
||||
// OptionalFields can be zero, hence these checks to ensure we do not populate the wrong values in the wrong spots
|
||||
separatorIndex := strings.Index(mountString, "-")
|
||||
if separatorIndex == -1 {
|
||||
return nil, fmt.Errorf("no separator found in mountinfo string: %s", mountString)
|
||||
}
|
||||
beforeFields := strings.Fields(mountString[:separatorIndex])
|
||||
afterFields := strings.Fields(mountString[separatorIndex+1:])
|
||||
if (len(beforeFields) + len(afterFields)) < 7 {
|
||||
return nil, fmt.Errorf("too few fields")
|
||||
}
|
||||
|
||||
mount := &MountInfo{
|
||||
MajorMinorVer: getStringSliceElement(beforeFields, 2, ""),
|
||||
Root: getStringSliceElement(beforeFields, 3, ""),
|
||||
MountPoint: getStringSliceElement(beforeFields, 4, ""),
|
||||
Options: mountOptionsParser(getStringSliceElement(beforeFields, 5, "")),
|
||||
OptionalFields: nil,
|
||||
FSType: getStringSliceElement(afterFields, 0, ""),
|
||||
Source: getStringSliceElement(afterFields, 1, ""),
|
||||
SuperOptions: mountOptionsParser(getStringSliceElement(afterFields, 2, "")),
|
||||
}
|
||||
|
||||
mount.MountId, err = strconv.Atoi(getStringSliceElement(beforeFields, 0, ""))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse mount ID")
|
||||
}
|
||||
mount.ParentId, err = strconv.Atoi(getStringSliceElement(beforeFields, 1, ""))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse parent ID")
|
||||
}
|
||||
// Has optional fields, which is a space separated list of values.
|
||||
// Example: shared:2 master:7
|
||||
if len(beforeFields) > 6 {
|
||||
mount.OptionalFields = make(map[string]string)
|
||||
optionalFields := beforeFields[6:]
|
||||
for _, field := range optionalFields {
|
||||
optionSplit := strings.Split(field, ":")
|
||||
target, value := optionSplit[0], ""
|
||||
if len(optionSplit) == 2 {
|
||||
value = optionSplit[1]
|
||||
}
|
||||
// Checks if the 'keys' in the optional fields in the mountinfo line are acceptable.
|
||||
// Allowed 'keys' are shared, master, propagate_from, unbindable.
|
||||
if _, ok := validOptionalFields[target]; ok {
|
||||
mount.OptionalFields[target] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
return mount, nil
|
||||
}
|
||||
|
||||
// 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 {
|
||||
splitOption := strings.Split(opt, "=")
|
||||
if len(splitOption) < 2 {
|
||||
key := splitOption[0]
|
||||
opts[key] = ""
|
||||
} else {
|
||||
key, value := splitOption[0], splitOption[1]
|
||||
opts[key] = value
|
||||
}
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
// Retrieves mountinfo information from `/proc/self/mountinfo`.
|
||||
func GetMounts() ([]*MountInfo, error) {
|
||||
f, err := os.Open("/proc/self/mountinfo")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
return parseMountInfo(f)
|
||||
}
|
||||
|
||||
// Retrieves mountinfo information from a processes' `/proc/<pid>/mountinfo`.
|
||||
func GetProcMounts(pid int) ([]*MountInfo, error) {
|
||||
f, err := os.Open(fmt.Sprintf("/proc/%d/mountinfo", pid))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
return parseMountInfo(f)
|
||||
}
|
107
vendor/github.com/prometheus/procfs/mountstats.go
generated
vendored
107
vendor/github.com/prometheus/procfs/mountstats.go
generated
vendored
|
@ -1,3 +1,16 @@
|
|||
// Copyright 2018 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
|
||||
|
||||
// While implementing parsing of /proc/[pid]/mountstats, this blog was used
|
||||
|
@ -26,8 +39,11 @@ const (
|
|||
statVersion10 = "1.0"
|
||||
statVersion11 = "1.1"
|
||||
|
||||
fieldTransport10Len = 10
|
||||
fieldTransport11Len = 13
|
||||
fieldTransport10TCPLen = 10
|
||||
fieldTransport10UDPLen = 7
|
||||
|
||||
fieldTransport11TCPLen = 13
|
||||
fieldTransport11UDPLen = 10
|
||||
)
|
||||
|
||||
// A Mount is a device mount parsed from /proc/[pid]/mountstats.
|
||||
|
@ -53,6 +69,8 @@ type MountStats interface {
|
|||
type MountStatsNFS struct {
|
||||
// The version of statistics provided.
|
||||
StatVersion string
|
||||
// The mount options of the NFS mount.
|
||||
Opts map[string]string
|
||||
// The age of the NFS mount.
|
||||
Age time.Duration
|
||||
// Statistics related to byte counters for various operations.
|
||||
|
@ -163,16 +181,18 @@ type NFSOperationStats struct {
|
|||
// Number of bytes received for this operation, including RPC headers and payload.
|
||||
BytesReceived uint64
|
||||
// Duration all requests spent queued for transmission before they were sent.
|
||||
CumulativeQueueTime time.Duration
|
||||
CumulativeQueueMilliseconds uint64
|
||||
// Duration it took to get a reply back after the request was transmitted.
|
||||
CumulativeTotalResponseTime time.Duration
|
||||
CumulativeTotalResponseMilliseconds uint64
|
||||
// Duration from when a request was enqueued to when it was completely handled.
|
||||
CumulativeTotalRequestTime time.Duration
|
||||
CumulativeTotalRequestMilliseconds uint64
|
||||
}
|
||||
|
||||
// A NFSTransportStats contains statistics for the NFS mount RPC requests and
|
||||
// responses.
|
||||
type NFSTransportStats struct {
|
||||
// The transport protocol used for the NFS mount.
|
||||
Protocol string
|
||||
// The local port used for the NFS mount.
|
||||
Port uint64
|
||||
// Number of times the client has had to establish a connection from scratch
|
||||
|
@ -184,7 +204,7 @@ type NFSTransportStats struct {
|
|||
// spent waiting for connections to the server to be established.
|
||||
ConnectIdleTime uint64
|
||||
// Duration since the NFS mount last saw any RPC traffic.
|
||||
IdleTime time.Duration
|
||||
IdleTimeSeconds uint64
|
||||
// Number of RPC requests for this mount sent to the NFS server.
|
||||
Sends uint64
|
||||
// Number of RPC responses for this mount received from the NFS server.
|
||||
|
@ -299,6 +319,7 @@ func parseMount(ss []string) (*Mount, error) {
|
|||
func parseMountStatsNFS(s *bufio.Scanner, statVersion string) (*MountStatsNFS, error) {
|
||||
// Field indicators for parsing specific types of data
|
||||
const (
|
||||
fieldOpts = "opts:"
|
||||
fieldAge = "age:"
|
||||
fieldBytes = "bytes:"
|
||||
fieldEvents = "events:"
|
||||
|
@ -320,6 +341,18 @@ func parseMountStatsNFS(s *bufio.Scanner, statVersion string) (*MountStatsNFS, e
|
|||
}
|
||||
|
||||
switch ss[0] {
|
||||
case fieldOpts:
|
||||
if stats.Opts == nil {
|
||||
stats.Opts = map[string]string{}
|
||||
}
|
||||
for _, opt := range strings.Split(ss[1], ",") {
|
||||
split := strings.Split(opt, "=")
|
||||
if len(split) == 2 {
|
||||
stats.Opts[split[0]] = split[1]
|
||||
} else {
|
||||
stats.Opts[opt] = ""
|
||||
}
|
||||
}
|
||||
case fieldAge:
|
||||
// Age integer is in seconds
|
||||
d, err := time.ParseDuration(ss[1] + "s")
|
||||
|
@ -347,7 +380,7 @@ func parseMountStatsNFS(s *bufio.Scanner, statVersion string) (*MountStatsNFS, e
|
|||
return nil, fmt.Errorf("not enough information for NFS transport stats: %v", ss)
|
||||
}
|
||||
|
||||
tstats, err := parseNFSTransportStats(ss[2:], statVersion)
|
||||
tstats, err := parseNFSTransportStats(ss[1:], statVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -491,15 +524,15 @@ func parseNFSOperationStats(s *bufio.Scanner) ([]NFSOperationStats, error) {
|
|||
}
|
||||
|
||||
ops = append(ops, NFSOperationStats{
|
||||
Operation: strings.TrimSuffix(ss[0], ":"),
|
||||
Requests: ns[0],
|
||||
Transmissions: ns[1],
|
||||
MajorTimeouts: ns[2],
|
||||
BytesSent: ns[3],
|
||||
BytesReceived: ns[4],
|
||||
CumulativeQueueTime: time.Duration(ns[5]) * time.Millisecond,
|
||||
CumulativeTotalResponseTime: time.Duration(ns[6]) * time.Millisecond,
|
||||
CumulativeTotalRequestTime: time.Duration(ns[7]) * time.Millisecond,
|
||||
Operation: strings.TrimSuffix(ss[0], ":"),
|
||||
Requests: ns[0],
|
||||
Transmissions: ns[1],
|
||||
MajorTimeouts: ns[2],
|
||||
BytesSent: ns[3],
|
||||
BytesReceived: ns[4],
|
||||
CumulativeQueueMilliseconds: ns[5],
|
||||
CumulativeTotalResponseMilliseconds: ns[6],
|
||||
CumulativeTotalRequestMilliseconds: ns[7],
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -509,13 +542,33 @@ func parseNFSOperationStats(s *bufio.Scanner) ([]NFSOperationStats, error) {
|
|||
// parseNFSTransportStats parses a NFSTransportStats line using an input set of
|
||||
// integer fields matched to a specific stats version.
|
||||
func parseNFSTransportStats(ss []string, statVersion string) (*NFSTransportStats, error) {
|
||||
// Extract the protocol field. It is the only string value in the line
|
||||
protocol := ss[0]
|
||||
ss = ss[1:]
|
||||
|
||||
switch statVersion {
|
||||
case statVersion10:
|
||||
if len(ss) != fieldTransport10Len {
|
||||
var expectedLength int
|
||||
if protocol == "tcp" {
|
||||
expectedLength = fieldTransport10TCPLen
|
||||
} else if protocol == "udp" {
|
||||
expectedLength = fieldTransport10UDPLen
|
||||
} else {
|
||||
return nil, fmt.Errorf("invalid NFS protocol \"%s\" in stats 1.0 statement: %v", protocol, ss)
|
||||
}
|
||||
if len(ss) != expectedLength {
|
||||
return nil, fmt.Errorf("invalid NFS transport stats 1.0 statement: %v", ss)
|
||||
}
|
||||
case statVersion11:
|
||||
if len(ss) != fieldTransport11Len {
|
||||
var expectedLength int
|
||||
if protocol == "tcp" {
|
||||
expectedLength = fieldTransport11TCPLen
|
||||
} else if protocol == "udp" {
|
||||
expectedLength = fieldTransport11UDPLen
|
||||
} else {
|
||||
return nil, fmt.Errorf("invalid NFS protocol \"%s\" in stats 1.1 statement: %v", protocol, ss)
|
||||
}
|
||||
if len(ss) != expectedLength {
|
||||
return nil, fmt.Errorf("invalid NFS transport stats 1.1 statement: %v", ss)
|
||||
}
|
||||
default:
|
||||
|
@ -523,12 +576,13 @@ func parseNFSTransportStats(ss []string, statVersion string) (*NFSTransportStats
|
|||
}
|
||||
|
||||
// Allocate enough for v1.1 stats since zero value for v1.1 stats will be okay
|
||||
// in a v1.0 response.
|
||||
// in a v1.0 response. Since the stat length is bigger for TCP stats, we use
|
||||
// the TCP length here.
|
||||
//
|
||||
// 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, fieldTransport11Len)
|
||||
ns := make([]uint64, fieldTransport11TCPLen)
|
||||
for i, s := range ss {
|
||||
n, err := strconv.ParseUint(s, 10, 64)
|
||||
if err != nil {
|
||||
|
@ -538,12 +592,23 @@ func parseNFSTransportStats(ss []string, statVersion string) (*NFSTransportStats
|
|||
ns[i] = n
|
||||
}
|
||||
|
||||
// The fields differ depending on the transport protocol (TCP or UDP)
|
||||
// From https://utcc.utoronto.ca/%7Ecks/space/blog/linux/NFSMountstatsXprt
|
||||
//
|
||||
// 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" {
|
||||
ns = append(ns[:2], append(make([]uint64, 3), ns[2:]...)...)
|
||||
}
|
||||
|
||||
return &NFSTransportStats{
|
||||
Protocol: protocol,
|
||||
Port: ns[0],
|
||||
Bind: ns[1],
|
||||
Connect: ns[2],
|
||||
ConnectIdleTime: ns[3],
|
||||
IdleTime: time.Duration(ns[4]) * time.Second,
|
||||
IdleTimeSeconds: ns[4],
|
||||
Sends: ns[5],
|
||||
Receives: ns[6],
|
||||
BadTransactionIDs: ns[7],
|
||||
|
|
53
vendor/github.com/prometheus/procfs/net_dev.go
generated
vendored
53
vendor/github.com/prometheus/procfs/net_dev.go
generated
vendored
|
@ -1,3 +1,16 @@
|
|||
// Copyright 2018 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 (
|
||||
|
@ -34,23 +47,13 @@ type NetDevLine struct {
|
|||
// are interface names.
|
||||
type NetDev map[string]NetDevLine
|
||||
|
||||
// NewNetDev returns kernel/system statistics read from /proc/net/dev.
|
||||
func NewNetDev() (NetDev, error) {
|
||||
fs, err := NewFS(DefaultMountPoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return fs.NewNetDev()
|
||||
// NetDev returns kernel/system statistics read from /proc/net/dev.
|
||||
func (fs FS) NetDev() (NetDev, error) {
|
||||
return newNetDev(fs.proc.Path("net/dev"))
|
||||
}
|
||||
|
||||
// NewNetDev returns kernel/system statistics read from /proc/net/dev.
|
||||
func (fs FS) NewNetDev() (NetDev, error) {
|
||||
return newNetDev(fs.Path("net/dev"))
|
||||
}
|
||||
|
||||
// NewNetDev returns kernel/system statistics read from /proc/[pid]/net/dev.
|
||||
func (p Proc) NewNetDev() (NetDev, error) {
|
||||
// NetDev returns kernel/system statistics read from /proc/[pid]/net/dev.
|
||||
func (p Proc) NetDev() (NetDev, error) {
|
||||
return newNetDev(p.path("net/dev"))
|
||||
}
|
||||
|
||||
|
@ -62,7 +65,7 @@ func newNetDev(file string) (NetDev, error) {
|
|||
}
|
||||
defer f.Close()
|
||||
|
||||
nd := NetDev{}
|
||||
netDev := NetDev{}
|
||||
s := bufio.NewScanner(f)
|
||||
for n := 0; s.Scan(); n++ {
|
||||
// Skip the 2 header lines.
|
||||
|
@ -70,20 +73,20 @@ func newNetDev(file string) (NetDev, error) {
|
|||
continue
|
||||
}
|
||||
|
||||
line, err := nd.parseLine(s.Text())
|
||||
line, err := netDev.parseLine(s.Text())
|
||||
if err != nil {
|
||||
return nd, err
|
||||
return netDev, err
|
||||
}
|
||||
|
||||
nd[line.Name] = *line
|
||||
netDev[line.Name] = *line
|
||||
}
|
||||
|
||||
return nd, s.Err()
|
||||
return netDev, s.Err()
|
||||
}
|
||||
|
||||
// parseLine parses a single line from the /proc/net/dev file. Header lines
|
||||
// must be filtered prior to calling this method.
|
||||
func (nd NetDev) parseLine(rawLine string) (*NetDevLine, error) {
|
||||
func (netDev NetDev) parseLine(rawLine string) (*NetDevLine, error) {
|
||||
parts := strings.SplitN(rawLine, ":", 2)
|
||||
if len(parts) != 2 {
|
||||
return nil, errors.New("invalid net/dev line, missing colon")
|
||||
|
@ -171,12 +174,12 @@ func (nd NetDev) parseLine(rawLine string) (*NetDevLine, error) {
|
|||
}
|
||||
|
||||
// Total aggregates the values across interfaces and returns a new NetDevLine.
|
||||
// The Name field will be a sorted comma seperated list of interface names.
|
||||
func (nd NetDev) Total() NetDevLine {
|
||||
// The Name field will be a sorted comma separated list of interface names.
|
||||
func (netDev NetDev) Total() NetDevLine {
|
||||
total := NetDevLine{}
|
||||
|
||||
names := make([]string, 0, len(nd))
|
||||
for _, ifc := range nd {
|
||||
names := make([]string, 0, len(netDev))
|
||||
for _, ifc := range netDev {
|
||||
names = append(names, ifc.Name)
|
||||
total.RxBytes += ifc.RxBytes
|
||||
total.RxPackets += ifc.RxPackets
|
||||
|
|
275
vendor/github.com/prometheus/procfs/net_unix.go
generated
vendored
Normal file
275
vendor/github.com/prometheus/procfs/net_unix.go
generated
vendored
Normal file
|
@ -0,0 +1,275 @@
|
|||
// Copyright 2018 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"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// For the proc file format details,
|
||||
// see https://elixir.bootlin.com/linux/v4.17/source/net/unix/af_unix.c#L2815
|
||||
// and https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/net.h#L48.
|
||||
|
||||
const (
|
||||
netUnixKernelPtrIdx = iota
|
||||
netUnixRefCountIdx
|
||||
_
|
||||
netUnixFlagsIdx
|
||||
netUnixTypeIdx
|
||||
netUnixStateIdx
|
||||
netUnixInodeIdx
|
||||
|
||||
// Inode and Path are optional.
|
||||
netUnixStaticFieldsCnt = 6
|
||||
)
|
||||
|
||||
const (
|
||||
netUnixTypeStream = 1
|
||||
netUnixTypeDgram = 2
|
||||
netUnixTypeSeqpacket = 5
|
||||
|
||||
netUnixFlagListen = 1 << 16
|
||||
|
||||
netUnixStateUnconnected = 1
|
||||
netUnixStateConnecting = 2
|
||||
netUnixStateConnected = 3
|
||||
netUnixStateDisconnected = 4
|
||||
)
|
||||
|
||||
var errInvalidKernelPtrFmt = errors.New("Invalid Num(the kernel table slot number) format")
|
||||
|
||||
// NetUnixType is the type of the type field.
|
||||
type NetUnixType uint64
|
||||
|
||||
// NetUnixFlags is the type of the flags field.
|
||||
type NetUnixFlags uint64
|
||||
|
||||
// NetUnixState is the type of the state field.
|
||||
type NetUnixState uint64
|
||||
|
||||
// NetUnixLine represents a line of /proc/net/unix.
|
||||
type NetUnixLine struct {
|
||||
KernelPtr string
|
||||
RefCount uint64
|
||||
Protocol uint64
|
||||
Flags NetUnixFlags
|
||||
Type NetUnixType
|
||||
State NetUnixState
|
||||
Inode uint64
|
||||
Path string
|
||||
}
|
||||
|
||||
// NetUnix holds the data read from /proc/net/unix.
|
||||
type NetUnix struct {
|
||||
Rows []*NetUnixLine
|
||||
}
|
||||
|
||||
// NewNetUnix returns data read from /proc/net/unix.
|
||||
func NewNetUnix() (*NetUnix, error) {
|
||||
fs, err := NewFS(DefaultMountPoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return fs.NewNetUnix()
|
||||
}
|
||||
|
||||
// NewNetUnix returns data read from /proc/net/unix.
|
||||
func (fs FS) NewNetUnix() (*NetUnix, error) {
|
||||
return NewNetUnixByPath(fs.proc.Path("net/unix"))
|
||||
}
|
||||
|
||||
// NewNetUnixByPath returns data read from /proc/net/unix by file path.
|
||||
// It might returns an error with partial parsed data, if an error occur after some data parsed.
|
||||
func NewNetUnixByPath(path string) (*NetUnix, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
return NewNetUnixByReader(f)
|
||||
}
|
||||
|
||||
// NewNetUnixByReader returns data read from /proc/net/unix by a reader.
|
||||
// It might returns an error with partial parsed data, if an error occur after some data parsed.
|
||||
func NewNetUnixByReader(reader io.Reader) (*NetUnix, error) {
|
||||
nu := &NetUnix{
|
||||
Rows: make([]*NetUnixLine, 0, 32),
|
||||
}
|
||||
scanner := bufio.NewScanner(reader)
|
||||
// Omit the header line.
|
||||
scanner.Scan()
|
||||
header := scanner.Text()
|
||||
// From the man page of proc(5), it does not contain an Inode field,
|
||||
// but in actually it exists.
|
||||
// This code works for both cases.
|
||||
hasInode := strings.Contains(header, "Inode")
|
||||
|
||||
minFieldsCnt := netUnixStaticFieldsCnt
|
||||
if hasInode {
|
||||
minFieldsCnt++
|
||||
}
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
item, err := nu.parseLine(line, hasInode, minFieldsCnt)
|
||||
if err != nil {
|
||||
return nu, err
|
||||
}
|
||||
nu.Rows = append(nu.Rows, item)
|
||||
}
|
||||
|
||||
return nu, scanner.Err()
|
||||
}
|
||||
|
||||
func (u *NetUnix) parseLine(line string, hasInode bool, minFieldsCnt int) (*NetUnixLine, error) {
|
||||
fields := strings.Fields(line)
|
||||
fieldsLen := len(fields)
|
||||
if fieldsLen < minFieldsCnt {
|
||||
return nil, fmt.Errorf(
|
||||
"Parse Unix domain failed: expect at least %d fields but got %d",
|
||||
minFieldsCnt, fieldsLen)
|
||||
}
|
||||
kernelPtr, err := u.parseKernelPtr(fields[netUnixKernelPtrIdx])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Parse Unix domain num(%s) failed: %s", fields[netUnixKernelPtrIdx], err)
|
||||
}
|
||||
users, err := u.parseUsers(fields[netUnixRefCountIdx])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Parse Unix domain ref count(%s) failed: %s", fields[netUnixRefCountIdx], err)
|
||||
}
|
||||
flags, err := u.parseFlags(fields[netUnixFlagsIdx])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Parse Unix domain flags(%s) failed: %s", fields[netUnixFlagsIdx], err)
|
||||
}
|
||||
typ, err := u.parseType(fields[netUnixTypeIdx])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Parse Unix domain type(%s) failed: %s", fields[netUnixTypeIdx], err)
|
||||
}
|
||||
state, err := u.parseState(fields[netUnixStateIdx])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Parse Unix domain state(%s) failed: %s", fields[netUnixStateIdx], err)
|
||||
}
|
||||
var inode uint64
|
||||
if hasInode {
|
||||
inodeStr := fields[netUnixInodeIdx]
|
||||
inode, err = u.parseInode(inodeStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Parse Unix domain inode(%s) failed: %s", inodeStr, err)
|
||||
}
|
||||
}
|
||||
|
||||
nuLine := &NetUnixLine{
|
||||
KernelPtr: kernelPtr,
|
||||
RefCount: users,
|
||||
Type: typ,
|
||||
Flags: flags,
|
||||
State: state,
|
||||
Inode: inode,
|
||||
}
|
||||
|
||||
// Path field is optional.
|
||||
if fieldsLen > minFieldsCnt {
|
||||
pathIdx := netUnixInodeIdx + 1
|
||||
if !hasInode {
|
||||
pathIdx--
|
||||
}
|
||||
nuLine.Path = fields[pathIdx]
|
||||
}
|
||||
|
||||
return nuLine, nil
|
||||
}
|
||||
|
||||
func (u NetUnix) parseKernelPtr(str string) (string, error) {
|
||||
if !strings.HasSuffix(str, ":") {
|
||||
return "", errInvalidKernelPtrFmt
|
||||
}
|
||||
return str[:len(str)-1], nil
|
||||
}
|
||||
|
||||
func (u NetUnix) parseUsers(hexStr string) (uint64, error) {
|
||||
return strconv.ParseUint(hexStr, 16, 32)
|
||||
}
|
||||
|
||||
func (u NetUnix) parseProtocol(hexStr string) (uint64, error) {
|
||||
return strconv.ParseUint(hexStr, 16, 32)
|
||||
}
|
||||
|
||||
func (u NetUnix) parseType(hexStr string) (NetUnixType, error) {
|
||||
typ, err := strconv.ParseUint(hexStr, 16, 16)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return NetUnixType(typ), nil
|
||||
}
|
||||
|
||||
func (u NetUnix) parseFlags(hexStr string) (NetUnixFlags, error) {
|
||||
flags, err := strconv.ParseUint(hexStr, 16, 32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return NetUnixFlags(flags), nil
|
||||
}
|
||||
|
||||
func (u NetUnix) parseState(hexStr string) (NetUnixState, error) {
|
||||
st, err := strconv.ParseInt(hexStr, 16, 8)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return NetUnixState(st), nil
|
||||
}
|
||||
|
||||
func (u NetUnix) parseInode(inodeStr string) (uint64, error) {
|
||||
return strconv.ParseUint(inodeStr, 10, 64)
|
||||
}
|
||||
|
||||
func (t NetUnixType) String() string {
|
||||
switch t {
|
||||
case netUnixTypeStream:
|
||||
return "stream"
|
||||
case netUnixTypeDgram:
|
||||
return "dgram"
|
||||
case netUnixTypeSeqpacket:
|
||||
return "seqpacket"
|
||||
}
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
func (f NetUnixFlags) String() string {
|
||||
switch f {
|
||||
case netUnixFlagListen:
|
||||
return "listen"
|
||||
default:
|
||||
return "default"
|
||||
}
|
||||
}
|
||||
|
||||
func (s NetUnixState) String() string {
|
||||
switch s {
|
||||
case netUnixStateUnconnected:
|
||||
return "unconnected"
|
||||
case netUnixStateConnecting:
|
||||
return "connecting"
|
||||
case netUnixStateConnected:
|
||||
return "connected"
|
||||
case netUnixStateDisconnected:
|
||||
return "disconnected"
|
||||
}
|
||||
return "unknown"
|
||||
}
|
263
vendor/github.com/prometheus/procfs/nfs/nfs.go
generated
vendored
263
vendor/github.com/prometheus/procfs/nfs/nfs.go
generated
vendored
|
@ -1,263 +0,0 @@
|
|||
// Copyright 2018 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 nfsd implements parsing of /proc/net/rpc/nfsd.
|
||||
// Fields are documented in https://www.svennd.be/nfsd-stats-explained-procnetrpcnfsd/
|
||||
package nfs
|
||||
|
||||
// ReplyCache models the "rc" line.
|
||||
type ReplyCache struct {
|
||||
Hits uint64
|
||||
Misses uint64
|
||||
NoCache uint64
|
||||
}
|
||||
|
||||
// FileHandles models the "fh" line.
|
||||
type FileHandles struct {
|
||||
Stale uint64
|
||||
TotalLookups uint64
|
||||
AnonLookups uint64
|
||||
DirNoCache uint64
|
||||
NoDirNoCache uint64
|
||||
}
|
||||
|
||||
// InputOutput models the "io" line.
|
||||
type InputOutput struct {
|
||||
Read uint64
|
||||
Write uint64
|
||||
}
|
||||
|
||||
// Threads models the "th" line.
|
||||
type Threads struct {
|
||||
Threads uint64
|
||||
FullCnt uint64
|
||||
}
|
||||
|
||||
// ReadAheadCache models the "ra" line.
|
||||
type ReadAheadCache struct {
|
||||
CacheSize uint64
|
||||
CacheHistogram []uint64
|
||||
NotFound uint64
|
||||
}
|
||||
|
||||
// Network models the "net" line.
|
||||
type Network struct {
|
||||
NetCount uint64
|
||||
UDPCount uint64
|
||||
TCPCount uint64
|
||||
TCPConnect uint64
|
||||
}
|
||||
|
||||
// ClientRPC models the nfs "rpc" line.
|
||||
type ClientRPC struct {
|
||||
RPCCount uint64
|
||||
Retransmissions uint64
|
||||
AuthRefreshes uint64
|
||||
}
|
||||
|
||||
// ServerRPC models the nfsd "rpc" line.
|
||||
type ServerRPC struct {
|
||||
RPCCount uint64
|
||||
BadCnt uint64
|
||||
BadFmt uint64
|
||||
BadAuth uint64
|
||||
BadcInt uint64
|
||||
}
|
||||
|
||||
// V2Stats models the "proc2" line.
|
||||
type V2Stats struct {
|
||||
Null uint64
|
||||
GetAttr uint64
|
||||
SetAttr uint64
|
||||
Root uint64
|
||||
Lookup uint64
|
||||
ReadLink uint64
|
||||
Read uint64
|
||||
WrCache uint64
|
||||
Write uint64
|
||||
Create uint64
|
||||
Remove uint64
|
||||
Rename uint64
|
||||
Link uint64
|
||||
SymLink uint64
|
||||
MkDir uint64
|
||||
RmDir uint64
|
||||
ReadDir uint64
|
||||
FsStat uint64
|
||||
}
|
||||
|
||||
// V3Stats models the "proc3" line.
|
||||
type V3Stats struct {
|
||||
Null uint64
|
||||
GetAttr uint64
|
||||
SetAttr uint64
|
||||
Lookup uint64
|
||||
Access uint64
|
||||
ReadLink uint64
|
||||
Read uint64
|
||||
Write uint64
|
||||
Create uint64
|
||||
MkDir uint64
|
||||
SymLink uint64
|
||||
MkNod uint64
|
||||
Remove uint64
|
||||
RmDir uint64
|
||||
Rename uint64
|
||||
Link uint64
|
||||
ReadDir uint64
|
||||
ReadDirPlus uint64
|
||||
FsStat uint64
|
||||
FsInfo uint64
|
||||
PathConf uint64
|
||||
Commit uint64
|
||||
}
|
||||
|
||||
// ClientV4Stats models the nfs "proc4" line.
|
||||
type ClientV4Stats struct {
|
||||
Null uint64
|
||||
Read uint64
|
||||
Write uint64
|
||||
Commit uint64
|
||||
Open uint64
|
||||
OpenConfirm uint64
|
||||
OpenNoattr uint64
|
||||
OpenDowngrade uint64
|
||||
Close uint64
|
||||
Setattr uint64
|
||||
FsInfo uint64
|
||||
Renew uint64
|
||||
SetClientId uint64
|
||||
SetClientIdConfirm uint64
|
||||
Lock uint64
|
||||
Lockt uint64
|
||||
Locku uint64
|
||||
Access uint64
|
||||
Getattr uint64
|
||||
Lookup uint64
|
||||
LookupRoot uint64
|
||||
Remove uint64
|
||||
Rename uint64
|
||||
Link uint64
|
||||
Symlink uint64
|
||||
Create uint64
|
||||
Pathconf uint64
|
||||
StatFs uint64
|
||||
ReadLink uint64
|
||||
ReadDir uint64
|
||||
ServerCaps uint64
|
||||
DelegReturn uint64
|
||||
GetAcl uint64
|
||||
SetAcl uint64
|
||||
FsLocations uint64
|
||||
ReleaseLockowner uint64
|
||||
Secinfo uint64
|
||||
FsidPresent uint64
|
||||
ExchangeId uint64
|
||||
CreateSession uint64
|
||||
DestroySession uint64
|
||||
Sequence uint64
|
||||
GetLeaseTime uint64
|
||||
ReclaimComplete uint64
|
||||
LayoutGet uint64
|
||||
GetDeviceInfo uint64
|
||||
LayoutCommit uint64
|
||||
LayoutReturn uint64
|
||||
SecinfoNoName uint64
|
||||
TestStateId uint64
|
||||
FreeStateId uint64
|
||||
GetDeviceList uint64
|
||||
BindConnToSession uint64
|
||||
DestroyClientId uint64
|
||||
Seek uint64
|
||||
Allocate uint64
|
||||
DeAllocate uint64
|
||||
LayoutStats uint64
|
||||
Clone uint64
|
||||
}
|
||||
|
||||
// ServerV4Stats models the nfsd "proc4" line.
|
||||
type ServerV4Stats struct {
|
||||
Null uint64
|
||||
Compound uint64
|
||||
}
|
||||
|
||||
// V4Ops models the "proc4ops" line: NFSv4 operations
|
||||
// Variable list, see:
|
||||
// v4.0 https://tools.ietf.org/html/rfc3010 (38 operations)
|
||||
// v4.1 https://tools.ietf.org/html/rfc5661 (58 operations)
|
||||
// v4.2 https://tools.ietf.org/html/draft-ietf-nfsv4-minorversion2-41 (71 operations)
|
||||
type V4Ops struct {
|
||||
//Values uint64 // Variable depending on v4.x sub-version. TODO: Will this always at least include the fields in this struct?
|
||||
Op0Unused uint64
|
||||
Op1Unused uint64
|
||||
Op2Future uint64
|
||||
Access uint64
|
||||
Close uint64
|
||||
Commit uint64
|
||||
Create uint64
|
||||
DelegPurge uint64
|
||||
DelegReturn uint64
|
||||
GetAttr uint64
|
||||
GetFH uint64
|
||||
Link uint64
|
||||
Lock uint64
|
||||
Lockt uint64
|
||||
Locku uint64
|
||||
Lookup uint64
|
||||
LookupRoot uint64
|
||||
Nverify uint64
|
||||
Open uint64
|
||||
OpenAttr uint64
|
||||
OpenConfirm uint64
|
||||
OpenDgrd uint64
|
||||
PutFH uint64
|
||||
PutPubFH uint64
|
||||
PutRootFH uint64
|
||||
Read uint64
|
||||
ReadDir uint64
|
||||
ReadLink uint64
|
||||
Remove uint64
|
||||
Rename uint64
|
||||
Renew uint64
|
||||
RestoreFH uint64
|
||||
SaveFH uint64
|
||||
SecInfo uint64
|
||||
SetAttr uint64
|
||||
Verify uint64
|
||||
Write uint64
|
||||
RelLockOwner uint64
|
||||
}
|
||||
|
||||
// RPCStats models all stats from /proc/net/rpc/nfs.
|
||||
type ClientRPCStats struct {
|
||||
Network Network
|
||||
ClientRPC ClientRPC
|
||||
V2Stats V2Stats
|
||||
V3Stats V3Stats
|
||||
ClientV4Stats ClientV4Stats
|
||||
}
|
||||
|
||||
// ServerRPCStats models all stats from /proc/net/rpc/nfsd.
|
||||
type ServerRPCStats struct {
|
||||
ReplyCache ReplyCache
|
||||
FileHandles FileHandles
|
||||
InputOutput InputOutput
|
||||
Threads Threads
|
||||
ReadAheadCache ReadAheadCache
|
||||
Network Network
|
||||
ServerRPC ServerRPC
|
||||
V2Stats V2Stats
|
||||
V3Stats V3Stats
|
||||
ServerV4Stats ServerV4Stats
|
||||
V4Ops V4Ops
|
||||
}
|
308
vendor/github.com/prometheus/procfs/nfs/parse.go
generated
vendored
308
vendor/github.com/prometheus/procfs/nfs/parse.go
generated
vendored
|
@ -1,308 +0,0 @@
|
|||
// Copyright 2018 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 nfs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func parseReplyCache(v []uint64) (ReplyCache, error) {
|
||||
if len(v) != 3 {
|
||||
return ReplyCache{}, fmt.Errorf("invalid ReplyCache line %q", v)
|
||||
}
|
||||
|
||||
return ReplyCache{
|
||||
Hits: v[0],
|
||||
Misses: v[1],
|
||||
NoCache: v[2],
|
||||
}, nil
|
||||
}
|
||||
|
||||
func parseFileHandles(v []uint64) (FileHandles, error) {
|
||||
if len(v) != 5 {
|
||||
return FileHandles{}, fmt.Errorf("invalid FileHandles, line %q", v)
|
||||
}
|
||||
|
||||
return FileHandles{
|
||||
Stale: v[0],
|
||||
TotalLookups: v[1],
|
||||
AnonLookups: v[2],
|
||||
DirNoCache: v[3],
|
||||
NoDirNoCache: v[4],
|
||||
}, nil
|
||||
}
|
||||
|
||||
func parseInputOutput(v []uint64) (InputOutput, error) {
|
||||
if len(v) != 2 {
|
||||
return InputOutput{}, fmt.Errorf("invalid InputOutput line %q", v)
|
||||
}
|
||||
|
||||
return InputOutput{
|
||||
Read: v[0],
|
||||
Write: v[1],
|
||||
}, nil
|
||||
}
|
||||
|
||||
func parseThreads(v []uint64) (Threads, error) {
|
||||
if len(v) != 2 {
|
||||
return Threads{}, fmt.Errorf("invalid Threads line %q", v)
|
||||
}
|
||||
|
||||
return Threads{
|
||||
Threads: v[0],
|
||||
FullCnt: v[1],
|
||||
}, nil
|
||||
}
|
||||
|
||||
func parseReadAheadCache(v []uint64) (ReadAheadCache, error) {
|
||||
if len(v) != 12 {
|
||||
return ReadAheadCache{}, fmt.Errorf("invalid ReadAheadCache line %q", v)
|
||||
}
|
||||
|
||||
return ReadAheadCache{
|
||||
CacheSize: v[0],
|
||||
CacheHistogram: v[1:11],
|
||||
NotFound: v[11],
|
||||
}, nil
|
||||
}
|
||||
|
||||
func parseNetwork(v []uint64) (Network, error) {
|
||||
if len(v) != 4 {
|
||||
return Network{}, fmt.Errorf("invalid Network line %q", v)
|
||||
}
|
||||
|
||||
return Network{
|
||||
NetCount: v[0],
|
||||
UDPCount: v[1],
|
||||
TCPCount: v[2],
|
||||
TCPConnect: v[3],
|
||||
}, nil
|
||||
}
|
||||
|
||||
func parseServerRPC(v []uint64) (ServerRPC, error) {
|
||||
if len(v) != 5 {
|
||||
return ServerRPC{}, fmt.Errorf("invalid RPC line %q", v)
|
||||
}
|
||||
|
||||
return ServerRPC{
|
||||
RPCCount: v[0],
|
||||
BadCnt: v[1],
|
||||
BadFmt: v[2],
|
||||
BadAuth: v[3],
|
||||
BadcInt: v[4],
|
||||
}, nil
|
||||
}
|
||||
|
||||
func parseClientRPC(v []uint64) (ClientRPC, error) {
|
||||
if len(v) != 3 {
|
||||
return ClientRPC{}, fmt.Errorf("invalid RPC line %q", v)
|
||||
}
|
||||
|
||||
return ClientRPC{
|
||||
RPCCount: v[0],
|
||||
Retransmissions: v[1],
|
||||
AuthRefreshes: v[2],
|
||||
}, nil
|
||||
}
|
||||
|
||||
func parseV2Stats(v []uint64) (V2Stats, error) {
|
||||
values := int(v[0])
|
||||
if len(v[1:]) != values || values != 18 {
|
||||
return V2Stats{}, fmt.Errorf("invalid V2Stats line %q", v)
|
||||
}
|
||||
|
||||
return V2Stats{
|
||||
Null: v[1],
|
||||
GetAttr: v[2],
|
||||
SetAttr: v[3],
|
||||
Root: v[4],
|
||||
Lookup: v[5],
|
||||
ReadLink: v[6],
|
||||
Read: v[7],
|
||||
WrCache: v[8],
|
||||
Write: v[9],
|
||||
Create: v[10],
|
||||
Remove: v[11],
|
||||
Rename: v[12],
|
||||
Link: v[13],
|
||||
SymLink: v[14],
|
||||
MkDir: v[15],
|
||||
RmDir: v[16],
|
||||
ReadDir: v[17],
|
||||
FsStat: v[18],
|
||||
}, nil
|
||||
}
|
||||
|
||||
func parseV3Stats(v []uint64) (V3Stats, error) {
|
||||
values := int(v[0])
|
||||
if len(v[1:]) != values || values != 22 {
|
||||
return V3Stats{}, fmt.Errorf("invalid V3Stats line %q", v)
|
||||
}
|
||||
|
||||
return V3Stats{
|
||||
Null: v[1],
|
||||
GetAttr: v[2],
|
||||
SetAttr: v[3],
|
||||
Lookup: v[4],
|
||||
Access: v[5],
|
||||
ReadLink: v[6],
|
||||
Read: v[7],
|
||||
Write: v[8],
|
||||
Create: v[9],
|
||||
MkDir: v[10],
|
||||
SymLink: v[11],
|
||||
MkNod: v[12],
|
||||
Remove: v[13],
|
||||
RmDir: v[14],
|
||||
Rename: v[15],
|
||||
Link: v[16],
|
||||
ReadDir: v[17],
|
||||
ReadDirPlus: v[18],
|
||||
FsStat: v[19],
|
||||
FsInfo: v[20],
|
||||
PathConf: v[21],
|
||||
Commit: v[22],
|
||||
}, nil
|
||||
}
|
||||
|
||||
func parseClientV4Stats(v []uint64) (ClientV4Stats, error) {
|
||||
values := int(v[0])
|
||||
if len(v[1:]) != values || values < 59 {
|
||||
return ClientV4Stats{}, fmt.Errorf("invalid V4Stats line %q", v)
|
||||
}
|
||||
|
||||
return ClientV4Stats{
|
||||
Null: v[1],
|
||||
Read: v[2],
|
||||
Write: v[3],
|
||||
Commit: v[4],
|
||||
Open: v[5],
|
||||
OpenConfirm: v[6],
|
||||
OpenNoattr: v[7],
|
||||
OpenDowngrade: v[8],
|
||||
Close: v[9],
|
||||
Setattr: v[10],
|
||||
FsInfo: v[11],
|
||||
Renew: v[12],
|
||||
SetClientId: v[13],
|
||||
SetClientIdConfirm: v[14],
|
||||
Lock: v[15],
|
||||
Lockt: v[16],
|
||||
Locku: v[17],
|
||||
Access: v[18],
|
||||
Getattr: v[19],
|
||||
Lookup: v[20],
|
||||
LookupRoot: v[21],
|
||||
Remove: v[22],
|
||||
Rename: v[23],
|
||||
Link: v[24],
|
||||
Symlink: v[25],
|
||||
Create: v[26],
|
||||
Pathconf: v[27],
|
||||
StatFs: v[28],
|
||||
ReadLink: v[29],
|
||||
ReadDir: v[30],
|
||||
ServerCaps: v[31],
|
||||
DelegReturn: v[32],
|
||||
GetAcl: v[33],
|
||||
SetAcl: v[34],
|
||||
FsLocations: v[35],
|
||||
ReleaseLockowner: v[36],
|
||||
Secinfo: v[37],
|
||||
FsidPresent: v[38],
|
||||
ExchangeId: v[39],
|
||||
CreateSession: v[40],
|
||||
DestroySession: v[41],
|
||||
Sequence: v[42],
|
||||
GetLeaseTime: v[43],
|
||||
ReclaimComplete: v[44],
|
||||
LayoutGet: v[45],
|
||||
GetDeviceInfo: v[46],
|
||||
LayoutCommit: v[47],
|
||||
LayoutReturn: v[48],
|
||||
SecinfoNoName: v[49],
|
||||
TestStateId: v[50],
|
||||
FreeStateId: v[51],
|
||||
GetDeviceList: v[52],
|
||||
BindConnToSession: v[53],
|
||||
DestroyClientId: v[54],
|
||||
Seek: v[55],
|
||||
Allocate: v[56],
|
||||
DeAllocate: v[57],
|
||||
LayoutStats: v[58],
|
||||
Clone: v[59],
|
||||
}, nil
|
||||
}
|
||||
|
||||
func parseServerV4Stats(v []uint64) (ServerV4Stats, error) {
|
||||
values := int(v[0])
|
||||
if len(v[1:]) != values || values != 2 {
|
||||
return ServerV4Stats{}, fmt.Errorf("invalid V4Stats line %q", v)
|
||||
}
|
||||
|
||||
return ServerV4Stats{
|
||||
Null: v[1],
|
||||
Compound: v[2],
|
||||
}, nil
|
||||
}
|
||||
|
||||
func parseV4Ops(v []uint64) (V4Ops, error) {
|
||||
values := int(v[0])
|
||||
if len(v[1:]) != values || values < 39 {
|
||||
return V4Ops{}, fmt.Errorf("invalid V4Ops line %q", v)
|
||||
}
|
||||
|
||||
stats := V4Ops{
|
||||
Op0Unused: v[1],
|
||||
Op1Unused: v[2],
|
||||
Op2Future: v[3],
|
||||
Access: v[4],
|
||||
Close: v[5],
|
||||
Commit: v[6],
|
||||
Create: v[7],
|
||||
DelegPurge: v[8],
|
||||
DelegReturn: v[9],
|
||||
GetAttr: v[10],
|
||||
GetFH: v[11],
|
||||
Link: v[12],
|
||||
Lock: v[13],
|
||||
Lockt: v[14],
|
||||
Locku: v[15],
|
||||
Lookup: v[16],
|
||||
LookupRoot: v[17],
|
||||
Nverify: v[18],
|
||||
Open: v[19],
|
||||
OpenAttr: v[20],
|
||||
OpenConfirm: v[21],
|
||||
OpenDgrd: v[22],
|
||||
PutFH: v[23],
|
||||
PutPubFH: v[24],
|
||||
PutRootFH: v[25],
|
||||
Read: v[26],
|
||||
ReadDir: v[27],
|
||||
ReadLink: v[28],
|
||||
Remove: v[29],
|
||||
Rename: v[30],
|
||||
Renew: v[31],
|
||||
RestoreFH: v[32],
|
||||
SaveFH: v[33],
|
||||
SecInfo: v[34],
|
||||
SetAttr: v[35],
|
||||
Verify: v[36],
|
||||
Write: v[37],
|
||||
RelLockOwner: v[38],
|
||||
}
|
||||
|
||||
return stats, nil
|
||||
}
|
67
vendor/github.com/prometheus/procfs/nfs/parse_nfs.go
generated
vendored
67
vendor/github.com/prometheus/procfs/nfs/parse_nfs.go
generated
vendored
|
@ -1,67 +0,0 @@
|
|||
// Copyright 2018 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 nfs
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus/procfs/internal/util"
|
||||
)
|
||||
|
||||
// ParseClientRPCStats returns stats read from /proc/net/rpc/nfs
|
||||
func ParseClientRPCStats(r io.Reader) (*ClientRPCStats, error) {
|
||||
stats := &ClientRPCStats{}
|
||||
|
||||
scanner := bufio.NewScanner(r)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
parts := strings.Fields(scanner.Text())
|
||||
// require at least <key> <value>
|
||||
if len(parts) < 2 {
|
||||
return nil, fmt.Errorf("invalid NFSd metric line %q", line)
|
||||
}
|
||||
|
||||
values, err := util.ParseUint64s(parts[1:])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing NFSd metric line: %s", err)
|
||||
}
|
||||
|
||||
switch metricLine := parts[0]; metricLine {
|
||||
case "net":
|
||||
stats.Network, err = parseNetwork(values)
|
||||
case "rpc":
|
||||
stats.ClientRPC, err = parseClientRPC(values)
|
||||
case "proc2":
|
||||
stats.V2Stats, err = parseV2Stats(values)
|
||||
case "proc3":
|
||||
stats.V3Stats, err = parseV3Stats(values)
|
||||
case "proc4":
|
||||
stats.ClientV4Stats, err = parseClientV4Stats(values)
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown NFSd metric line %q", metricLine)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("errors parsing NFSd metric line: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return nil, fmt.Errorf("error scanning NFSd file: %s", err)
|
||||
}
|
||||
|
||||
return stats, nil
|
||||
}
|
89
vendor/github.com/prometheus/procfs/nfs/parse_nfsd.go
generated
vendored
89
vendor/github.com/prometheus/procfs/nfs/parse_nfsd.go
generated
vendored
|
@ -1,89 +0,0 @@
|
|||
// Copyright 2018 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 nfs
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus/procfs/internal/util"
|
||||
)
|
||||
|
||||
// ParseServerRPCStats returns stats read from /proc/net/rpc/nfsd
|
||||
func ParseServerRPCStats(r io.Reader) (*ServerRPCStats, error) {
|
||||
stats := &ServerRPCStats{}
|
||||
|
||||
scanner := bufio.NewScanner(r)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
parts := strings.Fields(scanner.Text())
|
||||
// require at least <key> <value>
|
||||
if len(parts) < 2 {
|
||||
return nil, fmt.Errorf("invalid NFSd metric line %q", line)
|
||||
}
|
||||
label := parts[0]
|
||||
|
||||
var values []uint64
|
||||
var err error
|
||||
if label == "th" {
|
||||
if len(parts) < 3 {
|
||||
return nil, fmt.Errorf("invalid NFSd th metric line %q", line)
|
||||
}
|
||||
values, err = util.ParseUint64s(parts[1:3])
|
||||
} else {
|
||||
values, err = util.ParseUint64s(parts[1:])
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing NFSd metric line: %s", err)
|
||||
}
|
||||
|
||||
switch metricLine := parts[0]; metricLine {
|
||||
case "rc":
|
||||
stats.ReplyCache, err = parseReplyCache(values)
|
||||
case "fh":
|
||||
stats.FileHandles, err = parseFileHandles(values)
|
||||
case "io":
|
||||
stats.InputOutput, err = parseInputOutput(values)
|
||||
case "th":
|
||||
stats.Threads, err = parseThreads(values)
|
||||
case "ra":
|
||||
stats.ReadAheadCache, err = parseReadAheadCache(values)
|
||||
case "net":
|
||||
stats.Network, err = parseNetwork(values)
|
||||
case "rpc":
|
||||
stats.ServerRPC, err = parseServerRPC(values)
|
||||
case "proc2":
|
||||
stats.V2Stats, err = parseV2Stats(values)
|
||||
case "proc3":
|
||||
stats.V3Stats, err = parseV3Stats(values)
|
||||
case "proc4":
|
||||
stats.ServerV4Stats, err = parseServerV4Stats(values)
|
||||
case "proc4ops":
|
||||
stats.V4Ops, err = parseV4Ops(values)
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown NFSd metric line %q", metricLine)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("errors parsing NFSd metric line: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return nil, fmt.Errorf("error scanning NFSd file: %s", err)
|
||||
}
|
||||
|
||||
return stats, nil
|
||||
}
|
77
vendor/github.com/prometheus/procfs/proc.go
generated
vendored
77
vendor/github.com/prometheus/procfs/proc.go
generated
vendored
|
@ -1,11 +1,27 @@
|
|||
// Copyright 2018 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 (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus/procfs/internal/fs"
|
||||
)
|
||||
|
||||
// Proc provides information about a running process.
|
||||
|
@ -13,7 +29,7 @@ type Proc struct {
|
|||
// The process ID.
|
||||
PID int
|
||||
|
||||
fs FS
|
||||
fs fs.FS
|
||||
}
|
||||
|
||||
// Procs represents a list of Proc structs.
|
||||
|
@ -38,7 +54,7 @@ func NewProc(pid int) (Proc, error) {
|
|||
if err != nil {
|
||||
return Proc{}, err
|
||||
}
|
||||
return fs.NewProc(pid)
|
||||
return fs.Proc(pid)
|
||||
}
|
||||
|
||||
// AllProcs returns a list of all currently available processes under /proc.
|
||||
|
@ -52,28 +68,35 @@ func AllProcs() (Procs, error) {
|
|||
|
||||
// Self returns a process for the current process.
|
||||
func (fs FS) Self() (Proc, error) {
|
||||
p, err := os.Readlink(fs.Path("self"))
|
||||
p, err := os.Readlink(fs.proc.Path("self"))
|
||||
if err != nil {
|
||||
return Proc{}, err
|
||||
}
|
||||
pid, err := strconv.Atoi(strings.Replace(p, string(fs), "", -1))
|
||||
pid, err := strconv.Atoi(strings.Replace(p, string(fs.proc), "", -1))
|
||||
if err != nil {
|
||||
return Proc{}, err
|
||||
}
|
||||
return fs.NewProc(pid)
|
||||
return fs.Proc(pid)
|
||||
}
|
||||
|
||||
// NewProc returns a process for the given pid.
|
||||
//
|
||||
// Deprecated: use fs.Proc() instead
|
||||
func (fs FS) NewProc(pid int) (Proc, error) {
|
||||
if _, err := os.Stat(fs.Path(strconv.Itoa(pid))); err != nil {
|
||||
return fs.Proc(pid)
|
||||
}
|
||||
|
||||
// Proc returns a process for the given pid.
|
||||
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}, nil
|
||||
return Proc{PID: pid, fs: fs.proc}, nil
|
||||
}
|
||||
|
||||
// AllProcs returns a list of all currently available processes.
|
||||
func (fs FS) AllProcs() (Procs, error) {
|
||||
d, err := os.Open(fs.Path())
|
||||
d, err := os.Open(fs.proc.Path())
|
||||
if err != nil {
|
||||
return Procs{}, err
|
||||
}
|
||||
|
@ -90,7 +113,7 @@ func (fs FS) AllProcs() (Procs, error) {
|
|||
if err != nil {
|
||||
continue
|
||||
}
|
||||
p = append(p, Proc{PID: int(pid), fs: fs})
|
||||
p = append(p, Proc{PID: int(pid), fs: fs.proc})
|
||||
}
|
||||
|
||||
return p, nil
|
||||
|
@ -113,7 +136,7 @@ func (p Proc) CmdLine() ([]string, error) {
|
|||
return []string{}, nil
|
||||
}
|
||||
|
||||
return strings.Split(string(data[:len(data)-1]), string(byte(0))), nil
|
||||
return strings.Split(string(bytes.TrimRight(data, string("\x00"))), string(byte(0))), nil
|
||||
}
|
||||
|
||||
// Comm returns the command name of a process.
|
||||
|
@ -142,6 +165,26 @@ func (p Proc) Executable() (string, error) {
|
|||
return exe, err
|
||||
}
|
||||
|
||||
// Cwd returns the absolute path to the current working directory of the process.
|
||||
func (p Proc) Cwd() (string, error) {
|
||||
wd, err := os.Readlink(p.path("cwd"))
|
||||
if os.IsNotExist(err) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return wd, err
|
||||
}
|
||||
|
||||
// RootDir returns the absolute path to the process's root directory (as set by chroot)
|
||||
func (p Proc) RootDir() (string, error) {
|
||||
rdir, err := os.Readlink(p.path("root"))
|
||||
if os.IsNotExist(err) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return rdir, err
|
||||
}
|
||||
|
||||
// FileDescriptors returns the currently open file descriptors of a process.
|
||||
func (p Proc) FileDescriptors() ([]uintptr, error) {
|
||||
names, err := p.fileDescriptors()
|
||||
|
@ -204,6 +247,20 @@ func (p Proc) MountStats() ([]*Mount, error) {
|
|||
return parseMountStats(f)
|
||||
}
|
||||
|
||||
// MountInfo retrieves mount information for mount points in a
|
||||
// process's namespace.
|
||||
// It supplies information missing in `/proc/self/mounts` and
|
||||
// fixes various other problems with that file too.
|
||||
func (p Proc) MountInfo() ([]*MountInfo, error) {
|
||||
f, err := os.Open(p.path("mountinfo"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
return parseMountInfo(f)
|
||||
}
|
||||
|
||||
func (p Proc) fileDescriptors() ([]string, error) {
|
||||
d, err := os.Open(p.path("fd"))
|
||||
if err != nil {
|
||||
|
|
43
vendor/github.com/prometheus/procfs/proc_environ.go
generated
vendored
Normal file
43
vendor/github.com/prometheus/procfs/proc_environ.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// Copyright 2019 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 (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Environ reads process environments from /proc/<pid>/environ
|
||||
func (p Proc) Environ() ([]string, error) {
|
||||
environments := make([]string, 0)
|
||||
|
||||
f, err := os.Open(p.path("environ"))
|
||||
if err != nil {
|
||||
return environments, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
data, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
return environments, err
|
||||
}
|
||||
|
||||
environments = strings.Split(string(data), "\000")
|
||||
if len(environments) > 0 {
|
||||
environments = environments[:len(environments)-1]
|
||||
}
|
||||
|
||||
return environments, nil
|
||||
}
|
17
vendor/github.com/prometheus/procfs/proc_io.go
generated
vendored
17
vendor/github.com/prometheus/procfs/proc_io.go
generated
vendored
|
@ -1,3 +1,16 @@
|
|||
// Copyright 2018 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 (
|
||||
|
@ -26,8 +39,8 @@ type ProcIO struct {
|
|||
CancelledWriteBytes int64
|
||||
}
|
||||
|
||||
// NewIO creates a new ProcIO instance from a given Proc instance.
|
||||
func (p Proc) NewIO() (ProcIO, error) {
|
||||
// IO creates a new ProcIO instance from a given Proc instance.
|
||||
func (p Proc) IO() (ProcIO, error) {
|
||||
pio := ProcIO{}
|
||||
|
||||
f, err := os.Open(p.path("io"))
|
||||
|
|
20
vendor/github.com/prometheus/procfs/proc_limits.go
generated
vendored
20
vendor/github.com/prometheus/procfs/proc_limits.go
generated
vendored
|
@ -1,3 +1,16 @@
|
|||
// Copyright 2018 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 (
|
||||
|
@ -65,7 +78,14 @@ var (
|
|||
)
|
||||
|
||||
// NewLimits returns the current soft limits of the process.
|
||||
//
|
||||
// Deprecated: use p.Limits() instead
|
||||
func (p Proc) NewLimits() (ProcLimits, error) {
|
||||
return p.Limits()
|
||||
}
|
||||
|
||||
// Limits returns the current soft limits of the process.
|
||||
func (p Proc) Limits() (ProcLimits, error) {
|
||||
f, err := os.Open(p.path("limits"))
|
||||
if err != nil {
|
||||
return ProcLimits{}, err
|
||||
|
|
17
vendor/github.com/prometheus/procfs/proc_ns.go
generated
vendored
17
vendor/github.com/prometheus/procfs/proc_ns.go
generated
vendored
|
@ -1,3 +1,16 @@
|
|||
// Copyright 2018 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 (
|
||||
|
@ -16,9 +29,9 @@ type Namespace struct {
|
|||
// Namespaces contains all of the namespaces that the process is contained in.
|
||||
type Namespaces map[string]Namespace
|
||||
|
||||
// NewNamespaces reads from /proc/[pid/ns/* to get the namespaces of which the
|
||||
// Namespaces reads from /proc/<pid>/ns/* to get the namespaces of which the
|
||||
// process is a member.
|
||||
func (p Proc) NewNamespaces() (Namespaces, error) {
|
||||
func (p Proc) Namespaces() (Namespaces, error) {
|
||||
d, err := os.Open(p.path("ns"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
101
vendor/github.com/prometheus/procfs/proc_psi.go
generated
vendored
Normal file
101
vendor/github.com/prometheus/procfs/proc_psi.go
generated
vendored
Normal file
|
@ -0,0 +1,101 @@
|
|||
// Copyright 2019 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
|
||||
|
||||
// The PSI / pressure interface is described at
|
||||
// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/accounting/psi.txt
|
||||
// Each resource (cpu, io, memory, ...) is exposed as a single file.
|
||||
// Each file may contain up to two lines, one for "some" pressure and one for "full" pressure.
|
||||
// Each line contains several averages (over n seconds) and a total in µs.
|
||||
//
|
||||
// Example io pressure file:
|
||||
// > some avg10=0.06 avg60=0.21 avg300=0.99 total=8537362
|
||||
// > full avg10=0.00 avg60=0.13 avg300=0.96 total=8183134
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const lineFormat = "avg10=%f avg60=%f avg300=%f total=%d"
|
||||
|
||||
// PSILine is a single line of values as returned by /proc/pressure/*
|
||||
// The Avg entries are averages over n seconds, as a percentage
|
||||
// The Total line is in microseconds
|
||||
type PSILine struct {
|
||||
Avg10 float64
|
||||
Avg60 float64
|
||||
Avg300 float64
|
||||
Total uint64
|
||||
}
|
||||
|
||||
// PSIStats represent pressure stall information from /proc/pressure/*
|
||||
// Some indicates the share of time in which at least some tasks are stalled
|
||||
// Full indicates the share of time in which all non-idle tasks are stalled simultaneously
|
||||
type PSIStats struct {
|
||||
Some *PSILine
|
||||
Full *PSILine
|
||||
}
|
||||
|
||||
// PSIStatsForResource reads pressure stall information for the specified
|
||||
// resource from /proc/pressure/<resource>. At time of writing this can be
|
||||
// either "cpu", "memory" or "io".
|
||||
func (fs FS) PSIStatsForResource(resource string) (PSIStats, error) {
|
||||
file, err := os.Open(fs.proc.Path(fmt.Sprintf("%s/%s", "pressure", resource)))
|
||||
if err != nil {
|
||||
return PSIStats{}, fmt.Errorf("psi_stats: unavailable for %s", resource)
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
return parsePSIStats(resource, file)
|
||||
}
|
||||
|
||||
// parsePSIStats parses the specified file for pressure stall information
|
||||
func parsePSIStats(resource string, file io.Reader) (PSIStats, error) {
|
||||
psiStats := PSIStats{}
|
||||
stats, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
return psiStats, fmt.Errorf("psi_stats: unable to read data for %s", resource)
|
||||
}
|
||||
|
||||
for _, l := range strings.Split(string(stats), "\n") {
|
||||
prefix := strings.Split(l, " ")[0]
|
||||
switch prefix {
|
||||
case "some":
|
||||
psi := PSILine{}
|
||||
_, err := fmt.Sscanf(l, fmt.Sprintf("some %s", lineFormat), &psi.Avg10, &psi.Avg60, &psi.Avg300, &psi.Total)
|
||||
if err != nil {
|
||||
return PSIStats{}, err
|
||||
}
|
||||
psiStats.Some = &psi
|
||||
case "full":
|
||||
psi := PSILine{}
|
||||
_, err := fmt.Sscanf(l, fmt.Sprintf("full %s", lineFormat), &psi.Avg10, &psi.Avg60, &psi.Avg300, &psi.Total)
|
||||
if err != nil {
|
||||
return PSIStats{}, err
|
||||
}
|
||||
psiStats.Full = &psi
|
||||
default:
|
||||
// If we encounter a line with an unknown prefix, ignore it and move on
|
||||
// Should new measurement types be added in the future we'll simply ignore them instead
|
||||
// of erroring on retrieval
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return psiStats, nil
|
||||
}
|
33
vendor/github.com/prometheus/procfs/proc_stat.go
generated
vendored
33
vendor/github.com/prometheus/procfs/proc_stat.go
generated
vendored
|
@ -1,3 +1,16 @@
|
|||
// Copyright 2018 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 (
|
||||
|
@ -5,6 +18,8 @@ import (
|
|||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/prometheus/procfs/internal/fs"
|
||||
)
|
||||
|
||||
// Originally, this USER_HZ value was dynamically retrieved via a sysconf call
|
||||
|
@ -82,15 +97,22 @@ type ProcStat struct {
|
|||
// in clock ticks.
|
||||
Starttime uint64
|
||||
// Virtual memory size in bytes.
|
||||
VSize int
|
||||
VSize uint
|
||||
// Resident set size in pages.
|
||||
RSS int
|
||||
|
||||
fs FS
|
||||
proc fs.FS
|
||||
}
|
||||
|
||||
// NewStat returns the current status information of the process.
|
||||
//
|
||||
// Deprecated: use p.Stat() instead
|
||||
func (p Proc) NewStat() (ProcStat, error) {
|
||||
return p.Stat()
|
||||
}
|
||||
|
||||
// Stat returns the current status information of the process.
|
||||
func (p Proc) Stat() (ProcStat, error) {
|
||||
f, err := os.Open(p.path("stat"))
|
||||
if err != nil {
|
||||
return ProcStat{}, err
|
||||
|
@ -105,7 +127,7 @@ func (p Proc) NewStat() (ProcStat, error) {
|
|||
var (
|
||||
ignore int
|
||||
|
||||
s = ProcStat{PID: p.PID, fs: p.fs}
|
||||
s = ProcStat{PID: p.PID, proc: p.fs}
|
||||
l = bytes.Index(data, []byte("("))
|
||||
r = bytes.LastIndex(data, []byte(")"))
|
||||
)
|
||||
|
@ -151,7 +173,7 @@ func (p Proc) NewStat() (ProcStat, error) {
|
|||
}
|
||||
|
||||
// VirtualMemory returns the virtual memory size in bytes.
|
||||
func (s ProcStat) VirtualMemory() int {
|
||||
func (s ProcStat) VirtualMemory() uint {
|
||||
return s.VSize
|
||||
}
|
||||
|
||||
|
@ -162,7 +184,8 @@ func (s ProcStat) ResidentMemory() int {
|
|||
|
||||
// StartTime returns the unix timestamp of the process in seconds.
|
||||
func (s ProcStat) StartTime() (float64, error) {
|
||||
stat, err := s.fs.NewStat()
|
||||
fs := FS{proc: s.proc}
|
||||
stat, err := fs.Stat()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
|
162
vendor/github.com/prometheus/procfs/proc_status.go
generated
vendored
Normal file
162
vendor/github.com/prometheus/procfs/proc_status.go
generated
vendored
Normal file
|
@ -0,0 +1,162 @@
|
|||
// Copyright 2018 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 (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ProcStat provides status information about the process,
|
||||
// read from /proc/[pid]/stat.
|
||||
type ProcStatus struct {
|
||||
// The process ID.
|
||||
PID int
|
||||
// The process name.
|
||||
Name string
|
||||
|
||||
// Peak virtual memory size.
|
||||
VmPeak uint64
|
||||
// Virtual memory size.
|
||||
VmSize uint64
|
||||
// Locked memory size.
|
||||
VmLck uint64
|
||||
// Pinned memory size.
|
||||
VmPin uint64
|
||||
// Peak resident set size.
|
||||
VmHWM uint64
|
||||
// Resident set size (sum of RssAnnon RssFile and RssShmem).
|
||||
VmRSS uint64
|
||||
// Size of resident anonymous memory.
|
||||
RssAnon uint64
|
||||
// Size of resident file mappings.
|
||||
RssFile uint64
|
||||
// Size of resident shared memory.
|
||||
RssShmem uint64
|
||||
// Size of data segments.
|
||||
VmData uint64
|
||||
// Size of stack segments.
|
||||
VmStk uint64
|
||||
// Size of text segments.
|
||||
VmExe uint64
|
||||
// Shared library code size.
|
||||
VmLib uint64
|
||||
// Page table entries size.
|
||||
VmPTE uint64
|
||||
// Size of second-level page tables.
|
||||
VmPMD uint64
|
||||
// Swapped-out virtual memory size by anonymous private.
|
||||
VmSwap uint64
|
||||
// Size of hugetlb memory portions
|
||||
HugetlbPages uint64
|
||||
|
||||
// Number of voluntary context switches.
|
||||
VoluntaryCtxtSwitches uint64
|
||||
// Number of involuntary context switches.
|
||||
NonVoluntaryCtxtSwitches uint64
|
||||
}
|
||||
|
||||
// NewStatus returns the current status information of the process.
|
||||
func (p Proc) NewStatus() (ProcStatus, error) {
|
||||
f, err := os.Open(p.path("status"))
|
||||
if err != nil {
|
||||
return ProcStatus{}, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
data, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
return ProcStatus{}, err
|
||||
}
|
||||
|
||||
s := ProcStatus{PID: p.PID}
|
||||
|
||||
lines := strings.Split(string(data), "\n")
|
||||
for _, line := range lines {
|
||||
if !bytes.Contains([]byte(line), []byte(":")) {
|
||||
continue
|
||||
}
|
||||
|
||||
kv := strings.SplitN(line, ":", 2)
|
||||
|
||||
// removes spaces
|
||||
k := string(strings.TrimSpace(kv[0]))
|
||||
v := string(strings.TrimSpace(kv[1]))
|
||||
// removes "kB"
|
||||
v = string(bytes.Trim([]byte(v), " kB"))
|
||||
|
||||
// value to int when possible
|
||||
// we can skip error check here, 'cause vKBytes is not used when value is a string
|
||||
vKBytes, _ := strconv.ParseUint(v, 10, 64)
|
||||
// convert kB to B
|
||||
vBytes := vKBytes * 1024
|
||||
|
||||
s.fillStatus(k, v, vKBytes, vBytes)
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (s *ProcStatus) fillStatus(k string, vString string, vUint uint64, vUintBytes uint64) {
|
||||
switch k {
|
||||
case "Name":
|
||||
s.Name = vString
|
||||
case "VmPeak":
|
||||
s.VmPeak = vUintBytes
|
||||
case "VmSize":
|
||||
s.VmSize = vUintBytes
|
||||
case "VmLck":
|
||||
s.VmLck = vUintBytes
|
||||
case "VmPin":
|
||||
s.VmPin = vUintBytes
|
||||
case "VmHWM":
|
||||
s.VmHWM = vUintBytes
|
||||
case "VmRSS":
|
||||
s.VmRSS = vUintBytes
|
||||
case "RssAnon":
|
||||
s.RssAnon = vUintBytes
|
||||
case "RssFile":
|
||||
s.RssFile = vUintBytes
|
||||
case "RssShmem":
|
||||
s.RssShmem = vUintBytes
|
||||
case "VmData":
|
||||
s.VmData = vUintBytes
|
||||
case "VmStk":
|
||||
s.VmStk = vUintBytes
|
||||
case "VmExe":
|
||||
s.VmExe = vUintBytes
|
||||
case "VmLib":
|
||||
s.VmLib = vUintBytes
|
||||
case "VmPTE":
|
||||
s.VmPTE = vUintBytes
|
||||
case "VmPMD":
|
||||
s.VmPMD = vUintBytes
|
||||
case "VmSwap":
|
||||
s.VmSwap = vUintBytes
|
||||
case "HugetlbPages":
|
||||
s.HugetlbPages = vUintBytes
|
||||
case "voluntary_ctxt_switches":
|
||||
s.VoluntaryCtxtSwitches = vUint
|
||||
case "nonvoluntary_ctxt_switches":
|
||||
s.NonVoluntaryCtxtSwitches = vUint
|
||||
}
|
||||
}
|
||||
|
||||
// TotalCtxtSwitches returns the total context switch.
|
||||
func (s ProcStatus) TotalCtxtSwitches() uint64 {
|
||||
return s.VoluntaryCtxtSwitches + s.NonVoluntaryCtxtSwitches
|
||||
}
|
53
vendor/github.com/prometheus/procfs/stat.go
generated
vendored
53
vendor/github.com/prometheus/procfs/stat.go
generated
vendored
|
@ -1,3 +1,16 @@
|
|||
// Copyright 2018 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 (
|
||||
|
@ -7,6 +20,8 @@ import (
|
|||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus/procfs/internal/fs"
|
||||
)
|
||||
|
||||
// CPUStat shows how much time the cpu spend in various stages.
|
||||
|
@ -65,16 +80,6 @@ type Stat struct {
|
|||
SoftIRQ SoftIRQStat
|
||||
}
|
||||
|
||||
// NewStat returns kernel/system statistics read from /proc/stat.
|
||||
func NewStat() (Stat, error) {
|
||||
fs, err := NewFS(DefaultMountPoint)
|
||||
if err != nil {
|
||||
return Stat{}, err
|
||||
}
|
||||
|
||||
return fs.NewStat()
|
||||
}
|
||||
|
||||
// Parse a cpu statistics line and returns the CPUStat struct plus the cpu id (or -1 for the overall sum).
|
||||
func parseCPUStat(line string) (CPUStat, int64, error) {
|
||||
cpuStat := CPUStat{}
|
||||
|
@ -136,11 +141,31 @@ func parseSoftIRQStat(line string) (SoftIRQStat, uint64, error) {
|
|||
return softIRQStat, total, nil
|
||||
}
|
||||
|
||||
// NewStat returns an information about current kernel/system statistics.
|
||||
func (fs FS) NewStat() (Stat, error) {
|
||||
// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt
|
||||
// NewStat returns information about current cpu/process statistics.
|
||||
// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt
|
||||
//
|
||||
// Deprecated: use fs.Stat() instead
|
||||
func NewStat() (Stat, error) {
|
||||
fs, err := NewFS(fs.DefaultProcMountPoint)
|
||||
if err != nil {
|
||||
return Stat{}, err
|
||||
}
|
||||
return fs.Stat()
|
||||
}
|
||||
|
||||
f, err := os.Open(fs.Path("stat"))
|
||||
// NewStat returns information about current cpu/process statistics.
|
||||
// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt
|
||||
//
|
||||
// Deprecated: use fs.Stat() instead
|
||||
func (fs FS) NewStat() (Stat, error) {
|
||||
return fs.Stat()
|
||||
}
|
||||
|
||||
// Stat returns information about current cpu/process statistics.
|
||||
// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt
|
||||
func (fs FS) Stat() (Stat, error) {
|
||||
|
||||
f, err := os.Open(fs.proc.Path("stat"))
|
||||
if err != nil {
|
||||
return Stat{}, err
|
||||
}
|
||||
|
|
163
vendor/github.com/prometheus/procfs/ttar
generated
vendored
163
vendor/github.com/prometheus/procfs/ttar
generated
vendored
|
@ -1,11 +1,26 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Purpose: plain text tar format
|
||||
# Limitations: - only suitable for text files, directories, and symlinks
|
||||
# - stores only filename, content, and mode
|
||||
# - not designed for untrusted input
|
||||
|
||||
#
|
||||
# Note: must work with bash version 3.2 (macOS)
|
||||
|
||||
# Copyright 2017 Roger Luethi
|
||||
#
|
||||
# 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.
|
||||
|
||||
set -o errexit -o nounset
|
||||
|
||||
# Sanitize environment (for instance, standard sorting of glob matches)
|
||||
|
@ -13,6 +28,55 @@ export LC_ALL=C
|
|||
|
||||
path=""
|
||||
CMD=""
|
||||
ARG_STRING="$*"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Not all sed implementations can work on null bytes. In order to make ttar
|
||||
# work out of the box on macOS, use Python as a stream editor.
|
||||
|
||||
USE_PYTHON=0
|
||||
|
||||
PYTHON_CREATE_FILTER=$(cat << 'PCF'
|
||||
#!/usr/bin/env python
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
for line in sys.stdin:
|
||||
line = re.sub(r'EOF', r'\EOF', line)
|
||||
line = re.sub(r'NULLBYTE', r'\NULLBYTE', line)
|
||||
line = re.sub('\x00', r'NULLBYTE', line)
|
||||
sys.stdout.write(line)
|
||||
PCF
|
||||
)
|
||||
|
||||
PYTHON_EXTRACT_FILTER=$(cat << 'PEF'
|
||||
#!/usr/bin/env python
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
for line in sys.stdin:
|
||||
line = re.sub(r'(?<!\\)NULLBYTE', '\x00', line)
|
||||
line = re.sub(r'\\NULLBYTE', 'NULLBYTE', line)
|
||||
line = re.sub(r'([^\\])EOF', r'\1', line)
|
||||
line = re.sub(r'\\EOF', 'EOF', line)
|
||||
sys.stdout.write(line)
|
||||
PEF
|
||||
)
|
||||
|
||||
function test_environment {
|
||||
if [[ "$(echo "a" | sed 's/a/\x0/' | wc -c)" -ne 2 ]]; then
|
||||
echo "WARNING sed unable to handle null bytes, using Python (slow)."
|
||||
if ! which python >/dev/null; then
|
||||
echo "ERROR Python not found. Aborting."
|
||||
exit 2
|
||||
fi
|
||||
USE_PYTHON=1
|
||||
fi
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
function usage {
|
||||
bname=$(basename "$0")
|
||||
|
@ -22,7 +86,10 @@ Usage: $bname [-C <DIR>] -c -f <ARCHIVE> <FILE...> (create archive)
|
|||
$bname [-C <DIR>] -x -f <ARCHIVE> (extract archive)
|
||||
|
||||
Options:
|
||||
-C <DIR> (change directory)
|
||||
-C <DIR> (change directory)
|
||||
-v (verbose)
|
||||
--recursive-unlink (recursively delete existing directory if path
|
||||
collides with file or directory to extract)
|
||||
|
||||
Example: Change to sysfs directory, create ttar file from fixtures directory
|
||||
$bname -C sysfs -c -f sysfs/fixtures.ttar fixtures/
|
||||
|
@ -45,7 +112,10 @@ function set_cmd {
|
|||
CMD=$1
|
||||
}
|
||||
|
||||
while getopts :cf:htxvC: opt; do
|
||||
unset VERBOSE
|
||||
unset RECURSIVE_UNLINK
|
||||
|
||||
while getopts :cf:-:htxvC: opt; do
|
||||
case $opt in
|
||||
c)
|
||||
set_cmd "create"
|
||||
|
@ -69,6 +139,18 @@ while getopts :cf:htxvC: opt; do
|
|||
C)
|
||||
CDIR=$OPTARG
|
||||
;;
|
||||
-)
|
||||
case $OPTARG in
|
||||
recursive-unlink)
|
||||
RECURSIVE_UNLINK="yes"
|
||||
;;
|
||||
*)
|
||||
echo -e "Error: invalid option -$OPTARG"
|
||||
echo
|
||||
usage 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
echo >&2 "ERROR: invalid option -$OPTARG"
|
||||
echo
|
||||
|
@ -142,14 +224,52 @@ function extract {
|
|||
fi
|
||||
while IFS= read -r line; do
|
||||
line_no=$(( line_no + 1 ))
|
||||
local eof_without_newline
|
||||
if [ "$size" -gt 0 ]; then
|
||||
echo "$line" >> "$path"
|
||||
if [[ "$line" =~ [^\\]EOF ]]; then
|
||||
# An EOF not preceded by a backslash indicates that the line
|
||||
# does not end with a newline
|
||||
eof_without_newline=1
|
||||
else
|
||||
eof_without_newline=0
|
||||
fi
|
||||
# Replace NULLBYTE with null byte if at beginning of line
|
||||
# Replace NULLBYTE with null byte unless preceded by backslash
|
||||
# Remove one backslash in front of NULLBYTE (if any)
|
||||
# Remove EOF unless preceded by backslash
|
||||
# Remove one backslash in front of EOF
|
||||
if [ $USE_PYTHON -eq 1 ]; then
|
||||
echo -n "$line" | python -c "$PYTHON_EXTRACT_FILTER" >> "$path"
|
||||
else
|
||||
# The repeated pattern makes up for sed's lack of negative
|
||||
# lookbehind assertions (for consecutive null bytes).
|
||||
echo -n "$line" | \
|
||||
sed -e 's/^NULLBYTE/\x0/g;
|
||||
s/\([^\\]\)NULLBYTE/\1\x0/g;
|
||||
s/\([^\\]\)NULLBYTE/\1\x0/g;
|
||||
s/\\NULLBYTE/NULLBYTE/g;
|
||||
s/\([^\\]\)EOF/\1/g;
|
||||
s/\\EOF/EOF/g;
|
||||
' >> "$path"
|
||||
fi
|
||||
if [[ "$eof_without_newline" -eq 0 ]]; then
|
||||
echo >> "$path"
|
||||
fi
|
||||
size=$(( size - 1 ))
|
||||
continue
|
||||
fi
|
||||
if [[ $line =~ ^Path:\ (.*)$ ]]; then
|
||||
path=${BASH_REMATCH[1]}
|
||||
if [ -e "$path" ] || [ -L "$path" ]; then
|
||||
if [ -L "$path" ]; then
|
||||
rm "$path"
|
||||
elif [ -d "$path" ]; then
|
||||
if [ "${RECURSIVE_UNLINK:-}" == "yes" ]; then
|
||||
rm -r "$path"
|
||||
else
|
||||
# Safe because symlinks to directories are dealt with above
|
||||
rmdir "$path"
|
||||
fi
|
||||
elif [ -e "$path" ]; then
|
||||
rm "$path"
|
||||
fi
|
||||
elif [[ $line =~ ^Lines:\ (.*)$ ]]; then
|
||||
|
@ -187,11 +307,14 @@ function get_mode {
|
|||
local mfile=$1
|
||||
if [ -z "${STAT_OPTION:-}" ]; then
|
||||
if stat -c '%a' "$mfile" >/dev/null 2>&1; then
|
||||
# GNU stat
|
||||
STAT_OPTION='-c'
|
||||
STAT_FORMAT='%a'
|
||||
else
|
||||
# BSD stat
|
||||
STAT_OPTION='-f'
|
||||
STAT_FORMAT='%A'
|
||||
# Octal output, user/group/other (omit file type, sticky bit)
|
||||
STAT_FORMAT='%OLp'
|
||||
fi
|
||||
fi
|
||||
stat "${STAT_OPTION}" "${STAT_FORMAT}" "$mfile"
|
||||
|
@ -200,6 +323,7 @@ function get_mode {
|
|||
function _create {
|
||||
shopt -s nullglob
|
||||
local mode
|
||||
local eof_without_newline
|
||||
while (( "$#" )); do
|
||||
file=$1
|
||||
if [ -L "$file" ]; then
|
||||
|
@ -223,8 +347,30 @@ function _create {
|
|||
elif [ -f "$file" ]; then
|
||||
echo "Path: $file"
|
||||
lines=$(wc -l "$file"|awk '{print $1}')
|
||||
eof_without_newline=0
|
||||
if [[ "$(wc -c "$file"|awk '{print $1}')" -gt 0 ]] && \
|
||||
[[ "$(tail -c 1 "$file" | wc -l)" -eq 0 ]]; then
|
||||
eof_without_newline=1
|
||||
lines=$((lines+1))
|
||||
fi
|
||||
echo "Lines: $lines"
|
||||
cat "$file"
|
||||
# Add backslash in front of EOF
|
||||
# Add backslash in front of NULLBYTE
|
||||
# Replace null byte with NULLBYTE
|
||||
if [ $USE_PYTHON -eq 1 ]; then
|
||||
< "$file" python -c "$PYTHON_CREATE_FILTER"
|
||||
else
|
||||
< "$file" \
|
||||
sed 's/EOF/\\EOF/g;
|
||||
s/NULLBYTE/\\NULLBYTE/g;
|
||||
s/\x0/NULLBYTE/g;
|
||||
'
|
||||
fi
|
||||
if [[ "$eof_without_newline" -eq 1 ]]; then
|
||||
# Finish line with EOF to indicate that the original line did
|
||||
# not end with a linefeed
|
||||
echo "EOF"
|
||||
fi
|
||||
mode=$(get_mode "$file")
|
||||
echo "Mode: $mode"
|
||||
vecho "$mode $file"
|
||||
|
@ -249,9 +395,12 @@ function create {
|
|||
rm "$ttar_file"
|
||||
fi
|
||||
exec > "$ttar_file"
|
||||
echo "# Archive created by ttar $ARG_STRING"
|
||||
_create "$@"
|
||||
}
|
||||
|
||||
test_environment
|
||||
|
||||
if [ -n "${CDIR:-}" ]; then
|
||||
if [[ "$ARCHIVE" != /* ]]; then
|
||||
# Relative path: preserve the archive's location before changing
|
||||
|
|
4
vendor/github.com/prometheus/procfs/xfrm.go
generated
vendored
4
vendor/github.com/prometheus/procfs/xfrm.go
generated
vendored
|
@ -97,7 +97,7 @@ func NewXfrmStat() (XfrmStat, error) {
|
|||
|
||||
// NewXfrmStat reads the xfrm_stat statistics from the 'proc' filesystem.
|
||||
func (fs FS) NewXfrmStat() (XfrmStat, error) {
|
||||
file, err := os.Open(fs.Path("net/xfrm_stat"))
|
||||
file, err := os.Open(fs.proc.Path("net/xfrm_stat"))
|
||||
if err != nil {
|
||||
return XfrmStat{}, err
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ func (fs FS) NewXfrmStat() (XfrmStat, error) {
|
|||
|
||||
if len(fields) != 2 {
|
||||
return XfrmStat{}, fmt.Errorf(
|
||||
"couldnt parse %s line %s", file.Name(), s.Text())
|
||||
"couldn't parse %s line %s", file.Name(), s.Text())
|
||||
}
|
||||
|
||||
name := fields[0]
|
||||
|
|
330
vendor/github.com/prometheus/procfs/xfs/parse.go
generated
vendored
330
vendor/github.com/prometheus/procfs/xfs/parse.go
generated
vendored
|
@ -1,330 +0,0 @@
|
|||
// Copyright 2017 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package xfs
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus/procfs/internal/util"
|
||||
)
|
||||
|
||||
// ParseStats parses a Stats from an input io.Reader, using the format
|
||||
// found in /proc/fs/xfs/stat.
|
||||
func ParseStats(r io.Reader) (*Stats, error) {
|
||||
const (
|
||||
// Fields parsed into stats structures.
|
||||
fieldExtentAlloc = "extent_alloc"
|
||||
fieldAbt = "abt"
|
||||
fieldBlkMap = "blk_map"
|
||||
fieldBmbt = "bmbt"
|
||||
fieldDir = "dir"
|
||||
fieldTrans = "trans"
|
||||
fieldIg = "ig"
|
||||
fieldLog = "log"
|
||||
fieldRw = "rw"
|
||||
fieldAttr = "attr"
|
||||
fieldIcluster = "icluster"
|
||||
fieldVnodes = "vnodes"
|
||||
fieldBuf = "buf"
|
||||
fieldXpc = "xpc"
|
||||
|
||||
// Unimplemented at this time due to lack of documentation.
|
||||
fieldPushAil = "push_ail"
|
||||
fieldXstrat = "xstrat"
|
||||
fieldAbtb2 = "abtb2"
|
||||
fieldAbtc2 = "abtc2"
|
||||
fieldBmbt2 = "bmbt2"
|
||||
fieldIbt2 = "ibt2"
|
||||
fieldFibt2 = "fibt2"
|
||||
fieldQm = "qm"
|
||||
fieldDebug = "debug"
|
||||
)
|
||||
|
||||
var xfss Stats
|
||||
|
||||
s := bufio.NewScanner(r)
|
||||
for s.Scan() {
|
||||
// Expect at least a string label and a single integer value, ex:
|
||||
// - abt 0
|
||||
// - rw 1 2
|
||||
ss := strings.Fields(string(s.Bytes()))
|
||||
if len(ss) < 2 {
|
||||
continue
|
||||
}
|
||||
label := ss[0]
|
||||
|
||||
// Extended precision counters are uint64 values.
|
||||
if label == fieldXpc {
|
||||
us, err := util.ParseUint64s(ss[1:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
xfss.ExtendedPrecision, err = extendedPrecisionStats(us)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// All other counters are uint32 values.
|
||||
us, err := util.ParseUint32s(ss[1:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch label {
|
||||
case fieldExtentAlloc:
|
||||
xfss.ExtentAllocation, err = extentAllocationStats(us)
|
||||
case fieldAbt:
|
||||
xfss.AllocationBTree, err = btreeStats(us)
|
||||
case fieldBlkMap:
|
||||
xfss.BlockMapping, err = blockMappingStats(us)
|
||||
case fieldBmbt:
|
||||
xfss.BlockMapBTree, err = btreeStats(us)
|
||||
case fieldDir:
|
||||
xfss.DirectoryOperation, err = directoryOperationStats(us)
|
||||
case fieldTrans:
|
||||
xfss.Transaction, err = transactionStats(us)
|
||||
case fieldIg:
|
||||
xfss.InodeOperation, err = inodeOperationStats(us)
|
||||
case fieldLog:
|
||||
xfss.LogOperation, err = logOperationStats(us)
|
||||
case fieldRw:
|
||||
xfss.ReadWrite, err = readWriteStats(us)
|
||||
case fieldAttr:
|
||||
xfss.AttributeOperation, err = attributeOperationStats(us)
|
||||
case fieldIcluster:
|
||||
xfss.InodeClustering, err = inodeClusteringStats(us)
|
||||
case fieldVnodes:
|
||||
xfss.Vnode, err = vnodeStats(us)
|
||||
case fieldBuf:
|
||||
xfss.Buffer, err = bufferStats(us)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &xfss, s.Err()
|
||||
}
|
||||
|
||||
// extentAllocationStats builds an ExtentAllocationStats from a slice of uint32s.
|
||||
func extentAllocationStats(us []uint32) (ExtentAllocationStats, error) {
|
||||
if l := len(us); l != 4 {
|
||||
return ExtentAllocationStats{}, fmt.Errorf("incorrect number of values for XFS extent allocation stats: %d", l)
|
||||
}
|
||||
|
||||
return ExtentAllocationStats{
|
||||
ExtentsAllocated: us[0],
|
||||
BlocksAllocated: us[1],
|
||||
ExtentsFreed: us[2],
|
||||
BlocksFreed: us[3],
|
||||
}, nil
|
||||
}
|
||||
|
||||
// btreeStats builds a BTreeStats from a slice of uint32s.
|
||||
func btreeStats(us []uint32) (BTreeStats, error) {
|
||||
if l := len(us); l != 4 {
|
||||
return BTreeStats{}, fmt.Errorf("incorrect number of values for XFS btree stats: %d", l)
|
||||
}
|
||||
|
||||
return BTreeStats{
|
||||
Lookups: us[0],
|
||||
Compares: us[1],
|
||||
RecordsInserted: us[2],
|
||||
RecordsDeleted: us[3],
|
||||
}, nil
|
||||
}
|
||||
|
||||
// BlockMappingStat builds a BlockMappingStats from a slice of uint32s.
|
||||
func blockMappingStats(us []uint32) (BlockMappingStats, error) {
|
||||
if l := len(us); l != 7 {
|
||||
return BlockMappingStats{}, fmt.Errorf("incorrect number of values for XFS block mapping stats: %d", l)
|
||||
}
|
||||
|
||||
return BlockMappingStats{
|
||||
Reads: us[0],
|
||||
Writes: us[1],
|
||||
Unmaps: us[2],
|
||||
ExtentListInsertions: us[3],
|
||||
ExtentListDeletions: us[4],
|
||||
ExtentListLookups: us[5],
|
||||
ExtentListCompares: us[6],
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DirectoryOperationStats builds a DirectoryOperationStats from a slice of uint32s.
|
||||
func directoryOperationStats(us []uint32) (DirectoryOperationStats, error) {
|
||||
if l := len(us); l != 4 {
|
||||
return DirectoryOperationStats{}, fmt.Errorf("incorrect number of values for XFS directory operation stats: %d", l)
|
||||
}
|
||||
|
||||
return DirectoryOperationStats{
|
||||
Lookups: us[0],
|
||||
Creates: us[1],
|
||||
Removes: us[2],
|
||||
Getdents: us[3],
|
||||
}, nil
|
||||
}
|
||||
|
||||
// TransactionStats builds a TransactionStats from a slice of uint32s.
|
||||
func transactionStats(us []uint32) (TransactionStats, error) {
|
||||
if l := len(us); l != 3 {
|
||||
return TransactionStats{}, fmt.Errorf("incorrect number of values for XFS transaction stats: %d", l)
|
||||
}
|
||||
|
||||
return TransactionStats{
|
||||
Sync: us[0],
|
||||
Async: us[1],
|
||||
Empty: us[2],
|
||||
}, nil
|
||||
}
|
||||
|
||||
// InodeOperationStats builds an InodeOperationStats from a slice of uint32s.
|
||||
func inodeOperationStats(us []uint32) (InodeOperationStats, error) {
|
||||
if l := len(us); l != 7 {
|
||||
return InodeOperationStats{}, fmt.Errorf("incorrect number of values for XFS inode operation stats: %d", l)
|
||||
}
|
||||
|
||||
return InodeOperationStats{
|
||||
Attempts: us[0],
|
||||
Found: us[1],
|
||||
Recycle: us[2],
|
||||
Missed: us[3],
|
||||
Duplicate: us[4],
|
||||
Reclaims: us[5],
|
||||
AttributeChange: us[6],
|
||||
}, nil
|
||||
}
|
||||
|
||||
// LogOperationStats builds a LogOperationStats from a slice of uint32s.
|
||||
func logOperationStats(us []uint32) (LogOperationStats, error) {
|
||||
if l := len(us); l != 5 {
|
||||
return LogOperationStats{}, fmt.Errorf("incorrect number of values for XFS log operation stats: %d", l)
|
||||
}
|
||||
|
||||
return LogOperationStats{
|
||||
Writes: us[0],
|
||||
Blocks: us[1],
|
||||
NoInternalBuffers: us[2],
|
||||
Force: us[3],
|
||||
ForceSleep: us[4],
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ReadWriteStats builds a ReadWriteStats from a slice of uint32s.
|
||||
func readWriteStats(us []uint32) (ReadWriteStats, error) {
|
||||
if l := len(us); l != 2 {
|
||||
return ReadWriteStats{}, fmt.Errorf("incorrect number of values for XFS read write stats: %d", l)
|
||||
}
|
||||
|
||||
return ReadWriteStats{
|
||||
Read: us[0],
|
||||
Write: us[1],
|
||||
}, nil
|
||||
}
|
||||
|
||||
// AttributeOperationStats builds an AttributeOperationStats from a slice of uint32s.
|
||||
func attributeOperationStats(us []uint32) (AttributeOperationStats, error) {
|
||||
if l := len(us); l != 4 {
|
||||
return AttributeOperationStats{}, fmt.Errorf("incorrect number of values for XFS attribute operation stats: %d", l)
|
||||
}
|
||||
|
||||
return AttributeOperationStats{
|
||||
Get: us[0],
|
||||
Set: us[1],
|
||||
Remove: us[2],
|
||||
List: us[3],
|
||||
}, nil
|
||||
}
|
||||
|
||||
// InodeClusteringStats builds an InodeClusteringStats from a slice of uint32s.
|
||||
func inodeClusteringStats(us []uint32) (InodeClusteringStats, error) {
|
||||
if l := len(us); l != 3 {
|
||||
return InodeClusteringStats{}, fmt.Errorf("incorrect number of values for XFS inode clustering stats: %d", l)
|
||||
}
|
||||
|
||||
return InodeClusteringStats{
|
||||
Iflush: us[0],
|
||||
Flush: us[1],
|
||||
FlushInode: us[2],
|
||||
}, nil
|
||||
}
|
||||
|
||||
// VnodeStats builds a VnodeStats from a slice of uint32s.
|
||||
func vnodeStats(us []uint32) (VnodeStats, error) {
|
||||
// The attribute "Free" appears to not be available on older XFS
|
||||
// stats versions. Therefore, 7 or 8 elements may appear in
|
||||
// this slice.
|
||||
l := len(us)
|
||||
if l != 7 && l != 8 {
|
||||
return VnodeStats{}, fmt.Errorf("incorrect number of values for XFS vnode stats: %d", l)
|
||||
}
|
||||
|
||||
s := VnodeStats{
|
||||
Active: us[0],
|
||||
Allocate: us[1],
|
||||
Get: us[2],
|
||||
Hold: us[3],
|
||||
Release: us[4],
|
||||
Reclaim: us[5],
|
||||
Remove: us[6],
|
||||
}
|
||||
|
||||
// Skip adding free, unless it is present. The zero value will
|
||||
// be used in place of an actual count.
|
||||
if l == 7 {
|
||||
return s, nil
|
||||
}
|
||||
|
||||
s.Free = us[7]
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// BufferStats builds a BufferStats from a slice of uint32s.
|
||||
func bufferStats(us []uint32) (BufferStats, error) {
|
||||
if l := len(us); l != 9 {
|
||||
return BufferStats{}, fmt.Errorf("incorrect number of values for XFS buffer stats: %d", l)
|
||||
}
|
||||
|
||||
return BufferStats{
|
||||
Get: us[0],
|
||||
Create: us[1],
|
||||
GetLocked: us[2],
|
||||
GetLockedWaited: us[3],
|
||||
BusyLocked: us[4],
|
||||
MissLocked: us[5],
|
||||
PageRetries: us[6],
|
||||
PageFound: us[7],
|
||||
GetRead: us[8],
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ExtendedPrecisionStats builds an ExtendedPrecisionStats from a slice of uint32s.
|
||||
func extendedPrecisionStats(us []uint64) (ExtendedPrecisionStats, error) {
|
||||
if l := len(us); l != 3 {
|
||||
return ExtendedPrecisionStats{}, fmt.Errorf("incorrect number of values for XFS extended precision stats: %d", l)
|
||||
}
|
||||
|
||||
return ExtendedPrecisionStats{
|
||||
FlushBytes: us[0],
|
||||
WriteBytes: us[1],
|
||||
ReadBytes: us[2],
|
||||
}, nil
|
||||
}
|
163
vendor/github.com/prometheus/procfs/xfs/xfs.go
generated
vendored
163
vendor/github.com/prometheus/procfs/xfs/xfs.go
generated
vendored
|
@ -1,163 +0,0 @@
|
|||
// Copyright 2017 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package xfs provides access to statistics exposed by the XFS filesystem.
|
||||
package xfs
|
||||
|
||||
// Stats contains XFS filesystem runtime statistics, parsed from
|
||||
// /proc/fs/xfs/stat.
|
||||
//
|
||||
// The names and meanings of each statistic were taken from
|
||||
// http://xfs.org/index.php/Runtime_Stats and xfs_stats.h in the Linux
|
||||
// kernel source. Most counters are uint32s (same data types used in
|
||||
// xfs_stats.h), but some of the "extended precision stats" are uint64s.
|
||||
type Stats struct {
|
||||
// The name of the filesystem used to source these statistics.
|
||||
// If empty, this indicates aggregated statistics for all XFS
|
||||
// filesystems on the host.
|
||||
Name string
|
||||
|
||||
ExtentAllocation ExtentAllocationStats
|
||||
AllocationBTree BTreeStats
|
||||
BlockMapping BlockMappingStats
|
||||
BlockMapBTree BTreeStats
|
||||
DirectoryOperation DirectoryOperationStats
|
||||
Transaction TransactionStats
|
||||
InodeOperation InodeOperationStats
|
||||
LogOperation LogOperationStats
|
||||
ReadWrite ReadWriteStats
|
||||
AttributeOperation AttributeOperationStats
|
||||
InodeClustering InodeClusteringStats
|
||||
Vnode VnodeStats
|
||||
Buffer BufferStats
|
||||
ExtendedPrecision ExtendedPrecisionStats
|
||||
}
|
||||
|
||||
// ExtentAllocationStats contains statistics regarding XFS extent allocations.
|
||||
type ExtentAllocationStats struct {
|
||||
ExtentsAllocated uint32
|
||||
BlocksAllocated uint32
|
||||
ExtentsFreed uint32
|
||||
BlocksFreed uint32
|
||||
}
|
||||
|
||||
// BTreeStats contains statistics regarding an XFS internal B-tree.
|
||||
type BTreeStats struct {
|
||||
Lookups uint32
|
||||
Compares uint32
|
||||
RecordsInserted uint32
|
||||
RecordsDeleted uint32
|
||||
}
|
||||
|
||||
// BlockMappingStats contains statistics regarding XFS block maps.
|
||||
type BlockMappingStats struct {
|
||||
Reads uint32
|
||||
Writes uint32
|
||||
Unmaps uint32
|
||||
ExtentListInsertions uint32
|
||||
ExtentListDeletions uint32
|
||||
ExtentListLookups uint32
|
||||
ExtentListCompares uint32
|
||||
}
|
||||
|
||||
// DirectoryOperationStats contains statistics regarding XFS directory entries.
|
||||
type DirectoryOperationStats struct {
|
||||
Lookups uint32
|
||||
Creates uint32
|
||||
Removes uint32
|
||||
Getdents uint32
|
||||
}
|
||||
|
||||
// TransactionStats contains statistics regarding XFS metadata transactions.
|
||||
type TransactionStats struct {
|
||||
Sync uint32
|
||||
Async uint32
|
||||
Empty uint32
|
||||
}
|
||||
|
||||
// InodeOperationStats contains statistics regarding XFS inode operations.
|
||||
type InodeOperationStats struct {
|
||||
Attempts uint32
|
||||
Found uint32
|
||||
Recycle uint32
|
||||
Missed uint32
|
||||
Duplicate uint32
|
||||
Reclaims uint32
|
||||
AttributeChange uint32
|
||||
}
|
||||
|
||||
// LogOperationStats contains statistics regarding the XFS log buffer.
|
||||
type LogOperationStats struct {
|
||||
Writes uint32
|
||||
Blocks uint32
|
||||
NoInternalBuffers uint32
|
||||
Force uint32
|
||||
ForceSleep uint32
|
||||
}
|
||||
|
||||
// ReadWriteStats contains statistics regarding the number of read and write
|
||||
// system calls for XFS filesystems.
|
||||
type ReadWriteStats struct {
|
||||
Read uint32
|
||||
Write uint32
|
||||
}
|
||||
|
||||
// AttributeOperationStats contains statistics regarding manipulation of
|
||||
// XFS extended file attributes.
|
||||
type AttributeOperationStats struct {
|
||||
Get uint32
|
||||
Set uint32
|
||||
Remove uint32
|
||||
List uint32
|
||||
}
|
||||
|
||||
// InodeClusteringStats contains statistics regarding XFS inode clustering
|
||||
// operations.
|
||||
type InodeClusteringStats struct {
|
||||
Iflush uint32
|
||||
Flush uint32
|
||||
FlushInode uint32
|
||||
}
|
||||
|
||||
// VnodeStats contains statistics regarding XFS vnode operations.
|
||||
type VnodeStats struct {
|
||||
Active uint32
|
||||
Allocate uint32
|
||||
Get uint32
|
||||
Hold uint32
|
||||
Release uint32
|
||||
Reclaim uint32
|
||||
Remove uint32
|
||||
Free uint32
|
||||
}
|
||||
|
||||
// BufferStats contains statistics regarding XFS read/write I/O buffers.
|
||||
type BufferStats struct {
|
||||
Get uint32
|
||||
Create uint32
|
||||
GetLocked uint32
|
||||
GetLockedWaited uint32
|
||||
BusyLocked uint32
|
||||
MissLocked uint32
|
||||
PageRetries uint32
|
||||
PageFound uint32
|
||||
GetRead uint32
|
||||
}
|
||||
|
||||
// ExtendedPrecisionStats contains high precision counters used to track the
|
||||
// total number of bytes read, written, or flushed, during XFS operations.
|
||||
type ExtendedPrecisionStats struct {
|
||||
FlushBytes uint64
|
||||
WriteBytes uint64
|
||||
ReadBytes uint64
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue