├── vendor └── github.com │ ├── prometheus │ ├── procfs │ │ ├── .gitignore │ │ ├── MAINTAINERS.md │ │ ├── .travis.yml │ │ ├── NOTICE │ │ ├── README.md │ │ ├── CONTRIBUTING.md │ │ ├── internal │ │ │ └── util │ │ │ │ └── parse.go │ │ ├── doc.go │ │ ├── proc_io.go │ │ ├── nfs │ │ │ ├── parse_nfs.go │ │ │ ├── parse_nfsd.go │ │ │ └── nfs.go │ │ ├── proc_ns.go │ │ ├── Makefile │ │ ├── fs.go │ │ ├── buddyinfo.go │ │ ├── mdstat.go │ │ ├── proc_limits.go │ │ ├── xfs │ │ │ └── xfs.go │ │ ├── xfrm.go │ │ ├── proc_stat.go │ │ ├── proc.go │ │ ├── net_dev.go │ │ └── ipvs.go │ ├── client_golang │ │ ├── prometheus │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── fnv.go │ │ │ ├── collector.go │ │ │ ├── expvar_collector.go │ │ │ ├── process_collector.go │ │ │ ├── untyped.go │ │ │ ├── gauge.go │ │ │ ├── counter.go │ │ │ ├── metric.go │ │ │ ├── promhttp │ │ │ │ └── http.go │ │ │ └── value.go │ │ ├── AUTHORS.md │ │ └── NOTICE │ ├── client_model │ │ └── NOTICE │ └── common │ │ ├── NOTICE │ │ ├── model │ │ ├── model.go │ │ ├── fnv.go │ │ ├── fingerprinting.go │ │ ├── silence.go │ │ ├── metric.go │ │ ├── alert.go │ │ ├── labelset.go │ │ ├── signature.go │ │ ├── labels.go │ │ └── time.go │ │ ├── expfmt │ │ ├── fuzz.go │ │ ├── expfmt.go │ │ └── encode.go │ │ └── internal │ │ └── bitbucket.org │ │ └── ww │ │ └── goautoneg │ │ ├── README.txt │ │ └── autoneg.go │ ├── matttproud │ └── golang_protobuf_extensions │ │ ├── NOTICE │ │ └── pbutil │ │ ├── doc.go │ │ ├── encode.go │ │ └── decode.go │ ├── mindprince │ └── gonvml │ │ ├── .travis.yml │ │ ├── .travis.gofmt.sh │ │ ├── README.md │ │ ├── Makefile │ │ └── NVML_NOTICE │ ├── golang │ └── protobuf │ │ ├── AUTHORS │ │ ├── CONTRIBUTORS │ │ ├── LICENSE │ │ └── proto │ │ └── encode.go │ └── beorn7 │ └── perks │ └── LICENSE ├── Gopkg.toml ├── Dockerfile ├── Makefile ├── Gopkg.lock ├── README.md └── main.go /vendor/github.com/prometheus/procfs/.gitignore: -------------------------------------------------------------------------------- 1 | /fixtures/ 2 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/MAINTAINERS.md: -------------------------------------------------------------------------------- 1 | * Tobias Schmidt 2 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_golang/prometheus/.gitignore: -------------------------------------------------------------------------------- 1 | command-line-arguments.test 2 | -------------------------------------------------------------------------------- /vendor/github.com/matttproud/golang_protobuf_extensions/NOTICE: -------------------------------------------------------------------------------- 1 | Copyright 2012 Matt T. Proud (matt.proud@gmail.com) 2 | -------------------------------------------------------------------------------- /vendor/github.com/mindprince/gonvml/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - "1.8" 5 | - "1.9" 6 | - "1.10" 7 | 8 | script: 9 | - make presubmit 10 | -------------------------------------------------------------------------------- /vendor/github.com/mindprince/gonvml/.travis.gofmt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -n "$(gofmt -s -l .)" ]; then 4 | echo "Go code is not properly formatted:" 5 | gofmt -s -d -e . 6 | exit 1 7 | fi 8 | -------------------------------------------------------------------------------- /vendor/github.com/golang/protobuf/AUTHORS: -------------------------------------------------------------------------------- 1 | # This source code refers to The Go Authors for copyright purposes. 2 | # The master list of authors is in the main Go distribution, 3 | # visible at http://tip.golang.org/AUTHORS. 4 | -------------------------------------------------------------------------------- /vendor/github.com/golang/protobuf/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This source code was written by the Go contributors. 2 | # The master list of contributors is in the main Go distribution, 3 | # visible at http://tip.golang.org/CONTRIBUTORS. 4 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_golang/prometheus/README.md: -------------------------------------------------------------------------------- 1 | See [![go-doc](https://godoc.org/github.com/prometheus/client_golang/prometheus?status.svg)](https://godoc.org/github.com/prometheus/client_golang/prometheus). 2 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_model/NOTICE: -------------------------------------------------------------------------------- 1 | Data model artifacts for Prometheus. 2 | Copyright 2012-2015 The Prometheus Authors 3 | 4 | This product includes software developed at 5 | SoundCloud Ltd. (http://soundcloud.com/). 6 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/NOTICE: -------------------------------------------------------------------------------- 1 | Common libraries shared by Prometheus Go components. 2 | Copyright 2015 The Prometheus Authors 3 | 4 | This product includes software developed at 5 | SoundCloud Ltd. (http://soundcloud.com/). 6 | -------------------------------------------------------------------------------- /Gopkg.toml: -------------------------------------------------------------------------------- 1 | [[constraint]] 2 | branch = "master" 3 | name = "github.com/mindprince/gonvml" 4 | 5 | [[constraint]] 6 | name = "github.com/prometheus/client_golang" 7 | version = "0.8.0" 8 | 9 | [prune] 10 | go-tests = true 11 | unused-packages = true 12 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang as build 2 | RUN go get github.com/mindprince/nvidia_gpu_prometheus_exporter 3 | 4 | FROM ubuntu:18.04 5 | COPY --from=build /go/bin/nvidia_gpu_prometheus_exporter / 6 | CMD /nvidia_gpu_prometheus_exporter 7 | ENV NVIDIA_VISIBLE_DEVICES=all 8 | EXPOSE 9445 9 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | 3 | language: go 4 | 5 | go: 6 | - 1.7.x 7 | - 1.8.x 8 | - 1.9.x 9 | - 1.10.x 10 | - 1.x 11 | 12 | go_import_path: github.com/prometheus/procfs 13 | 14 | script: 15 | - make style check_license vet test staticcheck 16 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/NOTICE: -------------------------------------------------------------------------------- 1 | procfs provides functions to retrieve system, kernel and process 2 | metrics from the pseudo-filesystem proc. 3 | 4 | Copyright 2014-2015 The Prometheus Authors 5 | 6 | This product includes software developed at 7 | SoundCloud Ltd. (http://soundcloud.com/). 8 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PKG=github.com/mindprince/nvidia_gpu_prometheus_exporter 2 | REGISTRY=mindprince 3 | IMAGE=nvidia_gpu_prometheus_exporter 4 | TAG=0.1 5 | 6 | .PHONY: build 7 | build: 8 | docker run -v $(shell pwd):/go/src/$(PKG) --workdir=/go/src/$(PKG) golang:1.10 go build 9 | 10 | .PHONY: container 11 | container: 12 | docker build --pull -t ${REGISTRY}/${IMAGE}:${TAG} . 13 | 14 | .PHONY: push 15 | push: 16 | docker push ${REGISTRY}/${IMAGE}:${TAG} 17 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_golang/AUTHORS.md: -------------------------------------------------------------------------------- 1 | The Prometheus project was started by Matt T. Proud (emeritus) and 2 | Julius Volz in 2012. 3 | 4 | Maintainers of this repository: 5 | 6 | * Björn Rabenstein 7 | 8 | The following individuals have contributed code to this repository 9 | (listed in alphabetical order): 10 | 11 | * Bernerd Schaefer 12 | * Björn Rabenstein 13 | * Daniel Bornkessel 14 | * Jeff Younker 15 | * Julius Volz 16 | * Matt T. Proud 17 | * Tobias Schmidt 18 | 19 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/README.md: -------------------------------------------------------------------------------- 1 | # procfs 2 | 3 | This procfs package provides functions to retrieve system, kernel and process 4 | metrics from the pseudo-filesystem proc. 5 | 6 | *WARNING*: This package is a work in progress. Its API may still break in 7 | backwards-incompatible ways without warnings. Use it at your own risk. 8 | 9 | [![GoDoc](https://godoc.org/github.com/prometheus/procfs?status.png)](https://godoc.org/github.com/prometheus/procfs) 10 | [![Build Status](https://travis-ci.org/prometheus/procfs.svg?branch=master)](https://travis-ci.org/prometheus/procfs) 11 | [![Go Report Card](https://goreportcard.com/badge/github.com/prometheus/procfs)](https://goreportcard.com/report/github.com/prometheus/procfs) 12 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_golang/prometheus/fnv.go: -------------------------------------------------------------------------------- 1 | package prometheus 2 | 3 | // Inline and byte-free variant of hash/fnv's fnv64a. 4 | 5 | const ( 6 | offset64 = 14695981039346656037 7 | prime64 = 1099511628211 8 | ) 9 | 10 | // hashNew initializies a new fnv64a hash value. 11 | func hashNew() uint64 { 12 | return offset64 13 | } 14 | 15 | // hashAdd adds a string to a fnv64a hash value, returning the updated hash. 16 | func hashAdd(h uint64, s string) uint64 { 17 | for i := 0; i < len(s); i++ { 18 | h ^= uint64(s[i]) 19 | h *= prime64 20 | } 21 | return h 22 | } 23 | 24 | // hashAddByte adds a byte to a fnv64a hash value, returning the updated hash. 25 | func hashAddByte(h uint64, b byte) uint64 { 26 | h ^= uint64(b) 27 | h *= prime64 28 | return h 29 | } 30 | -------------------------------------------------------------------------------- /vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Matt T. Proud 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package pbutil provides record length-delimited Protocol Buffer streaming. 16 | package pbutil 17 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/model/model.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // Package model contains common data structures that are shared across 15 | // Prometheus components and libraries. 16 | package model 17 | -------------------------------------------------------------------------------- /vendor/github.com/mindprince/gonvml/README.md: -------------------------------------------------------------------------------- 1 | Go Bindings for NVML 2 | -------------------- 3 | 4 | [NVML or NVIDIA Management 5 | Library](https://developer.nvidia.com/nvidia-management-library-nvml) is a 6 | C-based API that can be used for monitoring NVIDIA GPU devices. It's closed 7 | source but can be downloaded as part of the [GPU Deployment 8 | Kit](https://developer.nvidia.com/gpu-deployment-kit). 9 | 10 | The [NVML API 11 | Reference](http://docs.nvidia.com/deploy/nvml-api/nvml-api-reference.html) 12 | describe various methods that are available as part of NVML. 13 | 14 | The `nvml.h` file is included in this repository so that we don't depend on 15 | the presence of NVML in the build environment. 16 | 17 | The `bindings.go` file is the cgo bridge which calls the NVML functions. The 18 | cgo preamble in `bindings.go` uses `dlopen` to dynamically load NVML and makes 19 | its functions available. 20 | -------------------------------------------------------------------------------- /vendor/github.com/mindprince/gonvml/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | PKG=github.com/mindprince/gonvml 16 | 17 | .PHONY: build 18 | build: 19 | docker run -v $(shell pwd):/go/src/$(PKG) --workdir=/go/src/$(PKG) golang:1.8 go build cmd/example/example.go 20 | 21 | .PHONY: presubmit 22 | presubmit: 23 | ./.travis.gofmt.sh 24 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_golang/NOTICE: -------------------------------------------------------------------------------- 1 | Prometheus instrumentation library for Go applications 2 | Copyright 2012-2015 The Prometheus Authors 3 | 4 | This product includes software developed at 5 | SoundCloud Ltd. (http://soundcloud.com/). 6 | 7 | 8 | The following components are included in this product: 9 | 10 | perks - a fork of https://github.com/bmizerany/perks 11 | https://github.com/beorn7/perks 12 | Copyright 2013-2015 Blake Mizerany, Björn Rabenstein 13 | See https://github.com/beorn7/perks/blob/master/README.md for license details. 14 | 15 | Go support for Protocol Buffers - Google's data interchange format 16 | http://github.com/golang/protobuf/ 17 | Copyright 2010 The Go Authors 18 | See source code for license details. 19 | 20 | Support for streaming Protocol Buffer messages for the Go language (golang). 21 | https://github.com/matttproud/golang_protobuf_extensions 22 | Copyright 2013 Matt T. Proud 23 | Licensed under the Apache License, Version 2.0 24 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Prometheus uses GitHub to manage reviews of pull requests. 4 | 5 | * If you have a trivial fix or improvement, go ahead and create a pull request, 6 | addressing (with `@...`) the maintainer of this repository (see 7 | [MAINTAINERS.md](MAINTAINERS.md)) in the description of the pull request. 8 | 9 | * If you plan to do something more involved, first discuss your ideas 10 | on our [mailing list](https://groups.google.com/forum/?fromgroups#!forum/prometheus-developers). 11 | This will avoid unnecessary work and surely give you and us a good deal 12 | of inspiration. 13 | 14 | * Relevant coding style guidelines are the [Go Code Review 15 | Comments](https://code.google.com/p/go-wiki/wiki/CodeReviewComments) 16 | and the _Formatting and style_ section of Peter Bourgon's [Go: Best 17 | Practices for Production 18 | Environments](http://peter.bourgon.org/go-in-production/#formatting-and-style). 19 | -------------------------------------------------------------------------------- /vendor/github.com/beorn7/perks/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2013 Blake Mizerany 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/fuzz.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // Build only when actually fuzzing 15 | // +build gofuzz 16 | 17 | package expfmt 18 | 19 | import "bytes" 20 | 21 | // Fuzz text metric parser with with github.com/dvyukov/go-fuzz: 22 | // 23 | // go-fuzz-build github.com/prometheus/common/expfmt 24 | // go-fuzz -bin expfmt-fuzz.zip -workdir fuzz 25 | // 26 | // Further input samples should go in the folder fuzz/corpus. 27 | func Fuzz(in []byte) int { 28 | parser := TextParser{} 29 | _, err := parser.TextToMetricFamilies(bytes.NewReader(in)) 30 | 31 | if err != nil { 32 | return 0 33 | } 34 | 35 | return 1 36 | } 37 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/model/fnv.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package model 15 | 16 | // Inline and byte-free variant of hash/fnv's fnv64a. 17 | 18 | const ( 19 | offset64 = 14695981039346656037 20 | prime64 = 1099511628211 21 | ) 22 | 23 | // hashNew initializies a new fnv64a hash value. 24 | func hashNew() uint64 { 25 | return offset64 26 | } 27 | 28 | // hashAdd adds a string to a fnv64a hash value, returning the updated hash. 29 | func hashAdd(h uint64, s string) uint64 { 30 | for i := 0; i < len(s); i++ { 31 | h ^= uint64(s[i]) 32 | h *= prime64 33 | } 34 | return h 35 | } 36 | 37 | // hashAddByte adds a byte to a fnv64a hash value, returning the updated hash. 38 | func hashAddByte(h uint64, b byte) uint64 { 39 | h ^= uint64(b) 40 | h *= prime64 41 | return h 42 | } 43 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/internal/util/parse.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package util 15 | 16 | import "strconv" 17 | 18 | // ParseUint32s parses a slice of strings into a slice of uint32s. 19 | func ParseUint32s(ss []string) ([]uint32, error) { 20 | us := make([]uint32, 0, len(ss)) 21 | for _, s := range ss { 22 | u, err := strconv.ParseUint(s, 10, 32) 23 | if err != nil { 24 | return nil, err 25 | } 26 | 27 | us = append(us, uint32(u)) 28 | } 29 | 30 | return us, nil 31 | } 32 | 33 | // ParseUint64s parses a slice of strings into a slice of uint64s. 34 | func ParseUint64s(ss []string) ([]uint64, error) { 35 | us := make([]uint64, 0, len(ss)) 36 | for _, s := range ss { 37 | u, err := strconv.ParseUint(s, 10, 64) 38 | if err != nil { 39 | return nil, err 40 | } 41 | 42 | us = append(us, u) 43 | } 44 | 45 | return us, nil 46 | } 47 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Prometheus Team 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // Package procfs provides functions to retrieve system, kernel and process 15 | // metrics from the pseudo-filesystem proc. 16 | // 17 | // Example: 18 | // 19 | // package main 20 | // 21 | // import ( 22 | // "fmt" 23 | // "log" 24 | // 25 | // "github.com/prometheus/procfs" 26 | // ) 27 | // 28 | // func main() { 29 | // p, err := procfs.Self() 30 | // if err != nil { 31 | // log.Fatalf("could not get process: %s", err) 32 | // } 33 | // 34 | // stat, err := p.NewStat() 35 | // if err != nil { 36 | // log.Fatalf("could not get process stat: %s", err) 37 | // } 38 | // 39 | // fmt.Printf("command: %s\n", stat.Comm) 40 | // fmt.Printf("cpu time: %fs\n", stat.CPUTime()) 41 | // fmt.Printf("vsize: %dB\n", stat.VirtualMemory()) 42 | // fmt.Printf("rss: %dB\n", stat.ResidentMemory()) 43 | // } 44 | // 45 | package procfs 46 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/expfmt.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // Package expfmt contains tools for reading and writing Prometheus metrics. 15 | package expfmt 16 | 17 | // Format specifies the HTTP content type of the different wire protocols. 18 | type Format string 19 | 20 | // Constants to assemble the Content-Type values for the different wire protocols. 21 | const ( 22 | TextVersion = "0.0.4" 23 | ProtoType = `application/vnd.google.protobuf` 24 | ProtoProtocol = `io.prometheus.client.MetricFamily` 25 | ProtoFmt = ProtoType + "; proto=" + ProtoProtocol + ";" 26 | 27 | // The Content-Type values for the different wire protocols. 28 | FmtUnknown Format = `` 29 | FmtText Format = `text/plain; version=` + TextVersion + `; charset=utf-8` 30 | FmtProtoDelim Format = ProtoFmt + ` encoding=delimited` 31 | FmtProtoText Format = ProtoFmt + ` encoding=text` 32 | FmtProtoCompact Format = ProtoFmt + ` encoding=compact-text` 33 | ) 34 | 35 | const ( 36 | hdrContentType = "Content-Type" 37 | hdrAccept = "Accept" 38 | ) 39 | -------------------------------------------------------------------------------- /vendor/github.com/golang/protobuf/LICENSE: -------------------------------------------------------------------------------- 1 | Go support for Protocol Buffers - Google's data interchange format 2 | 3 | Copyright 2010 The Go Authors. All rights reserved. 4 | https://github.com/golang/protobuf 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are 8 | met: 9 | 10 | * Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above 13 | copyright notice, this list of conditions and the following disclaimer 14 | in the documentation and/or other materials provided with the 15 | distribution. 16 | * Neither the name of Google Inc. nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | -------------------------------------------------------------------------------- /vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/encode.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Matt T. Proud 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package pbutil 16 | 17 | import ( 18 | "encoding/binary" 19 | "io" 20 | 21 | "github.com/golang/protobuf/proto" 22 | ) 23 | 24 | // WriteDelimited encodes and dumps a message to the provided writer prefixed 25 | // with a 32-bit varint indicating the length of the encoded message, producing 26 | // a length-delimited record stream, which can be used to chain together 27 | // encoded messages of the same type together in a file. It returns the total 28 | // number of bytes written and any applicable error. This is roughly 29 | // equivalent to the companion Java API's MessageLite#writeDelimitedTo. 30 | func WriteDelimited(w io.Writer, m proto.Message) (n int, err error) { 31 | buffer, err := proto.Marshal(m) 32 | if err != nil { 33 | return 0, err 34 | } 35 | 36 | var buf [binary.MaxVarintLen32]byte 37 | encodedLength := binary.PutUvarint(buf[:], uint64(len(buffer))) 38 | 39 | sync, err := w.Write(buf[:encodedLength]) 40 | if err != nil { 41 | return sync, err 42 | } 43 | 44 | n, err = w.Write(buffer) 45 | return n + sync, err 46 | } 47 | -------------------------------------------------------------------------------- /vendor/github.com/mindprince/gonvml/NVML_NOTICE: -------------------------------------------------------------------------------- 1 | Copyright 1993-2016 NVIDIA Corporation. All rights reserved. 2 | 3 | NOTICE TO USER: 4 | 5 | This source code is subject to NVIDIA ownership rights under U.S. and 6 | international Copyright laws. Users and possessors of this source code 7 | are hereby granted a nonexclusive, royalty-free license to use this code 8 | in individual and commercial software. 9 | 10 | NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE 11 | CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR 12 | IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH 13 | REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF 14 | MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE. 15 | IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL, 16 | OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 17 | OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 18 | OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE 19 | OR PERFORMANCE OF THIS SOURCE CODE. 20 | 21 | U.S. Government End Users. This source code is a "commercial item" as 22 | that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of 23 | "commercial computer software" and "commercial computer software 24 | documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995) 25 | and is provided to the U.S. Government only as a commercial end item. 26 | Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through 27 | 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the 28 | source code with only those rights set forth herein. 29 | 30 | Any use of this source code in individual and commercial software must 31 | include, in the user documentation and internal comments to the code, 32 | the above Disclaimer and U.S. Government End Users Notice. 33 | -------------------------------------------------------------------------------- /Gopkg.lock: -------------------------------------------------------------------------------- 1 | # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. 2 | 3 | 4 | [[projects]] 5 | branch = "master" 6 | name = "github.com/beorn7/perks" 7 | packages = ["quantile"] 8 | revision = "3a771d992973f24aa725d07868b467d1ddfceafb" 9 | 10 | [[projects]] 11 | name = "github.com/golang/protobuf" 12 | packages = ["proto"] 13 | revision = "b4deda0973fb4c70b50d226b1af49f3da59f5265" 14 | version = "v1.1.0" 15 | 16 | [[projects]] 17 | name = "github.com/matttproud/golang_protobuf_extensions" 18 | packages = ["pbutil"] 19 | revision = "3247c84500bff8d9fb6d579d800f20b3e091582c" 20 | version = "v1.0.0" 21 | 22 | [[projects]] 23 | branch = "master" 24 | name = "github.com/mindprince/gonvml" 25 | packages = ["."] 26 | revision = "b364b296c7320f5d3dc084aa536a3dba33b68f90" 27 | 28 | [[projects]] 29 | name = "github.com/prometheus/client_golang" 30 | packages = [ 31 | "prometheus", 32 | "prometheus/promhttp" 33 | ] 34 | revision = "c5b7fccd204277076155f10851dad72b76a49317" 35 | version = "v0.8.0" 36 | 37 | [[projects]] 38 | branch = "master" 39 | name = "github.com/prometheus/client_model" 40 | packages = ["go"] 41 | revision = "99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c" 42 | 43 | [[projects]] 44 | branch = "master" 45 | name = "github.com/prometheus/common" 46 | packages = [ 47 | "expfmt", 48 | "internal/bitbucket.org/ww/goautoneg", 49 | "model" 50 | ] 51 | revision = "7600349dcfe1abd18d72d3a1770870d9800a7801" 52 | 53 | [[projects]] 54 | branch = "master" 55 | name = "github.com/prometheus/procfs" 56 | packages = [ 57 | ".", 58 | "internal/util", 59 | "nfs", 60 | "xfs" 61 | ] 62 | revision = "8b1c2da0d56deffdbb9e48d4414b4e674bd8083e" 63 | 64 | [solve-meta] 65 | analyzer-name = "dep" 66 | analyzer-version = 1 67 | inputs-digest = "4164880afee0355bcb5dede946a616103b8849312a49d902665bba0826827fbb" 68 | solver-name = "gps-cdcl" 69 | solver-version = 1 70 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/proc_io.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package procfs 15 | 16 | import ( 17 | "fmt" 18 | "io/ioutil" 19 | "os" 20 | ) 21 | 22 | // ProcIO models the content of /proc//io. 23 | type ProcIO struct { 24 | // Chars read. 25 | RChar uint64 26 | // Chars written. 27 | WChar uint64 28 | // Read syscalls. 29 | SyscR uint64 30 | // Write syscalls. 31 | SyscW uint64 32 | // Bytes read. 33 | ReadBytes uint64 34 | // Bytes written. 35 | WriteBytes uint64 36 | // Bytes written, but taking into account truncation. See 37 | // Documentation/filesystems/proc.txt in the kernel sources for 38 | // detailed explanation. 39 | CancelledWriteBytes int64 40 | } 41 | 42 | // NewIO creates a new ProcIO instance from a given Proc instance. 43 | func (p Proc) NewIO() (ProcIO, error) { 44 | pio := ProcIO{} 45 | 46 | f, err := os.Open(p.path("io")) 47 | if err != nil { 48 | return pio, err 49 | } 50 | defer f.Close() 51 | 52 | data, err := ioutil.ReadAll(f) 53 | if err != nil { 54 | return pio, err 55 | } 56 | 57 | ioFormat := "rchar: %d\nwchar: %d\nsyscr: %d\nsyscw: %d\n" + 58 | "read_bytes: %d\nwrite_bytes: %d\n" + 59 | "cancelled_write_bytes: %d\n" 60 | 61 | _, err = fmt.Sscanf(string(data), ioFormat, &pio.RChar, &pio.WChar, &pio.SyscR, 62 | &pio.SyscW, &pio.ReadBytes, &pio.WriteBytes, &pio.CancelledWriteBytes) 63 | 64 | return pio, err 65 | } 66 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/nfs/parse_nfs.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package nfs 15 | 16 | import ( 17 | "bufio" 18 | "fmt" 19 | "io" 20 | "strings" 21 | 22 | "github.com/prometheus/procfs/internal/util" 23 | ) 24 | 25 | // ParseClientRPCStats returns stats read from /proc/net/rpc/nfs 26 | func ParseClientRPCStats(r io.Reader) (*ClientRPCStats, error) { 27 | stats := &ClientRPCStats{} 28 | 29 | scanner := bufio.NewScanner(r) 30 | for scanner.Scan() { 31 | line := scanner.Text() 32 | parts := strings.Fields(scanner.Text()) 33 | // require at least 34 | if len(parts) < 2 { 35 | return nil, fmt.Errorf("invalid NFS metric line %q", line) 36 | } 37 | 38 | values, err := util.ParseUint64s(parts[1:]) 39 | if err != nil { 40 | return nil, fmt.Errorf("error parsing NFS metric line: %s", err) 41 | } 42 | 43 | switch metricLine := parts[0]; metricLine { 44 | case "net": 45 | stats.Network, err = parseNetwork(values) 46 | case "rpc": 47 | stats.ClientRPC, err = parseClientRPC(values) 48 | case "proc2": 49 | stats.V2Stats, err = parseV2Stats(values) 50 | case "proc3": 51 | stats.V3Stats, err = parseV3Stats(values) 52 | case "proc4": 53 | stats.ClientV4Stats, err = parseClientV4Stats(values) 54 | default: 55 | return nil, fmt.Errorf("unknown NFS metric line %q", metricLine) 56 | } 57 | if err != nil { 58 | return nil, fmt.Errorf("errors parsing NFS metric line: %s", err) 59 | } 60 | } 61 | 62 | if err := scanner.Err(); err != nil { 63 | return nil, fmt.Errorf("error scanning NFS file: %s", err) 64 | } 65 | 66 | return stats, nil 67 | } 68 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/proc_ns.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package procfs 15 | 16 | import ( 17 | "fmt" 18 | "os" 19 | "strconv" 20 | "strings" 21 | ) 22 | 23 | // Namespace represents a single namespace of a process. 24 | type Namespace struct { 25 | Type string // Namespace type. 26 | Inode uint32 // Inode number of the namespace. If two processes are in the same namespace their inodes will match. 27 | } 28 | 29 | // Namespaces contains all of the namespaces that the process is contained in. 30 | type Namespaces map[string]Namespace 31 | 32 | // NewNamespaces reads from /proc/[pid/ns/* to get the namespaces of which the 33 | // process is a member. 34 | func (p Proc) NewNamespaces() (Namespaces, error) { 35 | d, err := os.Open(p.path("ns")) 36 | if err != nil { 37 | return nil, err 38 | } 39 | defer d.Close() 40 | 41 | names, err := d.Readdirnames(-1) 42 | if err != nil { 43 | return nil, fmt.Errorf("failed to read contents of ns dir: %v", err) 44 | } 45 | 46 | ns := make(Namespaces, len(names)) 47 | for _, name := range names { 48 | target, err := os.Readlink(p.path("ns", name)) 49 | if err != nil { 50 | return nil, err 51 | } 52 | 53 | fields := strings.SplitN(target, ":", 2) 54 | if len(fields) != 2 { 55 | return nil, fmt.Errorf("failed to parse namespace type and inode from '%v'", target) 56 | } 57 | 58 | typ := fields[0] 59 | inode, err := strconv.ParseUint(strings.Trim(fields[1], "[]"), 10, 32) 60 | if err != nil { 61 | return nil, fmt.Errorf("failed to parse inode from '%v': %v", fields[1], err) 62 | } 63 | 64 | ns[name] = Namespace{typ, uint32(inode)} 65 | } 66 | 67 | return ns, nil 68 | } 69 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | NVIDIA GPU Prometheus Exporter 2 | ------------------------------ 3 | 4 | This is a [Prometheus Exporter](https://prometheus.io/docs/instrumenting/exporters/) for 5 | exporting NVIDIA GPU metrics. It uses the [Go bindings](https://github.com/mindprince/gonvml) 6 | for [NVIDIA Management Library](https://developer.nvidia.com/nvidia-management-library-nvml) 7 | (NVML) which is a C-based API that can be used for monitoring NVIDIA GPU devices. 8 | Unlike some other similar exporters, it does not call the 9 | [`nvidia-smi`](https://developer.nvidia.com/nvidia-system-management-interface) binary. 10 | 11 | ## Building 12 | 13 | The repository includes `nvml.h`, so there are no special requirements from the 14 | build environment. `go get` should be able to build the exporter binary. 15 | 16 | ``` 17 | go get github.com/mindprince/nvidia_gpu_prometheus_exporter 18 | ``` 19 | 20 | ## Running 21 | 22 | The exporter requires the following: 23 | - access to NVML library (`libnvidia-ml.so.1`). 24 | - access to the GPU devices. 25 | 26 | To make sure that the exporter can access the NVML libraries, either add them 27 | to the search path for shared libraries. Or set `LD_LIBRARY_PATH` to point to 28 | their location. 29 | 30 | By default the metrics are exposed on port `9445`. This can be updated using 31 | the `-web.listen-address` flag. 32 | 33 | ## Running inside a container 34 | 35 | There's a docker image available on Docker Hub at 36 | [mindprince/nvidia_gpu_prometheus_exporter](https://hub.docker.com/r/mindprince/nvidia_gpu_prometheus_exporter/) 37 | 38 | If you are running the exporter inside a container, you will need to do the 39 | following to give the container access to NVML library: 40 | ``` 41 | -e LD_LIBRARY_PATH= 42 | --volume : 43 | ``` 44 | 45 | And you will need to do one of the following to give it access to the GPU 46 | devices: 47 | - Run with `--privileged` 48 | - If you are on docker v17.04.0-ce or above, run with `--device-cgroup-rule 'c 195:* mrw'` 49 | - Run with `--device /dev/nvidiactl:/dev/nvidiactl /dev/nvidia0:/dev/nvidia0 /dev/nvidia1:/dev/nvidia1 ` 50 | 51 | If you don't want to do the above, you can run it using nvidia-docker. 52 | 53 | ## Running using [nvidia-docker](https://github.com/NVIDIA/nvidia-docker) 54 | 55 | ``` 56 | nvidia-docker run -p 9445:9445 -ti mindprince/nvidia_gpu_prometheus_exporter:0.1 57 | ``` 58 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright 2018 The Prometheus Authors 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | # Ensure GOBIN is not set during build so that promu is installed to the correct path 15 | unexport GOBIN 16 | 17 | GO ?= go 18 | GOFMT ?= $(GO)fmt 19 | FIRST_GOPATH := $(firstword $(subst :, ,$(shell $(GO) env GOPATH))) 20 | STATICCHECK := $(FIRST_GOPATH)/bin/staticcheck 21 | pkgs = $(shell $(GO) list ./... | grep -v /vendor/) 22 | 23 | PREFIX ?= $(shell pwd) 24 | BIN_DIR ?= $(shell pwd) 25 | 26 | ifdef DEBUG 27 | bindata_flags = -debug 28 | endif 29 | 30 | STATICCHECK_IGNORE = 31 | 32 | all: format staticcheck build test 33 | 34 | style: 35 | @echo ">> checking code style" 36 | @! $(GOFMT) -d $(shell find . -path ./vendor -prune -o -name '*.go' -print) | grep '^' 37 | 38 | check_license: 39 | @echo ">> checking license header" 40 | @./scripts/check_license.sh 41 | 42 | test: fixtures/.unpacked sysfs/fixtures/.unpacked 43 | @echo ">> running all tests" 44 | @$(GO) test -race $(shell $(GO) list ./... | grep -v /vendor/ | grep -v examples) 45 | 46 | format: 47 | @echo ">> formatting code" 48 | @$(GO) fmt $(pkgs) 49 | 50 | vet: 51 | @echo ">> vetting code" 52 | @$(GO) vet $(pkgs) 53 | 54 | staticcheck: $(STATICCHECK) 55 | @echo ">> running staticcheck" 56 | @$(STATICCHECK) -ignore "$(STATICCHECK_IGNORE)" $(pkgs) 57 | 58 | %/.unpacked: %.ttar 59 | ./ttar -C $(dir $*) -x -f $*.ttar 60 | touch $@ 61 | 62 | $(FIRST_GOPATH)/bin/staticcheck: 63 | @GOOS= GOARCH= $(GO) get -u honnef.co/go/tools/cmd/staticcheck 64 | 65 | .PHONY: all style check_license format test vet staticcheck 66 | 67 | # Declaring the binaries at their default locations as PHONY targets is a hack 68 | # to ensure the latest version is downloaded on every make execution. 69 | # If this is not desired, copy/symlink these binaries to a different path and 70 | # set the respective environment variables. 71 | .PHONY: $(GOPATH)/bin/staticcheck 72 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/README.txt: -------------------------------------------------------------------------------- 1 | PACKAGE 2 | 3 | package goautoneg 4 | import "bitbucket.org/ww/goautoneg" 5 | 6 | HTTP Content-Type Autonegotiation. 7 | 8 | The functions in this package implement the behaviour specified in 9 | http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html 10 | 11 | Copyright (c) 2011, Open Knowledge Foundation Ltd. 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are 16 | met: 17 | 18 | Redistributions of source code must retain the above copyright 19 | notice, this list of conditions and the following disclaimer. 20 | 21 | Redistributions in binary form must reproduce the above copyright 22 | notice, this list of conditions and the following disclaimer in 23 | the documentation and/or other materials provided with the 24 | distribution. 25 | 26 | Neither the name of the Open Knowledge Foundation Ltd. nor the 27 | names of its contributors may be used to endorse or promote 28 | products derived from this software without specific prior written 29 | permission. 30 | 31 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 34 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 36 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 37 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 38 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 39 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 40 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 41 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 | 43 | 44 | FUNCTIONS 45 | 46 | func Negotiate(header string, alternatives []string) (content_type string) 47 | Negotiate the most appropriate content_type given the accept header 48 | and a list of alternatives. 49 | 50 | func ParseAccept(header string) (accept []Accept) 51 | Parse an Accept Header string returning a sorted list 52 | of clauses 53 | 54 | 55 | TYPES 56 | 57 | type Accept struct { 58 | Type, SubType string 59 | Q float32 60 | Params map[string]string 61 | } 62 | Structure to represent a clause in an HTTP Accept Header 63 | 64 | 65 | SUBDIRECTORIES 66 | 67 | .hg 68 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/fs.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package procfs 15 | 16 | import ( 17 | "fmt" 18 | "os" 19 | "path" 20 | 21 | "github.com/prometheus/procfs/nfs" 22 | "github.com/prometheus/procfs/xfs" 23 | ) 24 | 25 | // FS represents the pseudo-filesystem proc, which provides an interface to 26 | // kernel data structures. 27 | type FS string 28 | 29 | // DefaultMountPoint is the common mount point of the proc filesystem. 30 | const DefaultMountPoint = "/proc" 31 | 32 | // NewFS returns a new FS mounted under the given mountPoint. It will error 33 | // if the mount point can't be read. 34 | func NewFS(mountPoint string) (FS, error) { 35 | info, err := os.Stat(mountPoint) 36 | if err != nil { 37 | return "", fmt.Errorf("could not read %s: %s", mountPoint, err) 38 | } 39 | if !info.IsDir() { 40 | return "", fmt.Errorf("mount point %s is not a directory", mountPoint) 41 | } 42 | 43 | return FS(mountPoint), nil 44 | } 45 | 46 | // Path returns the path of the given subsystem relative to the procfs root. 47 | func (fs FS) Path(p ...string) string { 48 | return path.Join(append([]string{string(fs)}, p...)...) 49 | } 50 | 51 | // XFSStats retrieves XFS filesystem runtime statistics. 52 | func (fs FS) XFSStats() (*xfs.Stats, error) { 53 | f, err := os.Open(fs.Path("fs/xfs/stat")) 54 | if err != nil { 55 | return nil, err 56 | } 57 | defer f.Close() 58 | 59 | return xfs.ParseStats(f) 60 | } 61 | 62 | // NFSClientRPCStats retrieves NFS client RPC statistics. 63 | func (fs FS) NFSClientRPCStats() (*nfs.ClientRPCStats, error) { 64 | f, err := os.Open(fs.Path("net/rpc/nfs")) 65 | if err != nil { 66 | return nil, err 67 | } 68 | defer f.Close() 69 | 70 | return nfs.ParseClientRPCStats(f) 71 | } 72 | 73 | // NFSdServerRPCStats retrieves NFS daemon RPC statistics. 74 | func (fs FS) NFSdServerRPCStats() (*nfs.ServerRPCStats, error) { 75 | f, err := os.Open(fs.Path("net/rpc/nfsd")) 76 | if err != nil { 77 | return nil, err 78 | } 79 | defer f.Close() 80 | 81 | return nfs.ParseServerRPCStats(f) 82 | } 83 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/buddyinfo.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package procfs 15 | 16 | import ( 17 | "bufio" 18 | "fmt" 19 | "io" 20 | "os" 21 | "strconv" 22 | "strings" 23 | ) 24 | 25 | // A BuddyInfo is the details parsed from /proc/buddyinfo. 26 | // The data is comprised of an array of free fragments of each size. 27 | // The sizes are 2^n*PAGE_SIZE, where n is the array index. 28 | type BuddyInfo struct { 29 | Node string 30 | Zone string 31 | Sizes []float64 32 | } 33 | 34 | // NewBuddyInfo reads the buddyinfo statistics. 35 | func NewBuddyInfo() ([]BuddyInfo, error) { 36 | fs, err := NewFS(DefaultMountPoint) 37 | if err != nil { 38 | return nil, err 39 | } 40 | 41 | return fs.NewBuddyInfo() 42 | } 43 | 44 | // NewBuddyInfo reads the buddyinfo statistics from the specified `proc` filesystem. 45 | func (fs FS) NewBuddyInfo() ([]BuddyInfo, error) { 46 | file, err := os.Open(fs.Path("buddyinfo")) 47 | if err != nil { 48 | return nil, err 49 | } 50 | defer file.Close() 51 | 52 | return parseBuddyInfo(file) 53 | } 54 | 55 | func parseBuddyInfo(r io.Reader) ([]BuddyInfo, error) { 56 | var ( 57 | buddyInfo = []BuddyInfo{} 58 | scanner = bufio.NewScanner(r) 59 | bucketCount = -1 60 | ) 61 | 62 | for scanner.Scan() { 63 | var err error 64 | line := scanner.Text() 65 | parts := strings.Fields(line) 66 | 67 | if len(parts) < 4 { 68 | return nil, fmt.Errorf("invalid number of fields when parsing buddyinfo") 69 | } 70 | 71 | node := strings.TrimRight(parts[1], ",") 72 | zone := strings.TrimRight(parts[3], ",") 73 | arraySize := len(parts[4:]) 74 | 75 | if bucketCount == -1 { 76 | bucketCount = arraySize 77 | } else { 78 | if bucketCount != arraySize { 79 | return nil, fmt.Errorf("mismatch in number of buddyinfo buckets, previous count %d, new count %d", bucketCount, arraySize) 80 | } 81 | } 82 | 83 | sizes := make([]float64, arraySize) 84 | for i := 0; i < arraySize; i++ { 85 | sizes[i], err = strconv.ParseFloat(parts[i+4], 64) 86 | if err != nil { 87 | return nil, fmt.Errorf("invalid value in buddyinfo: %s", err) 88 | } 89 | } 90 | 91 | buddyInfo = append(buddyInfo, BuddyInfo{node, zone, sizes}) 92 | } 93 | 94 | return buddyInfo, scanner.Err() 95 | } 96 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/nfs/parse_nfsd.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package nfs 15 | 16 | import ( 17 | "bufio" 18 | "fmt" 19 | "io" 20 | "strings" 21 | 22 | "github.com/prometheus/procfs/internal/util" 23 | ) 24 | 25 | // ParseServerRPCStats returns stats read from /proc/net/rpc/nfsd 26 | func ParseServerRPCStats(r io.Reader) (*ServerRPCStats, error) { 27 | stats := &ServerRPCStats{} 28 | 29 | scanner := bufio.NewScanner(r) 30 | for scanner.Scan() { 31 | line := scanner.Text() 32 | parts := strings.Fields(scanner.Text()) 33 | // require at least 34 | if len(parts) < 2 { 35 | return nil, fmt.Errorf("invalid NFSd metric line %q", line) 36 | } 37 | label := parts[0] 38 | 39 | var values []uint64 40 | var err error 41 | if label == "th" { 42 | if len(parts) < 3 { 43 | return nil, fmt.Errorf("invalid NFSd th metric line %q", line) 44 | } 45 | values, err = util.ParseUint64s(parts[1:3]) 46 | } else { 47 | values, err = util.ParseUint64s(parts[1:]) 48 | } 49 | if err != nil { 50 | return nil, fmt.Errorf("error parsing NFSd metric line: %s", err) 51 | } 52 | 53 | switch metricLine := parts[0]; metricLine { 54 | case "rc": 55 | stats.ReplyCache, err = parseReplyCache(values) 56 | case "fh": 57 | stats.FileHandles, err = parseFileHandles(values) 58 | case "io": 59 | stats.InputOutput, err = parseInputOutput(values) 60 | case "th": 61 | stats.Threads, err = parseThreads(values) 62 | case "ra": 63 | stats.ReadAheadCache, err = parseReadAheadCache(values) 64 | case "net": 65 | stats.Network, err = parseNetwork(values) 66 | case "rpc": 67 | stats.ServerRPC, err = parseServerRPC(values) 68 | case "proc2": 69 | stats.V2Stats, err = parseV2Stats(values) 70 | case "proc3": 71 | stats.V3Stats, err = parseV3Stats(values) 72 | case "proc4": 73 | stats.ServerV4Stats, err = parseServerV4Stats(values) 74 | case "proc4ops": 75 | stats.V4Ops, err = parseV4Ops(values) 76 | default: 77 | return nil, fmt.Errorf("unknown NFSd metric line %q", metricLine) 78 | } 79 | if err != nil { 80 | return nil, fmt.Errorf("errors parsing NFSd metric line: %s", err) 81 | } 82 | } 83 | 84 | if err := scanner.Err(); err != nil { 85 | return nil, fmt.Errorf("error scanning NFSd file: %s", err) 86 | } 87 | 88 | return stats, nil 89 | } 90 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/expfmt/encode.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package expfmt 15 | 16 | import ( 17 | "fmt" 18 | "io" 19 | "net/http" 20 | 21 | "github.com/golang/protobuf/proto" 22 | "github.com/matttproud/golang_protobuf_extensions/pbutil" 23 | "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg" 24 | 25 | dto "github.com/prometheus/client_model/go" 26 | ) 27 | 28 | // Encoder types encode metric families into an underlying wire protocol. 29 | type Encoder interface { 30 | Encode(*dto.MetricFamily) error 31 | } 32 | 33 | type encoder func(*dto.MetricFamily) error 34 | 35 | func (e encoder) Encode(v *dto.MetricFamily) error { 36 | return e(v) 37 | } 38 | 39 | // Negotiate returns the Content-Type based on the given Accept header. 40 | // If no appropriate accepted type is found, FmtText is returned. 41 | func Negotiate(h http.Header) Format { 42 | for _, ac := range goautoneg.ParseAccept(h.Get(hdrAccept)) { 43 | // Check for protocol buffer 44 | if ac.Type+"/"+ac.SubType == ProtoType && ac.Params["proto"] == ProtoProtocol { 45 | switch ac.Params["encoding"] { 46 | case "delimited": 47 | return FmtProtoDelim 48 | case "text": 49 | return FmtProtoText 50 | case "compact-text": 51 | return FmtProtoCompact 52 | } 53 | } 54 | // Check for text format. 55 | ver := ac.Params["version"] 56 | if ac.Type == "text" && ac.SubType == "plain" && (ver == TextVersion || ver == "") { 57 | return FmtText 58 | } 59 | } 60 | return FmtText 61 | } 62 | 63 | // NewEncoder returns a new encoder based on content type negotiation. 64 | func NewEncoder(w io.Writer, format Format) Encoder { 65 | switch format { 66 | case FmtProtoDelim: 67 | return encoder(func(v *dto.MetricFamily) error { 68 | _, err := pbutil.WriteDelimited(w, v) 69 | return err 70 | }) 71 | case FmtProtoCompact: 72 | return encoder(func(v *dto.MetricFamily) error { 73 | _, err := fmt.Fprintln(w, v.String()) 74 | return err 75 | }) 76 | case FmtProtoText: 77 | return encoder(func(v *dto.MetricFamily) error { 78 | _, err := fmt.Fprintln(w, proto.MarshalTextString(v)) 79 | return err 80 | }) 81 | case FmtText: 82 | return encoder(func(v *dto.MetricFamily) error { 83 | _, err := MetricFamilyToText(w, v) 84 | return err 85 | }) 86 | } 87 | panic("expfmt.NewEncoder: unknown format") 88 | } 89 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/model/fingerprinting.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package model 15 | 16 | import ( 17 | "fmt" 18 | "strconv" 19 | ) 20 | 21 | // Fingerprint provides a hash-capable representation of a Metric. 22 | // For our purposes, FNV-1A 64-bit is used. 23 | type Fingerprint uint64 24 | 25 | // FingerprintFromString transforms a string representation into a Fingerprint. 26 | func FingerprintFromString(s string) (Fingerprint, error) { 27 | num, err := strconv.ParseUint(s, 16, 64) 28 | return Fingerprint(num), err 29 | } 30 | 31 | // ParseFingerprint parses the input string into a fingerprint. 32 | func ParseFingerprint(s string) (Fingerprint, error) { 33 | num, err := strconv.ParseUint(s, 16, 64) 34 | if err != nil { 35 | return 0, err 36 | } 37 | return Fingerprint(num), nil 38 | } 39 | 40 | func (f Fingerprint) String() string { 41 | return fmt.Sprintf("%016x", uint64(f)) 42 | } 43 | 44 | // Fingerprints represents a collection of Fingerprint subject to a given 45 | // natural sorting scheme. It implements sort.Interface. 46 | type Fingerprints []Fingerprint 47 | 48 | // Len implements sort.Interface. 49 | func (f Fingerprints) Len() int { 50 | return len(f) 51 | } 52 | 53 | // Less implements sort.Interface. 54 | func (f Fingerprints) Less(i, j int) bool { 55 | return f[i] < f[j] 56 | } 57 | 58 | // Swap implements sort.Interface. 59 | func (f Fingerprints) Swap(i, j int) { 60 | f[i], f[j] = f[j], f[i] 61 | } 62 | 63 | // FingerprintSet is a set of Fingerprints. 64 | type FingerprintSet map[Fingerprint]struct{} 65 | 66 | // Equal returns true if both sets contain the same elements (and not more). 67 | func (s FingerprintSet) Equal(o FingerprintSet) bool { 68 | if len(s) != len(o) { 69 | return false 70 | } 71 | 72 | for k := range s { 73 | if _, ok := o[k]; !ok { 74 | return false 75 | } 76 | } 77 | 78 | return true 79 | } 80 | 81 | // Intersection returns the elements contained in both sets. 82 | func (s FingerprintSet) Intersection(o FingerprintSet) FingerprintSet { 83 | myLength, otherLength := len(s), len(o) 84 | if myLength == 0 || otherLength == 0 { 85 | return FingerprintSet{} 86 | } 87 | 88 | subSet := s 89 | superSet := o 90 | 91 | if otherLength < myLength { 92 | subSet = o 93 | superSet = s 94 | } 95 | 96 | out := FingerprintSet{} 97 | 98 | for k := range subSet { 99 | if _, ok := superSet[k]; ok { 100 | out[k] = struct{}{} 101 | } 102 | } 103 | 104 | return out 105 | } 106 | -------------------------------------------------------------------------------- /vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/decode.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Matt T. Proud 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package pbutil 16 | 17 | import ( 18 | "encoding/binary" 19 | "errors" 20 | "io" 21 | 22 | "github.com/golang/protobuf/proto" 23 | ) 24 | 25 | var errInvalidVarint = errors.New("invalid varint32 encountered") 26 | 27 | // ReadDelimited decodes a message from the provided length-delimited stream, 28 | // where the length is encoded as 32-bit varint prefix to the message body. 29 | // It returns the total number of bytes read and any applicable error. This is 30 | // roughly equivalent to the companion Java API's 31 | // MessageLite#parseDelimitedFrom. As per the reader contract, this function 32 | // calls r.Read repeatedly as required until exactly one message including its 33 | // prefix is read and decoded (or an error has occurred). The function never 34 | // reads more bytes from the stream than required. The function never returns 35 | // an error if a message has been read and decoded correctly, even if the end 36 | // of the stream has been reached in doing so. In that case, any subsequent 37 | // calls return (0, io.EOF). 38 | func ReadDelimited(r io.Reader, m proto.Message) (n int, err error) { 39 | // Per AbstractParser#parsePartialDelimitedFrom with 40 | // CodedInputStream#readRawVarint32. 41 | var headerBuf [binary.MaxVarintLen32]byte 42 | var bytesRead, varIntBytes int 43 | var messageLength uint64 44 | for varIntBytes == 0 { // i.e. no varint has been decoded yet. 45 | if bytesRead >= len(headerBuf) { 46 | return bytesRead, errInvalidVarint 47 | } 48 | // We have to read byte by byte here to avoid reading more bytes 49 | // than required. Each read byte is appended to what we have 50 | // read before. 51 | newBytesRead, err := r.Read(headerBuf[bytesRead : bytesRead+1]) 52 | if newBytesRead == 0 { 53 | if err != nil { 54 | return bytesRead, err 55 | } 56 | // A Reader should not return (0, nil), but if it does, 57 | // it should be treated as no-op (according to the 58 | // Reader contract). So let's go on... 59 | continue 60 | } 61 | bytesRead += newBytesRead 62 | // Now present everything read so far to the varint decoder and 63 | // see if a varint can be decoded already. 64 | messageLength, varIntBytes = proto.DecodeVarint(headerBuf[:bytesRead]) 65 | } 66 | 67 | messageBuf := make([]byte, messageLength) 68 | newBytesRead, err := io.ReadFull(r, messageBuf) 69 | bytesRead += newBytesRead 70 | if err != nil { 71 | return bytesRead, err 72 | } 73 | 74 | return bytesRead, proto.Unmarshal(messageBuf, m) 75 | } 76 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/model/silence.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package model 15 | 16 | import ( 17 | "encoding/json" 18 | "fmt" 19 | "regexp" 20 | "time" 21 | ) 22 | 23 | // Matcher describes a matches the value of a given label. 24 | type Matcher struct { 25 | Name LabelName `json:"name"` 26 | Value string `json:"value"` 27 | IsRegex bool `json:"isRegex"` 28 | } 29 | 30 | func (m *Matcher) UnmarshalJSON(b []byte) error { 31 | type plain Matcher 32 | if err := json.Unmarshal(b, (*plain)(m)); err != nil { 33 | return err 34 | } 35 | 36 | if len(m.Name) == 0 { 37 | return fmt.Errorf("label name in matcher must not be empty") 38 | } 39 | if m.IsRegex { 40 | if _, err := regexp.Compile(m.Value); err != nil { 41 | return err 42 | } 43 | } 44 | return nil 45 | } 46 | 47 | // Validate returns true iff all fields of the matcher have valid values. 48 | func (m *Matcher) Validate() error { 49 | if !m.Name.IsValid() { 50 | return fmt.Errorf("invalid name %q", m.Name) 51 | } 52 | if m.IsRegex { 53 | if _, err := regexp.Compile(m.Value); err != nil { 54 | return fmt.Errorf("invalid regular expression %q", m.Value) 55 | } 56 | } else if !LabelValue(m.Value).IsValid() || len(m.Value) == 0 { 57 | return fmt.Errorf("invalid value %q", m.Value) 58 | } 59 | return nil 60 | } 61 | 62 | // Silence defines the representation of a silence definition in the Prometheus 63 | // eco-system. 64 | type Silence struct { 65 | ID uint64 `json:"id,omitempty"` 66 | 67 | Matchers []*Matcher `json:"matchers"` 68 | 69 | StartsAt time.Time `json:"startsAt"` 70 | EndsAt time.Time `json:"endsAt"` 71 | 72 | CreatedAt time.Time `json:"createdAt,omitempty"` 73 | CreatedBy string `json:"createdBy"` 74 | Comment string `json:"comment,omitempty"` 75 | } 76 | 77 | // Validate returns true iff all fields of the silence have valid values. 78 | func (s *Silence) Validate() error { 79 | if len(s.Matchers) == 0 { 80 | return fmt.Errorf("at least one matcher required") 81 | } 82 | for _, m := range s.Matchers { 83 | if err := m.Validate(); err != nil { 84 | return fmt.Errorf("invalid matcher: %s", err) 85 | } 86 | } 87 | if s.StartsAt.IsZero() { 88 | return fmt.Errorf("start time missing") 89 | } 90 | if s.EndsAt.IsZero() { 91 | return fmt.Errorf("end time missing") 92 | } 93 | if s.EndsAt.Before(s.StartsAt) { 94 | return fmt.Errorf("start time must be before end time") 95 | } 96 | if s.CreatedBy == "" { 97 | return fmt.Errorf("creator information missing") 98 | } 99 | if s.Comment == "" { 100 | return fmt.Errorf("comment missing") 101 | } 102 | if s.CreatedAt.IsZero() { 103 | return fmt.Errorf("creation timestamp missing") 104 | } 105 | return nil 106 | } 107 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/model/metric.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package model 15 | 16 | import ( 17 | "fmt" 18 | "regexp" 19 | "sort" 20 | "strings" 21 | ) 22 | 23 | var ( 24 | separator = []byte{0} 25 | // MetricNameRE is a regular expression matching valid metric 26 | // names. Note that the IsValidMetricName function performs the same 27 | // check but faster than a match with this regular expression. 28 | MetricNameRE = regexp.MustCompile(`^[a-zA-Z_:][a-zA-Z0-9_:]*$`) 29 | ) 30 | 31 | // A Metric is similar to a LabelSet, but the key difference is that a Metric is 32 | // a singleton and refers to one and only one stream of samples. 33 | type Metric LabelSet 34 | 35 | // Equal compares the metrics. 36 | func (m Metric) Equal(o Metric) bool { 37 | return LabelSet(m).Equal(LabelSet(o)) 38 | } 39 | 40 | // Before compares the metrics' underlying label sets. 41 | func (m Metric) Before(o Metric) bool { 42 | return LabelSet(m).Before(LabelSet(o)) 43 | } 44 | 45 | // Clone returns a copy of the Metric. 46 | func (m Metric) Clone() Metric { 47 | clone := make(Metric, len(m)) 48 | for k, v := range m { 49 | clone[k] = v 50 | } 51 | return clone 52 | } 53 | 54 | func (m Metric) String() string { 55 | metricName, hasName := m[MetricNameLabel] 56 | numLabels := len(m) - 1 57 | if !hasName { 58 | numLabels = len(m) 59 | } 60 | labelStrings := make([]string, 0, numLabels) 61 | for label, value := range m { 62 | if label != MetricNameLabel { 63 | labelStrings = append(labelStrings, fmt.Sprintf("%s=%q", label, value)) 64 | } 65 | } 66 | 67 | switch numLabels { 68 | case 0: 69 | if hasName { 70 | return string(metricName) 71 | } 72 | return "{}" 73 | default: 74 | sort.Strings(labelStrings) 75 | return fmt.Sprintf("%s{%s}", metricName, strings.Join(labelStrings, ", ")) 76 | } 77 | } 78 | 79 | // Fingerprint returns a Metric's Fingerprint. 80 | func (m Metric) Fingerprint() Fingerprint { 81 | return LabelSet(m).Fingerprint() 82 | } 83 | 84 | // FastFingerprint returns a Metric's Fingerprint calculated by a faster hashing 85 | // algorithm, which is, however, more susceptible to hash collisions. 86 | func (m Metric) FastFingerprint() Fingerprint { 87 | return LabelSet(m).FastFingerprint() 88 | } 89 | 90 | // IsValidMetricName returns true iff name matches the pattern of MetricNameRE. 91 | // This function, however, does not use MetricNameRE for the check but a much 92 | // faster hardcoded implementation. 93 | func IsValidMetricName(n LabelValue) bool { 94 | if len(n) == 0 { 95 | return false 96 | } 97 | for i, b := range n { 98 | if !((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || b == ':' || (b >= '0' && b <= '9' && i > 0)) { 99 | return false 100 | } 101 | } 102 | return true 103 | } 104 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_golang/prometheus/collector.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package prometheus 15 | 16 | // Collector is the interface implemented by anything that can be used by 17 | // Prometheus to collect metrics. A Collector has to be registered for 18 | // collection. See Registerer.Register. 19 | // 20 | // The stock metrics provided by this package (Gauge, Counter, Summary, 21 | // Histogram, Untyped) are also Collectors (which only ever collect one metric, 22 | // namely itself). An implementer of Collector may, however, collect multiple 23 | // metrics in a coordinated fashion and/or create metrics on the fly. Examples 24 | // for collectors already implemented in this library are the metric vectors 25 | // (i.e. collection of multiple instances of the same Metric but with different 26 | // label values) like GaugeVec or SummaryVec, and the ExpvarCollector. 27 | type Collector interface { 28 | // Describe sends the super-set of all possible descriptors of metrics 29 | // collected by this Collector to the provided channel and returns once 30 | // the last descriptor has been sent. The sent descriptors fulfill the 31 | // consistency and uniqueness requirements described in the Desc 32 | // documentation. (It is valid if one and the same Collector sends 33 | // duplicate descriptors. Those duplicates are simply ignored. However, 34 | // two different Collectors must not send duplicate descriptors.) This 35 | // method idempotently sends the same descriptors throughout the 36 | // lifetime of the Collector. If a Collector encounters an error while 37 | // executing this method, it must send an invalid descriptor (created 38 | // with NewInvalidDesc) to signal the error to the registry. 39 | Describe(chan<- *Desc) 40 | // Collect is called by the Prometheus registry when collecting 41 | // metrics. The implementation sends each collected metric via the 42 | // provided channel and returns once the last metric has been sent. The 43 | // descriptor of each sent metric is one of those returned by 44 | // Describe. Returned metrics that share the same descriptor must differ 45 | // in their variable label values. This method may be called 46 | // concurrently and must therefore be implemented in a concurrency safe 47 | // way. Blocking occurs at the expense of total performance of rendering 48 | // all registered metrics. Ideally, Collector implementations support 49 | // concurrent readers. 50 | Collect(chan<- Metric) 51 | } 52 | 53 | // selfCollector implements Collector for a single Metric so that the Metric 54 | // collects itself. Add it as an anonymous field to a struct that implements 55 | // Metric, and call init with the Metric itself as an argument. 56 | type selfCollector struct { 57 | self Metric 58 | } 59 | 60 | // init provides the selfCollector with a reference to the metric it is supposed 61 | // to collect. It is usually called within the factory function to create a 62 | // metric. See example. 63 | func (c *selfCollector) init(self Metric) { 64 | c.self = self 65 | } 66 | 67 | // Describe implements Collector. 68 | func (c *selfCollector) Describe(ch chan<- *Desc) { 69 | ch <- c.self.Desc() 70 | } 71 | 72 | // Collect implements Collector. 73 | func (c *selfCollector) Collect(ch chan<- Metric) { 74 | ch <- c.self 75 | } 76 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/model/alert.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package model 15 | 16 | import ( 17 | "fmt" 18 | "time" 19 | ) 20 | 21 | type AlertStatus string 22 | 23 | const ( 24 | AlertFiring AlertStatus = "firing" 25 | AlertResolved AlertStatus = "resolved" 26 | ) 27 | 28 | // Alert is a generic representation of an alert in the Prometheus eco-system. 29 | type Alert struct { 30 | // Label value pairs for purpose of aggregation, matching, and disposition 31 | // dispatching. This must minimally include an "alertname" label. 32 | Labels LabelSet `json:"labels"` 33 | 34 | // Extra key/value information which does not define alert identity. 35 | Annotations LabelSet `json:"annotations"` 36 | 37 | // The known time range for this alert. Both ends are optional. 38 | StartsAt time.Time `json:"startsAt,omitempty"` 39 | EndsAt time.Time `json:"endsAt,omitempty"` 40 | GeneratorURL string `json:"generatorURL"` 41 | } 42 | 43 | // Name returns the name of the alert. It is equivalent to the "alertname" label. 44 | func (a *Alert) Name() string { 45 | return string(a.Labels[AlertNameLabel]) 46 | } 47 | 48 | // Fingerprint returns a unique hash for the alert. It is equivalent to 49 | // the fingerprint of the alert's label set. 50 | func (a *Alert) Fingerprint() Fingerprint { 51 | return a.Labels.Fingerprint() 52 | } 53 | 54 | func (a *Alert) String() string { 55 | s := fmt.Sprintf("%s[%s]", a.Name(), a.Fingerprint().String()[:7]) 56 | if a.Resolved() { 57 | return s + "[resolved]" 58 | } 59 | return s + "[active]" 60 | } 61 | 62 | // Resolved returns true iff the activity interval ended in the past. 63 | func (a *Alert) Resolved() bool { 64 | return a.ResolvedAt(time.Now()) 65 | } 66 | 67 | // ResolvedAt returns true off the activity interval ended before 68 | // the given timestamp. 69 | func (a *Alert) ResolvedAt(ts time.Time) bool { 70 | if a.EndsAt.IsZero() { 71 | return false 72 | } 73 | return !a.EndsAt.After(ts) 74 | } 75 | 76 | // Status returns the status of the alert. 77 | func (a *Alert) Status() AlertStatus { 78 | if a.Resolved() { 79 | return AlertResolved 80 | } 81 | return AlertFiring 82 | } 83 | 84 | // Validate checks whether the alert data is inconsistent. 85 | func (a *Alert) Validate() error { 86 | if a.StartsAt.IsZero() { 87 | return fmt.Errorf("start time missing") 88 | } 89 | if !a.EndsAt.IsZero() && a.EndsAt.Before(a.StartsAt) { 90 | return fmt.Errorf("start time must be before end time") 91 | } 92 | if err := a.Labels.Validate(); err != nil { 93 | return fmt.Errorf("invalid label set: %s", err) 94 | } 95 | if len(a.Labels) == 0 { 96 | return fmt.Errorf("at least one label pair required") 97 | } 98 | if err := a.Annotations.Validate(); err != nil { 99 | return fmt.Errorf("invalid annotations: %s", err) 100 | } 101 | return nil 102 | } 103 | 104 | // Alert is a list of alerts that can be sorted in chronological order. 105 | type Alerts []*Alert 106 | 107 | func (as Alerts) Len() int { return len(as) } 108 | func (as Alerts) Swap(i, j int) { as[i], as[j] = as[j], as[i] } 109 | 110 | func (as Alerts) Less(i, j int) bool { 111 | if as[i].StartsAt.Before(as[j].StartsAt) { 112 | return true 113 | } 114 | if as[i].EndsAt.Before(as[j].EndsAt) { 115 | return true 116 | } 117 | return as[i].Fingerprint() < as[j].Fingerprint() 118 | } 119 | 120 | // HasFiring returns true iff one of the alerts is not resolved. 121 | func (as Alerts) HasFiring() bool { 122 | for _, a := range as { 123 | if !a.Resolved() { 124 | return true 125 | } 126 | } 127 | return false 128 | } 129 | 130 | // Status returns StatusFiring iff at least one of the alerts is firing. 131 | func (as Alerts) Status() AlertStatus { 132 | if as.HasFiring() { 133 | return AlertFiring 134 | } 135 | return AlertResolved 136 | } 137 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_golang/prometheus/expvar_collector.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package prometheus 15 | 16 | import ( 17 | "encoding/json" 18 | "expvar" 19 | ) 20 | 21 | type expvarCollector struct { 22 | exports map[string]*Desc 23 | } 24 | 25 | // NewExpvarCollector returns a newly allocated expvar Collector that still has 26 | // to be registered with a Prometheus registry. 27 | // 28 | // An expvar Collector collects metrics from the expvar interface. It provides a 29 | // quick way to expose numeric values that are already exported via expvar as 30 | // Prometheus metrics. Note that the data models of expvar and Prometheus are 31 | // fundamentally different, and that the expvar Collector is inherently slower 32 | // than native Prometheus metrics. Thus, the expvar Collector is probably great 33 | // for experiments and prototying, but you should seriously consider a more 34 | // direct implementation of Prometheus metrics for monitoring production 35 | // systems. 36 | // 37 | // The exports map has the following meaning: 38 | // 39 | // The keys in the map correspond to expvar keys, i.e. for every expvar key you 40 | // want to export as Prometheus metric, you need an entry in the exports 41 | // map. The descriptor mapped to each key describes how to export the expvar 42 | // value. It defines the name and the help string of the Prometheus metric 43 | // proxying the expvar value. The type will always be Untyped. 44 | // 45 | // For descriptors without variable labels, the expvar value must be a number or 46 | // a bool. The number is then directly exported as the Prometheus sample 47 | // value. (For a bool, 'false' translates to 0 and 'true' to 1). Expvar values 48 | // that are not numbers or bools are silently ignored. 49 | // 50 | // If the descriptor has one variable label, the expvar value must be an expvar 51 | // map. The keys in the expvar map become the various values of the one 52 | // Prometheus label. The values in the expvar map must be numbers or bools again 53 | // as above. 54 | // 55 | // For descriptors with more than one variable label, the expvar must be a 56 | // nested expvar map, i.e. where the values of the topmost map are maps again 57 | // etc. until a depth is reached that corresponds to the number of labels. The 58 | // leaves of that structure must be numbers or bools as above to serve as the 59 | // sample values. 60 | // 61 | // Anything that does not fit into the scheme above is silently ignored. 62 | func NewExpvarCollector(exports map[string]*Desc) Collector { 63 | return &expvarCollector{ 64 | exports: exports, 65 | } 66 | } 67 | 68 | // Describe implements Collector. 69 | func (e *expvarCollector) Describe(ch chan<- *Desc) { 70 | for _, desc := range e.exports { 71 | ch <- desc 72 | } 73 | } 74 | 75 | // Collect implements Collector. 76 | func (e *expvarCollector) Collect(ch chan<- Metric) { 77 | for name, desc := range e.exports { 78 | var m Metric 79 | expVar := expvar.Get(name) 80 | if expVar == nil { 81 | continue 82 | } 83 | var v interface{} 84 | labels := make([]string, len(desc.variableLabels)) 85 | if err := json.Unmarshal([]byte(expVar.String()), &v); err != nil { 86 | ch <- NewInvalidMetric(desc, err) 87 | continue 88 | } 89 | var processValue func(v interface{}, i int) 90 | processValue = func(v interface{}, i int) { 91 | if i >= len(labels) { 92 | copiedLabels := append(make([]string, 0, len(labels)), labels...) 93 | switch v := v.(type) { 94 | case float64: 95 | m = MustNewConstMetric(desc, UntypedValue, v, copiedLabels...) 96 | case bool: 97 | if v { 98 | m = MustNewConstMetric(desc, UntypedValue, 1, copiedLabels...) 99 | } else { 100 | m = MustNewConstMetric(desc, UntypedValue, 0, copiedLabels...) 101 | } 102 | default: 103 | return 104 | } 105 | ch <- m 106 | return 107 | } 108 | vm, ok := v.(map[string]interface{}) 109 | if !ok { 110 | return 111 | } 112 | for lv, val := range vm { 113 | labels[i] = lv 114 | processValue(val, i+1) 115 | } 116 | } 117 | processValue(v, 0) 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_golang/prometheus/process_collector.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package prometheus 15 | 16 | import "github.com/prometheus/procfs" 17 | 18 | type processCollector struct { 19 | pid int 20 | collectFn func(chan<- Metric) 21 | pidFn func() (int, error) 22 | cpuTotal Counter 23 | openFDs, maxFDs Gauge 24 | vsize, rss Gauge 25 | startTime Gauge 26 | } 27 | 28 | // NewProcessCollector returns a collector which exports the current state of 29 | // process metrics including cpu, memory and file descriptor usage as well as 30 | // the process start time for the given process id under the given namespace. 31 | func NewProcessCollector(pid int, namespace string) Collector { 32 | return NewProcessCollectorPIDFn( 33 | func() (int, error) { return pid, nil }, 34 | namespace, 35 | ) 36 | } 37 | 38 | // NewProcessCollectorPIDFn returns a collector which exports the current state 39 | // of process metrics including cpu, memory and file descriptor usage as well 40 | // as the process start time under the given namespace. The given pidFn is 41 | // called on each collect and is used to determine the process to export 42 | // metrics for. 43 | func NewProcessCollectorPIDFn( 44 | pidFn func() (int, error), 45 | namespace string, 46 | ) Collector { 47 | c := processCollector{ 48 | pidFn: pidFn, 49 | collectFn: func(chan<- Metric) {}, 50 | 51 | cpuTotal: NewCounter(CounterOpts{ 52 | Namespace: namespace, 53 | Name: "process_cpu_seconds_total", 54 | Help: "Total user and system CPU time spent in seconds.", 55 | }), 56 | openFDs: NewGauge(GaugeOpts{ 57 | Namespace: namespace, 58 | Name: "process_open_fds", 59 | Help: "Number of open file descriptors.", 60 | }), 61 | maxFDs: NewGauge(GaugeOpts{ 62 | Namespace: namespace, 63 | Name: "process_max_fds", 64 | Help: "Maximum number of open file descriptors.", 65 | }), 66 | vsize: NewGauge(GaugeOpts{ 67 | Namespace: namespace, 68 | Name: "process_virtual_memory_bytes", 69 | Help: "Virtual memory size in bytes.", 70 | }), 71 | rss: NewGauge(GaugeOpts{ 72 | Namespace: namespace, 73 | Name: "process_resident_memory_bytes", 74 | Help: "Resident memory size in bytes.", 75 | }), 76 | startTime: NewGauge(GaugeOpts{ 77 | Namespace: namespace, 78 | Name: "process_start_time_seconds", 79 | Help: "Start time of the process since unix epoch in seconds.", 80 | }), 81 | } 82 | 83 | // Set up process metric collection if supported by the runtime. 84 | if _, err := procfs.NewStat(); err == nil { 85 | c.collectFn = c.processCollect 86 | } 87 | 88 | return &c 89 | } 90 | 91 | // Describe returns all descriptions of the collector. 92 | func (c *processCollector) Describe(ch chan<- *Desc) { 93 | ch <- c.cpuTotal.Desc() 94 | ch <- c.openFDs.Desc() 95 | ch <- c.maxFDs.Desc() 96 | ch <- c.vsize.Desc() 97 | ch <- c.rss.Desc() 98 | ch <- c.startTime.Desc() 99 | } 100 | 101 | // Collect returns the current state of all metrics of the collector. 102 | func (c *processCollector) Collect(ch chan<- Metric) { 103 | c.collectFn(ch) 104 | } 105 | 106 | // TODO(ts): Bring back error reporting by reverting 7faf9e7 as soon as the 107 | // client allows users to configure the error behavior. 108 | func (c *processCollector) processCollect(ch chan<- Metric) { 109 | pid, err := c.pidFn() 110 | if err != nil { 111 | return 112 | } 113 | 114 | p, err := procfs.NewProc(pid) 115 | if err != nil { 116 | return 117 | } 118 | 119 | if stat, err := p.NewStat(); err == nil { 120 | c.cpuTotal.Set(stat.CPUTime()) 121 | ch <- c.cpuTotal 122 | c.vsize.Set(float64(stat.VirtualMemory())) 123 | ch <- c.vsize 124 | c.rss.Set(float64(stat.ResidentMemory())) 125 | ch <- c.rss 126 | 127 | if startTime, err := stat.StartTime(); err == nil { 128 | c.startTime.Set(startTime) 129 | ch <- c.startTime 130 | } 131 | } 132 | 133 | if fds, err := p.FileDescriptorsLen(); err == nil { 134 | c.openFDs.Set(float64(fds)) 135 | ch <- c.openFDs 136 | } 137 | 138 | if limits, err := p.NewLimits(); err == nil { 139 | c.maxFDs.Set(float64(limits.OpenFiles)) 140 | ch <- c.maxFDs 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/mdstat.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package procfs 15 | 16 | import ( 17 | "fmt" 18 | "io/ioutil" 19 | "regexp" 20 | "strconv" 21 | "strings" 22 | ) 23 | 24 | var ( 25 | statuslineRE = regexp.MustCompile(`(\d+) blocks .*\[(\d+)/(\d+)\] \[[U_]+\]`) 26 | buildlineRE = regexp.MustCompile(`\((\d+)/\d+\)`) 27 | ) 28 | 29 | // MDStat holds info parsed from /proc/mdstat. 30 | type MDStat struct { 31 | // Name of the device. 32 | Name string 33 | // activity-state of the device. 34 | ActivityState string 35 | // Number of active disks. 36 | DisksActive int64 37 | // Total number of disks the device consists of. 38 | DisksTotal int64 39 | // Number of blocks the device holds. 40 | BlocksTotal int64 41 | // Number of blocks on the device that are in sync. 42 | BlocksSynced int64 43 | } 44 | 45 | // ParseMDStat parses an mdstat-file and returns a struct with the relevant infos. 46 | func (fs FS) ParseMDStat() (mdstates []MDStat, err error) { 47 | mdStatusFilePath := fs.Path("mdstat") 48 | content, err := ioutil.ReadFile(mdStatusFilePath) 49 | if err != nil { 50 | return []MDStat{}, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err) 51 | } 52 | 53 | mdStates := []MDStat{} 54 | lines := strings.Split(string(content), "\n") 55 | for i, l := range lines { 56 | if l == "" { 57 | continue 58 | } 59 | if l[0] == ' ' { 60 | continue 61 | } 62 | if strings.HasPrefix(l, "Personalities") || strings.HasPrefix(l, "unused") { 63 | continue 64 | } 65 | 66 | mainLine := strings.Split(l, " ") 67 | if len(mainLine) < 3 { 68 | return mdStates, fmt.Errorf("error parsing mdline: %s", l) 69 | } 70 | mdName := mainLine[0] 71 | activityState := mainLine[2] 72 | 73 | if len(lines) <= i+3 { 74 | return mdStates, fmt.Errorf( 75 | "error parsing %s: too few lines for md device %s", 76 | mdStatusFilePath, 77 | mdName, 78 | ) 79 | } 80 | 81 | active, total, size, err := evalStatusline(lines[i+1]) 82 | if err != nil { 83 | return mdStates, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err) 84 | } 85 | 86 | // j is the line number of the syncing-line. 87 | j := i + 2 88 | if strings.Contains(lines[i+2], "bitmap") { // skip bitmap line 89 | j = i + 3 90 | } 91 | 92 | // If device is syncing at the moment, get the number of currently 93 | // synced bytes, otherwise that number equals the size of the device. 94 | syncedBlocks := size 95 | if strings.Contains(lines[j], "recovery") || strings.Contains(lines[j], "resync") { 96 | syncedBlocks, err = evalBuildline(lines[j]) 97 | if err != nil { 98 | return mdStates, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err) 99 | } 100 | } 101 | 102 | mdStates = append(mdStates, MDStat{ 103 | Name: mdName, 104 | ActivityState: activityState, 105 | DisksActive: active, 106 | DisksTotal: total, 107 | BlocksTotal: size, 108 | BlocksSynced: syncedBlocks, 109 | }) 110 | } 111 | 112 | return mdStates, nil 113 | } 114 | 115 | func evalStatusline(statusline string) (active, total, size int64, err error) { 116 | matches := statuslineRE.FindStringSubmatch(statusline) 117 | if len(matches) != 4 { 118 | return 0, 0, 0, fmt.Errorf("unexpected statusline: %s", statusline) 119 | } 120 | 121 | size, err = strconv.ParseInt(matches[1], 10, 64) 122 | if err != nil { 123 | return 0, 0, 0, fmt.Errorf("unexpected statusline %s: %s", statusline, err) 124 | } 125 | 126 | total, err = strconv.ParseInt(matches[2], 10, 64) 127 | if err != nil { 128 | return 0, 0, 0, fmt.Errorf("unexpected statusline %s: %s", statusline, err) 129 | } 130 | 131 | active, err = strconv.ParseInt(matches[3], 10, 64) 132 | if err != nil { 133 | return 0, 0, 0, fmt.Errorf("unexpected statusline %s: %s", statusline, err) 134 | } 135 | 136 | return active, total, size, nil 137 | } 138 | 139 | func evalBuildline(buildline string) (syncedBlocks int64, err error) { 140 | matches := buildlineRE.FindStringSubmatch(buildline) 141 | if len(matches) != 2 { 142 | return 0, fmt.Errorf("unexpected buildline: %s", buildline) 143 | } 144 | 145 | syncedBlocks, err = strconv.ParseInt(matches[1], 10, 64) 146 | if err != nil { 147 | return 0, fmt.Errorf("%s in buildline: %s", err, buildline) 148 | } 149 | 150 | return syncedBlocks, nil 151 | } 152 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/model/labelset.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package model 15 | 16 | import ( 17 | "encoding/json" 18 | "fmt" 19 | "sort" 20 | "strings" 21 | ) 22 | 23 | // A LabelSet is a collection of LabelName and LabelValue pairs. The LabelSet 24 | // may be fully-qualified down to the point where it may resolve to a single 25 | // Metric in the data store or not. All operations that occur within the realm 26 | // of a LabelSet can emit a vector of Metric entities to which the LabelSet may 27 | // match. 28 | type LabelSet map[LabelName]LabelValue 29 | 30 | // Validate checks whether all names and values in the label set 31 | // are valid. 32 | func (ls LabelSet) Validate() error { 33 | for ln, lv := range ls { 34 | if !ln.IsValid() { 35 | return fmt.Errorf("invalid name %q", ln) 36 | } 37 | if !lv.IsValid() { 38 | return fmt.Errorf("invalid value %q", lv) 39 | } 40 | } 41 | return nil 42 | } 43 | 44 | // Equal returns true iff both label sets have exactly the same key/value pairs. 45 | func (ls LabelSet) Equal(o LabelSet) bool { 46 | if len(ls) != len(o) { 47 | return false 48 | } 49 | for ln, lv := range ls { 50 | olv, ok := o[ln] 51 | if !ok { 52 | return false 53 | } 54 | if olv != lv { 55 | return false 56 | } 57 | } 58 | return true 59 | } 60 | 61 | // Before compares the metrics, using the following criteria: 62 | // 63 | // If m has fewer labels than o, it is before o. If it has more, it is not. 64 | // 65 | // If the number of labels is the same, the superset of all label names is 66 | // sorted alphanumerically. The first differing label pair found in that order 67 | // determines the outcome: If the label does not exist at all in m, then m is 68 | // before o, and vice versa. Otherwise the label value is compared 69 | // alphanumerically. 70 | // 71 | // If m and o are equal, the method returns false. 72 | func (ls LabelSet) Before(o LabelSet) bool { 73 | if len(ls) < len(o) { 74 | return true 75 | } 76 | if len(ls) > len(o) { 77 | return false 78 | } 79 | 80 | lns := make(LabelNames, 0, len(ls)+len(o)) 81 | for ln := range ls { 82 | lns = append(lns, ln) 83 | } 84 | for ln := range o { 85 | lns = append(lns, ln) 86 | } 87 | // It's probably not worth it to de-dup lns. 88 | sort.Sort(lns) 89 | for _, ln := range lns { 90 | mlv, ok := ls[ln] 91 | if !ok { 92 | return true 93 | } 94 | olv, ok := o[ln] 95 | if !ok { 96 | return false 97 | } 98 | if mlv < olv { 99 | return true 100 | } 101 | if mlv > olv { 102 | return false 103 | } 104 | } 105 | return false 106 | } 107 | 108 | // Clone returns a copy of the label set. 109 | func (ls LabelSet) Clone() LabelSet { 110 | lsn := make(LabelSet, len(ls)) 111 | for ln, lv := range ls { 112 | lsn[ln] = lv 113 | } 114 | return lsn 115 | } 116 | 117 | // Merge is a helper function to non-destructively merge two label sets. 118 | func (l LabelSet) Merge(other LabelSet) LabelSet { 119 | result := make(LabelSet, len(l)) 120 | 121 | for k, v := range l { 122 | result[k] = v 123 | } 124 | 125 | for k, v := range other { 126 | result[k] = v 127 | } 128 | 129 | return result 130 | } 131 | 132 | func (l LabelSet) String() string { 133 | lstrs := make([]string, 0, len(l)) 134 | for l, v := range l { 135 | lstrs = append(lstrs, fmt.Sprintf("%s=%q", l, v)) 136 | } 137 | 138 | sort.Strings(lstrs) 139 | return fmt.Sprintf("{%s}", strings.Join(lstrs, ", ")) 140 | } 141 | 142 | // Fingerprint returns the LabelSet's fingerprint. 143 | func (ls LabelSet) Fingerprint() Fingerprint { 144 | return labelSetToFingerprint(ls) 145 | } 146 | 147 | // FastFingerprint returns the LabelSet's Fingerprint calculated by a faster hashing 148 | // algorithm, which is, however, more susceptible to hash collisions. 149 | func (ls LabelSet) FastFingerprint() Fingerprint { 150 | return labelSetToFastFingerprint(ls) 151 | } 152 | 153 | // UnmarshalJSON implements the json.Unmarshaler interface. 154 | func (l *LabelSet) UnmarshalJSON(b []byte) error { 155 | var m map[LabelName]LabelValue 156 | if err := json.Unmarshal(b, &m); err != nil { 157 | return err 158 | } 159 | // encoding/json only unmarshals maps of the form map[string]T. It treats 160 | // LabelName as a string and does not call its UnmarshalJSON method. 161 | // Thus, we have to replicate the behavior here. 162 | for ln := range m { 163 | if !ln.IsValid() { 164 | return fmt.Errorf("%q is not a valid label name", ln) 165 | } 166 | } 167 | *l = LabelSet(m) 168 | return nil 169 | } 170 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/autoneg.go: -------------------------------------------------------------------------------- 1 | /* 2 | HTTP Content-Type Autonegotiation. 3 | 4 | The functions in this package implement the behaviour specified in 5 | http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html 6 | 7 | Copyright (c) 2011, Open Knowledge Foundation Ltd. 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions are 12 | met: 13 | 14 | Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | 17 | Redistributions in binary form must reproduce the above copyright 18 | notice, this list of conditions and the following disclaimer in 19 | the documentation and/or other materials provided with the 20 | distribution. 21 | 22 | Neither the name of the Open Knowledge Foundation Ltd. nor the 23 | names of its contributors may be used to endorse or promote 24 | products derived from this software without specific prior written 25 | permission. 26 | 27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 28 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 29 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 30 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 31 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 32 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 33 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 34 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 35 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 37 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | 39 | 40 | */ 41 | package goautoneg 42 | 43 | import ( 44 | "sort" 45 | "strconv" 46 | "strings" 47 | ) 48 | 49 | // Structure to represent a clause in an HTTP Accept Header 50 | type Accept struct { 51 | Type, SubType string 52 | Q float64 53 | Params map[string]string 54 | } 55 | 56 | // For internal use, so that we can use the sort interface 57 | type accept_slice []Accept 58 | 59 | func (accept accept_slice) Len() int { 60 | slice := []Accept(accept) 61 | return len(slice) 62 | } 63 | 64 | func (accept accept_slice) Less(i, j int) bool { 65 | slice := []Accept(accept) 66 | ai, aj := slice[i], slice[j] 67 | if ai.Q > aj.Q { 68 | return true 69 | } 70 | if ai.Type != "*" && aj.Type == "*" { 71 | return true 72 | } 73 | if ai.SubType != "*" && aj.SubType == "*" { 74 | return true 75 | } 76 | return false 77 | } 78 | 79 | func (accept accept_slice) Swap(i, j int) { 80 | slice := []Accept(accept) 81 | slice[i], slice[j] = slice[j], slice[i] 82 | } 83 | 84 | // Parse an Accept Header string returning a sorted list 85 | // of clauses 86 | func ParseAccept(header string) (accept []Accept) { 87 | parts := strings.Split(header, ",") 88 | accept = make([]Accept, 0, len(parts)) 89 | for _, part := range parts { 90 | part := strings.Trim(part, " ") 91 | 92 | a := Accept{} 93 | a.Params = make(map[string]string) 94 | a.Q = 1.0 95 | 96 | mrp := strings.Split(part, ";") 97 | 98 | media_range := mrp[0] 99 | sp := strings.Split(media_range, "/") 100 | a.Type = strings.Trim(sp[0], " ") 101 | 102 | switch { 103 | case len(sp) == 1 && a.Type == "*": 104 | a.SubType = "*" 105 | case len(sp) == 2: 106 | a.SubType = strings.Trim(sp[1], " ") 107 | default: 108 | continue 109 | } 110 | 111 | if len(mrp) == 1 { 112 | accept = append(accept, a) 113 | continue 114 | } 115 | 116 | for _, param := range mrp[1:] { 117 | sp := strings.SplitN(param, "=", 2) 118 | if len(sp) != 2 { 119 | continue 120 | } 121 | token := strings.Trim(sp[0], " ") 122 | if token == "q" { 123 | a.Q, _ = strconv.ParseFloat(sp[1], 32) 124 | } else { 125 | a.Params[token] = strings.Trim(sp[1], " ") 126 | } 127 | } 128 | 129 | accept = append(accept, a) 130 | } 131 | 132 | slice := accept_slice(accept) 133 | sort.Sort(slice) 134 | 135 | return 136 | } 137 | 138 | // Negotiate the most appropriate content_type given the accept header 139 | // and a list of alternatives. 140 | func Negotiate(header string, alternatives []string) (content_type string) { 141 | asp := make([][]string, 0, len(alternatives)) 142 | for _, ctype := range alternatives { 143 | asp = append(asp, strings.SplitN(ctype, "/", 2)) 144 | } 145 | for _, clause := range ParseAccept(header) { 146 | for i, ctsp := range asp { 147 | if clause.Type == ctsp[0] && clause.SubType == ctsp[1] { 148 | content_type = alternatives[i] 149 | return 150 | } 151 | if clause.Type == ctsp[0] && clause.SubType == "*" { 152 | content_type = alternatives[i] 153 | return 154 | } 155 | if clause.Type == "*" && clause.SubType == "*" { 156 | content_type = alternatives[i] 157 | return 158 | } 159 | } 160 | } 161 | return 162 | } 163 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/model/signature.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package model 15 | 16 | import ( 17 | "sort" 18 | ) 19 | 20 | // SeparatorByte is a byte that cannot occur in valid UTF-8 sequences and is 21 | // used to separate label names, label values, and other strings from each other 22 | // when calculating their combined hash value (aka signature aka fingerprint). 23 | const SeparatorByte byte = 255 24 | 25 | var ( 26 | // cache the signature of an empty label set. 27 | emptyLabelSignature = hashNew() 28 | ) 29 | 30 | // LabelsToSignature returns a quasi-unique signature (i.e., fingerprint) for a 31 | // given label set. (Collisions are possible but unlikely if the number of label 32 | // sets the function is applied to is small.) 33 | func LabelsToSignature(labels map[string]string) uint64 { 34 | if len(labels) == 0 { 35 | return emptyLabelSignature 36 | } 37 | 38 | labelNames := make([]string, 0, len(labels)) 39 | for labelName := range labels { 40 | labelNames = append(labelNames, labelName) 41 | } 42 | sort.Strings(labelNames) 43 | 44 | sum := hashNew() 45 | for _, labelName := range labelNames { 46 | sum = hashAdd(sum, labelName) 47 | sum = hashAddByte(sum, SeparatorByte) 48 | sum = hashAdd(sum, labels[labelName]) 49 | sum = hashAddByte(sum, SeparatorByte) 50 | } 51 | return sum 52 | } 53 | 54 | // labelSetToFingerprint works exactly as LabelsToSignature but takes a LabelSet as 55 | // parameter (rather than a label map) and returns a Fingerprint. 56 | func labelSetToFingerprint(ls LabelSet) Fingerprint { 57 | if len(ls) == 0 { 58 | return Fingerprint(emptyLabelSignature) 59 | } 60 | 61 | labelNames := make(LabelNames, 0, len(ls)) 62 | for labelName := range ls { 63 | labelNames = append(labelNames, labelName) 64 | } 65 | sort.Sort(labelNames) 66 | 67 | sum := hashNew() 68 | for _, labelName := range labelNames { 69 | sum = hashAdd(sum, string(labelName)) 70 | sum = hashAddByte(sum, SeparatorByte) 71 | sum = hashAdd(sum, string(ls[labelName])) 72 | sum = hashAddByte(sum, SeparatorByte) 73 | } 74 | return Fingerprint(sum) 75 | } 76 | 77 | // labelSetToFastFingerprint works similar to labelSetToFingerprint but uses a 78 | // faster and less allocation-heavy hash function, which is more susceptible to 79 | // create hash collisions. Therefore, collision detection should be applied. 80 | func labelSetToFastFingerprint(ls LabelSet) Fingerprint { 81 | if len(ls) == 0 { 82 | return Fingerprint(emptyLabelSignature) 83 | } 84 | 85 | var result uint64 86 | for labelName, labelValue := range ls { 87 | sum := hashNew() 88 | sum = hashAdd(sum, string(labelName)) 89 | sum = hashAddByte(sum, SeparatorByte) 90 | sum = hashAdd(sum, string(labelValue)) 91 | result ^= sum 92 | } 93 | return Fingerprint(result) 94 | } 95 | 96 | // SignatureForLabels works like LabelsToSignature but takes a Metric as 97 | // parameter (rather than a label map) and only includes the labels with the 98 | // specified LabelNames into the signature calculation. The labels passed in 99 | // will be sorted by this function. 100 | func SignatureForLabels(m Metric, labels ...LabelName) uint64 { 101 | if len(labels) == 0 { 102 | return emptyLabelSignature 103 | } 104 | 105 | sort.Sort(LabelNames(labels)) 106 | 107 | sum := hashNew() 108 | for _, label := range labels { 109 | sum = hashAdd(sum, string(label)) 110 | sum = hashAddByte(sum, SeparatorByte) 111 | sum = hashAdd(sum, string(m[label])) 112 | sum = hashAddByte(sum, SeparatorByte) 113 | } 114 | return sum 115 | } 116 | 117 | // SignatureWithoutLabels works like LabelsToSignature but takes a Metric as 118 | // parameter (rather than a label map) and excludes the labels with any of the 119 | // specified LabelNames from the signature calculation. 120 | func SignatureWithoutLabels(m Metric, labels map[LabelName]struct{}) uint64 { 121 | if len(m) == 0 { 122 | return emptyLabelSignature 123 | } 124 | 125 | labelNames := make(LabelNames, 0, len(m)) 126 | for labelName := range m { 127 | if _, exclude := labels[labelName]; !exclude { 128 | labelNames = append(labelNames, labelName) 129 | } 130 | } 131 | if len(labelNames) == 0 { 132 | return emptyLabelSignature 133 | } 134 | sort.Sort(labelNames) 135 | 136 | sum := hashNew() 137 | for _, labelName := range labelNames { 138 | sum = hashAdd(sum, string(labelName)) 139 | sum = hashAddByte(sum, SeparatorByte) 140 | sum = hashAdd(sum, string(m[labelName])) 141 | sum = hashAddByte(sum, SeparatorByte) 142 | } 143 | return sum 144 | } 145 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/proc_limits.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package procfs 15 | 16 | import ( 17 | "bufio" 18 | "fmt" 19 | "os" 20 | "regexp" 21 | "strconv" 22 | ) 23 | 24 | // ProcLimits represents the soft limits for each of the process's resource 25 | // limits. For more information see getrlimit(2): 26 | // http://man7.org/linux/man-pages/man2/getrlimit.2.html. 27 | type ProcLimits struct { 28 | // CPU time limit in seconds. 29 | CPUTime int64 30 | // Maximum size of files that the process may create. 31 | FileSize int64 32 | // Maximum size of the process's data segment (initialized data, 33 | // uninitialized data, and heap). 34 | DataSize int64 35 | // Maximum size of the process stack in bytes. 36 | StackSize int64 37 | // Maximum size of a core file. 38 | CoreFileSize int64 39 | // Limit of the process's resident set in pages. 40 | ResidentSet int64 41 | // Maximum number of processes that can be created for the real user ID of 42 | // the calling process. 43 | Processes int64 44 | // Value one greater than the maximum file descriptor number that can be 45 | // opened by this process. 46 | OpenFiles int64 47 | // Maximum number of bytes of memory that may be locked into RAM. 48 | LockedMemory int64 49 | // Maximum size of the process's virtual memory address space in bytes. 50 | AddressSpace int64 51 | // Limit on the combined number of flock(2) locks and fcntl(2) leases that 52 | // this process may establish. 53 | FileLocks int64 54 | // Limit of signals that may be queued for the real user ID of the calling 55 | // process. 56 | PendingSignals int64 57 | // Limit on the number of bytes that can be allocated for POSIX message 58 | // queues for the real user ID of the calling process. 59 | MsqqueueSize int64 60 | // Limit of the nice priority set using setpriority(2) or nice(2). 61 | NicePriority int64 62 | // Limit of the real-time priority set using sched_setscheduler(2) or 63 | // sched_setparam(2). 64 | RealtimePriority int64 65 | // Limit (in microseconds) on the amount of CPU time that a process 66 | // scheduled under a real-time scheduling policy may consume without making 67 | // a blocking system call. 68 | RealtimeTimeout int64 69 | } 70 | 71 | const ( 72 | limitsFields = 3 73 | limitsUnlimited = "unlimited" 74 | ) 75 | 76 | var ( 77 | limitsDelimiter = regexp.MustCompile(" +") 78 | ) 79 | 80 | // NewLimits returns the current soft limits of the process. 81 | func (p Proc) NewLimits() (ProcLimits, error) { 82 | f, err := os.Open(p.path("limits")) 83 | if err != nil { 84 | return ProcLimits{}, err 85 | } 86 | defer f.Close() 87 | 88 | var ( 89 | l = ProcLimits{} 90 | s = bufio.NewScanner(f) 91 | ) 92 | for s.Scan() { 93 | fields := limitsDelimiter.Split(s.Text(), limitsFields) 94 | if len(fields) != limitsFields { 95 | return ProcLimits{}, fmt.Errorf( 96 | "couldn't parse %s line %s", f.Name(), s.Text()) 97 | } 98 | 99 | switch fields[0] { 100 | case "Max cpu time": 101 | l.CPUTime, err = parseInt(fields[1]) 102 | case "Max file size": 103 | l.FileSize, err = parseInt(fields[1]) 104 | case "Max data size": 105 | l.DataSize, err = parseInt(fields[1]) 106 | case "Max stack size": 107 | l.StackSize, err = parseInt(fields[1]) 108 | case "Max core file size": 109 | l.CoreFileSize, err = parseInt(fields[1]) 110 | case "Max resident set": 111 | l.ResidentSet, err = parseInt(fields[1]) 112 | case "Max processes": 113 | l.Processes, err = parseInt(fields[1]) 114 | case "Max open files": 115 | l.OpenFiles, err = parseInt(fields[1]) 116 | case "Max locked memory": 117 | l.LockedMemory, err = parseInt(fields[1]) 118 | case "Max address space": 119 | l.AddressSpace, err = parseInt(fields[1]) 120 | case "Max file locks": 121 | l.FileLocks, err = parseInt(fields[1]) 122 | case "Max pending signals": 123 | l.PendingSignals, err = parseInt(fields[1]) 124 | case "Max msgqueue size": 125 | l.MsqqueueSize, err = parseInt(fields[1]) 126 | case "Max nice priority": 127 | l.NicePriority, err = parseInt(fields[1]) 128 | case "Max realtime priority": 129 | l.RealtimePriority, err = parseInt(fields[1]) 130 | case "Max realtime timeout": 131 | l.RealtimeTimeout, err = parseInt(fields[1]) 132 | } 133 | if err != nil { 134 | return ProcLimits{}, err 135 | } 136 | } 137 | 138 | return l, s.Err() 139 | } 140 | 141 | func parseInt(s string) (int64, error) { 142 | if s == limitsUnlimited { 143 | return -1, nil 144 | } 145 | i, err := strconv.ParseInt(s, 10, 64) 146 | if err != nil { 147 | return 0, fmt.Errorf("couldn't parse value %s: %s", s, err) 148 | } 149 | return i, nil 150 | } 151 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/xfs/xfs.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // Package xfs provides access to statistics exposed by the XFS filesystem. 15 | package xfs 16 | 17 | // Stats contains XFS filesystem runtime statistics, parsed from 18 | // /proc/fs/xfs/stat. 19 | // 20 | // The names and meanings of each statistic were taken from 21 | // http://xfs.org/index.php/Runtime_Stats and xfs_stats.h in the Linux 22 | // kernel source. Most counters are uint32s (same data types used in 23 | // xfs_stats.h), but some of the "extended precision stats" are uint64s. 24 | type Stats struct { 25 | // The name of the filesystem used to source these statistics. 26 | // If empty, this indicates aggregated statistics for all XFS 27 | // filesystems on the host. 28 | Name string 29 | 30 | ExtentAllocation ExtentAllocationStats 31 | AllocationBTree BTreeStats 32 | BlockMapping BlockMappingStats 33 | BlockMapBTree BTreeStats 34 | DirectoryOperation DirectoryOperationStats 35 | Transaction TransactionStats 36 | InodeOperation InodeOperationStats 37 | LogOperation LogOperationStats 38 | ReadWrite ReadWriteStats 39 | AttributeOperation AttributeOperationStats 40 | InodeClustering InodeClusteringStats 41 | Vnode VnodeStats 42 | Buffer BufferStats 43 | ExtendedPrecision ExtendedPrecisionStats 44 | } 45 | 46 | // ExtentAllocationStats contains statistics regarding XFS extent allocations. 47 | type ExtentAllocationStats struct { 48 | ExtentsAllocated uint32 49 | BlocksAllocated uint32 50 | ExtentsFreed uint32 51 | BlocksFreed uint32 52 | } 53 | 54 | // BTreeStats contains statistics regarding an XFS internal B-tree. 55 | type BTreeStats struct { 56 | Lookups uint32 57 | Compares uint32 58 | RecordsInserted uint32 59 | RecordsDeleted uint32 60 | } 61 | 62 | // BlockMappingStats contains statistics regarding XFS block maps. 63 | type BlockMappingStats struct { 64 | Reads uint32 65 | Writes uint32 66 | Unmaps uint32 67 | ExtentListInsertions uint32 68 | ExtentListDeletions uint32 69 | ExtentListLookups uint32 70 | ExtentListCompares uint32 71 | } 72 | 73 | // DirectoryOperationStats contains statistics regarding XFS directory entries. 74 | type DirectoryOperationStats struct { 75 | Lookups uint32 76 | Creates uint32 77 | Removes uint32 78 | Getdents uint32 79 | } 80 | 81 | // TransactionStats contains statistics regarding XFS metadata transactions. 82 | type TransactionStats struct { 83 | Sync uint32 84 | Async uint32 85 | Empty uint32 86 | } 87 | 88 | // InodeOperationStats contains statistics regarding XFS inode operations. 89 | type InodeOperationStats struct { 90 | Attempts uint32 91 | Found uint32 92 | Recycle uint32 93 | Missed uint32 94 | Duplicate uint32 95 | Reclaims uint32 96 | AttributeChange uint32 97 | } 98 | 99 | // LogOperationStats contains statistics regarding the XFS log buffer. 100 | type LogOperationStats struct { 101 | Writes uint32 102 | Blocks uint32 103 | NoInternalBuffers uint32 104 | Force uint32 105 | ForceSleep uint32 106 | } 107 | 108 | // ReadWriteStats contains statistics regarding the number of read and write 109 | // system calls for XFS filesystems. 110 | type ReadWriteStats struct { 111 | Read uint32 112 | Write uint32 113 | } 114 | 115 | // AttributeOperationStats contains statistics regarding manipulation of 116 | // XFS extended file attributes. 117 | type AttributeOperationStats struct { 118 | Get uint32 119 | Set uint32 120 | Remove uint32 121 | List uint32 122 | } 123 | 124 | // InodeClusteringStats contains statistics regarding XFS inode clustering 125 | // operations. 126 | type InodeClusteringStats struct { 127 | Iflush uint32 128 | Flush uint32 129 | FlushInode uint32 130 | } 131 | 132 | // VnodeStats contains statistics regarding XFS vnode operations. 133 | type VnodeStats struct { 134 | Active uint32 135 | Allocate uint32 136 | Get uint32 137 | Hold uint32 138 | Release uint32 139 | Reclaim uint32 140 | Remove uint32 141 | Free uint32 142 | } 143 | 144 | // BufferStats contains statistics regarding XFS read/write I/O buffers. 145 | type BufferStats struct { 146 | Get uint32 147 | Create uint32 148 | GetLocked uint32 149 | GetLockedWaited uint32 150 | BusyLocked uint32 151 | MissLocked uint32 152 | PageRetries uint32 153 | PageFound uint32 154 | GetRead uint32 155 | } 156 | 157 | // ExtendedPrecisionStats contains high precision counters used to track the 158 | // total number of bytes read, written, or flushed, during XFS operations. 159 | type ExtendedPrecisionStats struct { 160 | FlushBytes uint64 161 | WriteBytes uint64 162 | ReadBytes uint64 163 | } 164 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_golang/prometheus/untyped.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package prometheus 15 | 16 | // Untyped is a Metric that represents a single numerical value that can 17 | // arbitrarily go up and down. 18 | // 19 | // An Untyped metric works the same as a Gauge. The only difference is that to 20 | // no type information is implied. 21 | // 22 | // To create Untyped instances, use NewUntyped. 23 | type Untyped interface { 24 | Metric 25 | Collector 26 | 27 | // Set sets the Untyped metric to an arbitrary value. 28 | Set(float64) 29 | // Inc increments the Untyped metric by 1. 30 | Inc() 31 | // Dec decrements the Untyped metric by 1. 32 | Dec() 33 | // Add adds the given value to the Untyped metric. (The value can be 34 | // negative, resulting in a decrease.) 35 | Add(float64) 36 | // Sub subtracts the given value from the Untyped metric. (The value can 37 | // be negative, resulting in an increase.) 38 | Sub(float64) 39 | } 40 | 41 | // UntypedOpts is an alias for Opts. See there for doc comments. 42 | type UntypedOpts Opts 43 | 44 | // NewUntyped creates a new Untyped metric from the provided UntypedOpts. 45 | func NewUntyped(opts UntypedOpts) Untyped { 46 | return newValue(NewDesc( 47 | BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), 48 | opts.Help, 49 | nil, 50 | opts.ConstLabels, 51 | ), UntypedValue, 0) 52 | } 53 | 54 | // UntypedVec is a Collector that bundles a set of Untyped metrics that all 55 | // share the same Desc, but have different values for their variable 56 | // labels. This is used if you want to count the same thing partitioned by 57 | // various dimensions. Create instances with NewUntypedVec. 58 | type UntypedVec struct { 59 | *MetricVec 60 | } 61 | 62 | // NewUntypedVec creates a new UntypedVec based on the provided UntypedOpts and 63 | // partitioned by the given label names. At least one label name must be 64 | // provided. 65 | func NewUntypedVec(opts UntypedOpts, labelNames []string) *UntypedVec { 66 | desc := NewDesc( 67 | BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), 68 | opts.Help, 69 | labelNames, 70 | opts.ConstLabels, 71 | ) 72 | return &UntypedVec{ 73 | MetricVec: newMetricVec(desc, func(lvs ...string) Metric { 74 | return newValue(desc, UntypedValue, 0, lvs...) 75 | }), 76 | } 77 | } 78 | 79 | // GetMetricWithLabelValues replaces the method of the same name in 80 | // MetricVec. The difference is that this method returns an Untyped and not a 81 | // Metric so that no type conversion is required. 82 | func (m *UntypedVec) GetMetricWithLabelValues(lvs ...string) (Untyped, error) { 83 | metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...) 84 | if metric != nil { 85 | return metric.(Untyped), err 86 | } 87 | return nil, err 88 | } 89 | 90 | // GetMetricWith replaces the method of the same name in MetricVec. The 91 | // difference is that this method returns an Untyped and not a Metric so that no 92 | // type conversion is required. 93 | func (m *UntypedVec) GetMetricWith(labels Labels) (Untyped, error) { 94 | metric, err := m.MetricVec.GetMetricWith(labels) 95 | if metric != nil { 96 | return metric.(Untyped), err 97 | } 98 | return nil, err 99 | } 100 | 101 | // WithLabelValues works as GetMetricWithLabelValues, but panics where 102 | // GetMetricWithLabelValues would have returned an error. By not returning an 103 | // error, WithLabelValues allows shortcuts like 104 | // myVec.WithLabelValues("404", "GET").Add(42) 105 | func (m *UntypedVec) WithLabelValues(lvs ...string) Untyped { 106 | return m.MetricVec.WithLabelValues(lvs...).(Untyped) 107 | } 108 | 109 | // With works as GetMetricWith, but panics where GetMetricWithLabels would have 110 | // returned an error. By not returning an error, With allows shortcuts like 111 | // myVec.With(Labels{"code": "404", "method": "GET"}).Add(42) 112 | func (m *UntypedVec) With(labels Labels) Untyped { 113 | return m.MetricVec.With(labels).(Untyped) 114 | } 115 | 116 | // UntypedFunc is an Untyped whose value is determined at collect time by 117 | // calling a provided function. 118 | // 119 | // To create UntypedFunc instances, use NewUntypedFunc. 120 | type UntypedFunc interface { 121 | Metric 122 | Collector 123 | } 124 | 125 | // NewUntypedFunc creates a new UntypedFunc based on the provided 126 | // UntypedOpts. The value reported is determined by calling the given function 127 | // from within the Write method. Take into account that metric collection may 128 | // happen concurrently. If that results in concurrent calls to Write, like in 129 | // the case where an UntypedFunc is directly registered with Prometheus, the 130 | // provided function must be concurrency-safe. 131 | func NewUntypedFunc(opts UntypedOpts, function func() float64) UntypedFunc { 132 | return newValueFunc(NewDesc( 133 | BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), 134 | opts.Help, 135 | nil, 136 | opts.ConstLabels, 137 | ), UntypedValue, function) 138 | } 139 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_golang/prometheus/gauge.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package prometheus 15 | 16 | // Gauge is a Metric that represents a single numerical value that can 17 | // arbitrarily go up and down. 18 | // 19 | // A Gauge is typically used for measured values like temperatures or current 20 | // memory usage, but also "counts" that can go up and down, like the number of 21 | // running goroutines. 22 | // 23 | // To create Gauge instances, use NewGauge. 24 | type Gauge interface { 25 | Metric 26 | Collector 27 | 28 | // Set sets the Gauge to an arbitrary value. 29 | Set(float64) 30 | // Inc increments the Gauge by 1. 31 | Inc() 32 | // Dec decrements the Gauge by 1. 33 | Dec() 34 | // Add adds the given value to the Gauge. (The value can be 35 | // negative, resulting in a decrease of the Gauge.) 36 | Add(float64) 37 | // Sub subtracts the given value from the Gauge. (The value can be 38 | // negative, resulting in an increase of the Gauge.) 39 | Sub(float64) 40 | } 41 | 42 | // GaugeOpts is an alias for Opts. See there for doc comments. 43 | type GaugeOpts Opts 44 | 45 | // NewGauge creates a new Gauge based on the provided GaugeOpts. 46 | func NewGauge(opts GaugeOpts) Gauge { 47 | return newValue(NewDesc( 48 | BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), 49 | opts.Help, 50 | nil, 51 | opts.ConstLabels, 52 | ), GaugeValue, 0) 53 | } 54 | 55 | // GaugeVec is a Collector that bundles a set of Gauges that all share the same 56 | // Desc, but have different values for their variable labels. This is used if 57 | // you want to count the same thing partitioned by various dimensions 58 | // (e.g. number of operations queued, partitioned by user and operation 59 | // type). Create instances with NewGaugeVec. 60 | type GaugeVec struct { 61 | *MetricVec 62 | } 63 | 64 | // NewGaugeVec creates a new GaugeVec based on the provided GaugeOpts and 65 | // partitioned by the given label names. At least one label name must be 66 | // provided. 67 | func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec { 68 | desc := NewDesc( 69 | BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), 70 | opts.Help, 71 | labelNames, 72 | opts.ConstLabels, 73 | ) 74 | return &GaugeVec{ 75 | MetricVec: newMetricVec(desc, func(lvs ...string) Metric { 76 | return newValue(desc, GaugeValue, 0, lvs...) 77 | }), 78 | } 79 | } 80 | 81 | // GetMetricWithLabelValues replaces the method of the same name in 82 | // MetricVec. The difference is that this method returns a Gauge and not a 83 | // Metric so that no type conversion is required. 84 | func (m *GaugeVec) GetMetricWithLabelValues(lvs ...string) (Gauge, error) { 85 | metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...) 86 | if metric != nil { 87 | return metric.(Gauge), err 88 | } 89 | return nil, err 90 | } 91 | 92 | // GetMetricWith replaces the method of the same name in MetricVec. The 93 | // difference is that this method returns a Gauge and not a Metric so that no 94 | // type conversion is required. 95 | func (m *GaugeVec) GetMetricWith(labels Labels) (Gauge, error) { 96 | metric, err := m.MetricVec.GetMetricWith(labels) 97 | if metric != nil { 98 | return metric.(Gauge), err 99 | } 100 | return nil, err 101 | } 102 | 103 | // WithLabelValues works as GetMetricWithLabelValues, but panics where 104 | // GetMetricWithLabelValues would have returned an error. By not returning an 105 | // error, WithLabelValues allows shortcuts like 106 | // myVec.WithLabelValues("404", "GET").Add(42) 107 | func (m *GaugeVec) WithLabelValues(lvs ...string) Gauge { 108 | return m.MetricVec.WithLabelValues(lvs...).(Gauge) 109 | } 110 | 111 | // With works as GetMetricWith, but panics where GetMetricWithLabels would have 112 | // returned an error. By not returning an error, With allows shortcuts like 113 | // myVec.With(Labels{"code": "404", "method": "GET"}).Add(42) 114 | func (m *GaugeVec) With(labels Labels) Gauge { 115 | return m.MetricVec.With(labels).(Gauge) 116 | } 117 | 118 | // GaugeFunc is a Gauge whose value is determined at collect time by calling a 119 | // provided function. 120 | // 121 | // To create GaugeFunc instances, use NewGaugeFunc. 122 | type GaugeFunc interface { 123 | Metric 124 | Collector 125 | } 126 | 127 | // NewGaugeFunc creates a new GaugeFunc based on the provided GaugeOpts. The 128 | // value reported is determined by calling the given function from within the 129 | // Write method. Take into account that metric collection may happen 130 | // concurrently. If that results in concurrent calls to Write, like in the case 131 | // where a GaugeFunc is directly registered with Prometheus, the provided 132 | // function must be concurrency-safe. 133 | func NewGaugeFunc(opts GaugeOpts, function func() float64) GaugeFunc { 134 | return newValueFunc(NewDesc( 135 | BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), 136 | opts.Help, 137 | nil, 138 | opts.ConstLabels, 139 | ), GaugeValue, function) 140 | } 141 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/xfrm.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Prometheus Team 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package procfs 15 | 16 | import ( 17 | "bufio" 18 | "fmt" 19 | "os" 20 | "strconv" 21 | "strings" 22 | ) 23 | 24 | // XfrmStat models the contents of /proc/net/xfrm_stat. 25 | type XfrmStat struct { 26 | // All errors which are not matched by other 27 | XfrmInError int 28 | // No buffer is left 29 | XfrmInBufferError int 30 | // Header Error 31 | XfrmInHdrError int 32 | // No state found 33 | // i.e. either inbound SPI, address, or IPSEC protocol at SA is wrong 34 | XfrmInNoStates int 35 | // Transformation protocol specific error 36 | // e.g. SA Key is wrong 37 | XfrmInStateProtoError int 38 | // Transformation mode specific error 39 | XfrmInStateModeError int 40 | // Sequence error 41 | // e.g. sequence number is out of window 42 | XfrmInStateSeqError int 43 | // State is expired 44 | XfrmInStateExpired int 45 | // State has mismatch option 46 | // e.g. UDP encapsulation type is mismatched 47 | XfrmInStateMismatch int 48 | // State is invalid 49 | XfrmInStateInvalid int 50 | // No matching template for states 51 | // e.g. Inbound SAs are correct but SP rule is wrong 52 | XfrmInTmplMismatch int 53 | // No policy is found for states 54 | // e.g. Inbound SAs are correct but no SP is found 55 | XfrmInNoPols int 56 | // Policy discards 57 | XfrmInPolBlock int 58 | // Policy error 59 | XfrmInPolError int 60 | // All errors which are not matched by others 61 | XfrmOutError int 62 | // Bundle generation error 63 | XfrmOutBundleGenError int 64 | // Bundle check error 65 | XfrmOutBundleCheckError int 66 | // No state was found 67 | XfrmOutNoStates int 68 | // Transformation protocol specific error 69 | XfrmOutStateProtoError int 70 | // Transportation mode specific error 71 | XfrmOutStateModeError int 72 | // Sequence error 73 | // i.e sequence number overflow 74 | XfrmOutStateSeqError int 75 | // State is expired 76 | XfrmOutStateExpired int 77 | // Policy discads 78 | XfrmOutPolBlock int 79 | // Policy is dead 80 | XfrmOutPolDead int 81 | // Policy Error 82 | XfrmOutPolError int 83 | XfrmFwdHdrError int 84 | XfrmOutStateInvalid int 85 | XfrmAcquireError int 86 | } 87 | 88 | // NewXfrmStat reads the xfrm_stat statistics. 89 | func NewXfrmStat() (XfrmStat, error) { 90 | fs, err := NewFS(DefaultMountPoint) 91 | if err != nil { 92 | return XfrmStat{}, err 93 | } 94 | 95 | return fs.NewXfrmStat() 96 | } 97 | 98 | // NewXfrmStat reads the xfrm_stat statistics from the 'proc' filesystem. 99 | func (fs FS) NewXfrmStat() (XfrmStat, error) { 100 | file, err := os.Open(fs.Path("net/xfrm_stat")) 101 | if err != nil { 102 | return XfrmStat{}, err 103 | } 104 | defer file.Close() 105 | 106 | var ( 107 | x = XfrmStat{} 108 | s = bufio.NewScanner(file) 109 | ) 110 | 111 | for s.Scan() { 112 | fields := strings.Fields(s.Text()) 113 | 114 | if len(fields) != 2 { 115 | return XfrmStat{}, fmt.Errorf( 116 | "couldnt parse %s line %s", file.Name(), s.Text()) 117 | } 118 | 119 | name := fields[0] 120 | value, err := strconv.Atoi(fields[1]) 121 | if err != nil { 122 | return XfrmStat{}, err 123 | } 124 | 125 | switch name { 126 | case "XfrmInError": 127 | x.XfrmInError = value 128 | case "XfrmInBufferError": 129 | x.XfrmInBufferError = value 130 | case "XfrmInHdrError": 131 | x.XfrmInHdrError = value 132 | case "XfrmInNoStates": 133 | x.XfrmInNoStates = value 134 | case "XfrmInStateProtoError": 135 | x.XfrmInStateProtoError = value 136 | case "XfrmInStateModeError": 137 | x.XfrmInStateModeError = value 138 | case "XfrmInStateSeqError": 139 | x.XfrmInStateSeqError = value 140 | case "XfrmInStateExpired": 141 | x.XfrmInStateExpired = value 142 | case "XfrmInStateInvalid": 143 | x.XfrmInStateInvalid = value 144 | case "XfrmInTmplMismatch": 145 | x.XfrmInTmplMismatch = value 146 | case "XfrmInNoPols": 147 | x.XfrmInNoPols = value 148 | case "XfrmInPolBlock": 149 | x.XfrmInPolBlock = value 150 | case "XfrmInPolError": 151 | x.XfrmInPolError = value 152 | case "XfrmOutError": 153 | x.XfrmOutError = value 154 | case "XfrmInStateMismatch": 155 | x.XfrmInStateMismatch = value 156 | case "XfrmOutBundleGenError": 157 | x.XfrmOutBundleGenError = value 158 | case "XfrmOutBundleCheckError": 159 | x.XfrmOutBundleCheckError = value 160 | case "XfrmOutNoStates": 161 | x.XfrmOutNoStates = value 162 | case "XfrmOutStateProtoError": 163 | x.XfrmOutStateProtoError = value 164 | case "XfrmOutStateModeError": 165 | x.XfrmOutStateModeError = value 166 | case "XfrmOutStateSeqError": 167 | x.XfrmOutStateSeqError = value 168 | case "XfrmOutStateExpired": 169 | x.XfrmOutStateExpired = value 170 | case "XfrmOutPolBlock": 171 | x.XfrmOutPolBlock = value 172 | case "XfrmOutPolDead": 173 | x.XfrmOutPolDead = value 174 | case "XfrmOutPolError": 175 | x.XfrmOutPolError = value 176 | case "XfrmFwdHdrError": 177 | x.XfrmFwdHdrError = value 178 | case "XfrmOutStateInvalid": 179 | x.XfrmOutStateInvalid = value 180 | case "XfrmAcquireError": 181 | x.XfrmAcquireError = value 182 | } 183 | 184 | } 185 | 186 | return x, s.Err() 187 | } 188 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/proc_stat.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package procfs 15 | 16 | import ( 17 | "bytes" 18 | "fmt" 19 | "io/ioutil" 20 | "os" 21 | ) 22 | 23 | // Originally, this USER_HZ value was dynamically retrieved via a sysconf call 24 | // which required cgo. However, that caused a lot of problems regarding 25 | // cross-compilation. Alternatives such as running a binary to determine the 26 | // value, or trying to derive it in some other way were all problematic. After 27 | // much research it was determined that USER_HZ is actually hardcoded to 100 on 28 | // all Go-supported platforms as of the time of this writing. This is why we 29 | // decided to hardcode it here as well. It is not impossible that there could 30 | // be systems with exceptions, but they should be very exotic edge cases, and 31 | // in that case, the worst outcome will be two misreported metrics. 32 | // 33 | // See also the following discussions: 34 | // 35 | // - https://github.com/prometheus/node_exporter/issues/52 36 | // - https://github.com/prometheus/procfs/pull/2 37 | // - http://stackoverflow.com/questions/17410841/how-does-user-hz-solve-the-jiffy-scaling-issue 38 | const userHZ = 100 39 | 40 | // ProcStat provides status information about the process, 41 | // read from /proc/[pid]/stat. 42 | type ProcStat struct { 43 | // The process ID. 44 | PID int 45 | // The filename of the executable. 46 | Comm string 47 | // The process state. 48 | State string 49 | // The PID of the parent of this process. 50 | PPID int 51 | // The process group ID of the process. 52 | PGRP int 53 | // The session ID of the process. 54 | Session int 55 | // The controlling terminal of the process. 56 | TTY int 57 | // The ID of the foreground process group of the controlling terminal of 58 | // the process. 59 | TPGID int 60 | // The kernel flags word of the process. 61 | Flags uint 62 | // The number of minor faults the process has made which have not required 63 | // loading a memory page from disk. 64 | MinFlt uint 65 | // The number of minor faults that the process's waited-for children have 66 | // made. 67 | CMinFlt uint 68 | // The number of major faults the process has made which have required 69 | // loading a memory page from disk. 70 | MajFlt uint 71 | // The number of major faults that the process's waited-for children have 72 | // made. 73 | CMajFlt uint 74 | // Amount of time that this process has been scheduled in user mode, 75 | // measured in clock ticks. 76 | UTime uint 77 | // Amount of time that this process has been scheduled in kernel mode, 78 | // measured in clock ticks. 79 | STime uint 80 | // Amount of time that this process's waited-for children have been 81 | // scheduled in user mode, measured in clock ticks. 82 | CUTime uint 83 | // Amount of time that this process's waited-for children have been 84 | // scheduled in kernel mode, measured in clock ticks. 85 | CSTime uint 86 | // For processes running a real-time scheduling policy, this is the negated 87 | // scheduling priority, minus one. 88 | Priority int 89 | // The nice value, a value in the range 19 (low priority) to -20 (high 90 | // priority). 91 | Nice int 92 | // Number of threads in this process. 93 | NumThreads int 94 | // The time the process started after system boot, the value is expressed 95 | // in clock ticks. 96 | Starttime uint64 97 | // Virtual memory size in bytes. 98 | VSize int 99 | // Resident set size in pages. 100 | RSS int 101 | 102 | fs FS 103 | } 104 | 105 | // NewStat returns the current status information of the process. 106 | func (p Proc) NewStat() (ProcStat, error) { 107 | f, err := os.Open(p.path("stat")) 108 | if err != nil { 109 | return ProcStat{}, err 110 | } 111 | defer f.Close() 112 | 113 | data, err := ioutil.ReadAll(f) 114 | if err != nil { 115 | return ProcStat{}, err 116 | } 117 | 118 | var ( 119 | ignore int 120 | 121 | s = ProcStat{PID: p.PID, fs: p.fs} 122 | l = bytes.Index(data, []byte("(")) 123 | r = bytes.LastIndex(data, []byte(")")) 124 | ) 125 | 126 | if l < 0 || r < 0 { 127 | return ProcStat{}, fmt.Errorf( 128 | "unexpected format, couldn't extract comm: %s", 129 | data, 130 | ) 131 | } 132 | 133 | s.Comm = string(data[l+1 : r]) 134 | _, err = fmt.Fscan( 135 | bytes.NewBuffer(data[r+2:]), 136 | &s.State, 137 | &s.PPID, 138 | &s.PGRP, 139 | &s.Session, 140 | &s.TTY, 141 | &s.TPGID, 142 | &s.Flags, 143 | &s.MinFlt, 144 | &s.CMinFlt, 145 | &s.MajFlt, 146 | &s.CMajFlt, 147 | &s.UTime, 148 | &s.STime, 149 | &s.CUTime, 150 | &s.CSTime, 151 | &s.Priority, 152 | &s.Nice, 153 | &s.NumThreads, 154 | &ignore, 155 | &s.Starttime, 156 | &s.VSize, 157 | &s.RSS, 158 | ) 159 | if err != nil { 160 | return ProcStat{}, err 161 | } 162 | 163 | return s, nil 164 | } 165 | 166 | // VirtualMemory returns the virtual memory size in bytes. 167 | func (s ProcStat) VirtualMemory() int { 168 | return s.VSize 169 | } 170 | 171 | // ResidentMemory returns the resident memory size in bytes. 172 | func (s ProcStat) ResidentMemory() int { 173 | return s.RSS * os.Getpagesize() 174 | } 175 | 176 | // StartTime returns the unix timestamp of the process in seconds. 177 | func (s ProcStat) StartTime() (float64, error) { 178 | stat, err := s.fs.NewStat() 179 | if err != nil { 180 | return 0, err 181 | } 182 | return float64(stat.BootTime) + (float64(s.Starttime) / userHZ), nil 183 | } 184 | 185 | // CPUTime returns the total CPU user and system time in seconds. 186 | func (s ProcStat) CPUTime() float64 { 187 | return float64(s.UTime+s.STime) / userHZ 188 | } 189 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "log" 6 | "net/http" 7 | "strconv" 8 | "sync" 9 | 10 | "github.com/mindprince/gonvml" 11 | "github.com/prometheus/client_golang/prometheus" 12 | "github.com/prometheus/client_golang/prometheus/promhttp" 13 | ) 14 | 15 | const ( 16 | namespace = "nvidia_gpu" 17 | ) 18 | 19 | var ( 20 | addr = flag.String("web.listen-address", ":9445", "Address to listen on for web interface and telemetry.") 21 | 22 | labels = []string{"minor_number", "uuid", "name"} 23 | ) 24 | 25 | type Collector struct { 26 | sync.Mutex 27 | numDevices prometheus.Gauge 28 | usedMemory *prometheus.GaugeVec 29 | totalMemory *prometheus.GaugeVec 30 | dutyCycle *prometheus.GaugeVec 31 | powerUsage *prometheus.GaugeVec 32 | temperature *prometheus.GaugeVec 33 | fanSpeed *prometheus.GaugeVec 34 | } 35 | 36 | func NewCollector() *Collector { 37 | return &Collector{ 38 | numDevices: prometheus.NewGauge( 39 | prometheus.GaugeOpts{ 40 | Namespace: namespace, 41 | Name: "num_devices", 42 | Help: "Number of GPU devices", 43 | }, 44 | ), 45 | usedMemory: prometheus.NewGaugeVec( 46 | prometheus.GaugeOpts{ 47 | Namespace: namespace, 48 | Name: "memory_used_bytes", 49 | Help: "Memory used by the GPU device in bytes", 50 | }, 51 | labels, 52 | ), 53 | totalMemory: prometheus.NewGaugeVec( 54 | prometheus.GaugeOpts{ 55 | Namespace: namespace, 56 | Name: "memory_total_bytes", 57 | Help: "Total memory of the GPU device in bytes", 58 | }, 59 | labels, 60 | ), 61 | dutyCycle: prometheus.NewGaugeVec( 62 | prometheus.GaugeOpts{ 63 | Namespace: namespace, 64 | Name: "duty_cycle", 65 | Help: "Percent of time over the past sample period during which one or more kernels were executing on the GPU device", 66 | }, 67 | labels, 68 | ), 69 | powerUsage: prometheus.NewGaugeVec( 70 | prometheus.GaugeOpts{ 71 | Namespace: namespace, 72 | Name: "power_usage_milliwatts", 73 | Help: "Power usage of the GPU device in milliwatts", 74 | }, 75 | labels, 76 | ), 77 | temperature: prometheus.NewGaugeVec( 78 | prometheus.GaugeOpts{ 79 | Namespace: namespace, 80 | Name: "temperature_celsius", 81 | Help: "Temperature of the GPU device in celsius", 82 | }, 83 | labels, 84 | ), 85 | fanSpeed: prometheus.NewGaugeVec( 86 | prometheus.GaugeOpts{ 87 | Namespace: namespace, 88 | Name: "fanspeed_percent", 89 | Help: "Fanspeed of the GPU device as a percent of its maximum", 90 | }, 91 | labels, 92 | ), 93 | } 94 | } 95 | 96 | func (c *Collector) Describe(ch chan<- *prometheus.Desc) { 97 | ch <- c.numDevices.Desc() 98 | c.usedMemory.Describe(ch) 99 | c.totalMemory.Describe(ch) 100 | c.dutyCycle.Describe(ch) 101 | c.powerUsage.Describe(ch) 102 | c.temperature.Describe(ch) 103 | c.fanSpeed.Describe(ch) 104 | } 105 | 106 | func (c *Collector) Collect(ch chan<- prometheus.Metric) { 107 | // Only one Collect call in progress at a time. 108 | c.Lock() 109 | defer c.Unlock() 110 | 111 | c.usedMemory.Reset() 112 | c.totalMemory.Reset() 113 | c.dutyCycle.Reset() 114 | c.powerUsage.Reset() 115 | c.temperature.Reset() 116 | c.fanSpeed.Reset() 117 | 118 | numDevices, err := gonvml.DeviceCount() 119 | if err != nil { 120 | log.Printf("DeviceCount() error: %v", err) 121 | return 122 | } else { 123 | c.numDevices.Set(float64(numDevices)) 124 | ch <- c.numDevices 125 | } 126 | 127 | for i := 0; i < int(numDevices); i++ { 128 | dev, err := gonvml.DeviceHandleByIndex(uint(i)) 129 | if err != nil { 130 | log.Printf("DeviceHandleByIndex(%d) error: %v", i, err) 131 | continue 132 | } 133 | 134 | minorNumber, err := dev.MinorNumber() 135 | if err != nil { 136 | log.Printf("MinorNumber() error: %v", err) 137 | continue 138 | } 139 | minor := strconv.Itoa(int(minorNumber)) 140 | 141 | uuid, err := dev.UUID() 142 | if err != nil { 143 | log.Printf("UUID() error: %v", err) 144 | continue 145 | } 146 | 147 | name, err := dev.Name() 148 | if err != nil { 149 | log.Printf("Name() error: %v", err) 150 | continue 151 | } 152 | 153 | totalMemory, usedMemory, err := dev.MemoryInfo() 154 | if err != nil { 155 | log.Printf("MemoryInfo() error: %v", err) 156 | } else { 157 | c.usedMemory.WithLabelValues(minor, uuid, name).Set(float64(usedMemory)) 158 | c.totalMemory.WithLabelValues(minor, uuid, name).Set(float64(totalMemory)) 159 | } 160 | 161 | dutyCycle, _, err := dev.UtilizationRates() 162 | if err != nil { 163 | log.Printf("UtilizationRates() error: %v", err) 164 | } else { 165 | c.dutyCycle.WithLabelValues(minor, uuid, name).Set(float64(dutyCycle)) 166 | } 167 | 168 | powerUsage, err := dev.PowerUsage() 169 | if err != nil { 170 | log.Printf("PowerUsage() error: %v", err) 171 | } else { 172 | c.powerUsage.WithLabelValues(minor, uuid, name).Set(float64(powerUsage)) 173 | } 174 | 175 | temperature, err := dev.Temperature() 176 | if err != nil { 177 | log.Printf("Temperature() error: %v", err) 178 | } else { 179 | c.temperature.WithLabelValues(minor, uuid, name).Set(float64(temperature)) 180 | } 181 | 182 | fanSpeed, err := dev.FanSpeed() 183 | if err != nil { 184 | log.Printf("FanSpeed() error: %v", err) 185 | } else { 186 | c.fanSpeed.WithLabelValues(minor, uuid, name).Set(float64(fanSpeed)) 187 | } 188 | } 189 | c.usedMemory.Collect(ch) 190 | c.totalMemory.Collect(ch) 191 | c.dutyCycle.Collect(ch) 192 | c.powerUsage.Collect(ch) 193 | c.temperature.Collect(ch) 194 | c.fanSpeed.Collect(ch) 195 | } 196 | 197 | func main() { 198 | flag.Parse() 199 | 200 | if err := gonvml.Initialize(); err != nil { 201 | log.Fatalf("Couldn't initialize gonvml: %v. Make sure NVML is in the shared library search path.", err) 202 | } 203 | defer gonvml.Shutdown() 204 | 205 | if driverVersion, err := gonvml.SystemDriverVersion(); err != nil { 206 | log.Printf("SystemDriverVersion() error: %v", err) 207 | } else { 208 | log.Printf("SystemDriverVersion(): %v", driverVersion) 209 | } 210 | 211 | prometheus.MustRegister(NewCollector()) 212 | 213 | // Serve on all paths under addr 214 | log.Fatalf("ListenAndServe error: %v", http.ListenAndServe(*addr, promhttp.Handler())) 215 | } 216 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/proc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package procfs 15 | 16 | import ( 17 | "bytes" 18 | "fmt" 19 | "io/ioutil" 20 | "os" 21 | "strconv" 22 | "strings" 23 | ) 24 | 25 | // Proc provides information about a running process. 26 | type Proc struct { 27 | // The process ID. 28 | PID int 29 | 30 | fs FS 31 | } 32 | 33 | // Procs represents a list of Proc structs. 34 | type Procs []Proc 35 | 36 | func (p Procs) Len() int { return len(p) } 37 | func (p Procs) Swap(i, j int) { p[i], p[j] = p[j], p[i] } 38 | func (p Procs) Less(i, j int) bool { return p[i].PID < p[j].PID } 39 | 40 | // Self returns a process for the current process read via /proc/self. 41 | func Self() (Proc, error) { 42 | fs, err := NewFS(DefaultMountPoint) 43 | if err != nil { 44 | return Proc{}, err 45 | } 46 | return fs.Self() 47 | } 48 | 49 | // NewProc returns a process for the given pid under /proc. 50 | func NewProc(pid int) (Proc, error) { 51 | fs, err := NewFS(DefaultMountPoint) 52 | if err != nil { 53 | return Proc{}, err 54 | } 55 | return fs.NewProc(pid) 56 | } 57 | 58 | // AllProcs returns a list of all currently available processes under /proc. 59 | func AllProcs() (Procs, error) { 60 | fs, err := NewFS(DefaultMountPoint) 61 | if err != nil { 62 | return Procs{}, err 63 | } 64 | return fs.AllProcs() 65 | } 66 | 67 | // Self returns a process for the current process. 68 | func (fs FS) Self() (Proc, error) { 69 | p, err := os.Readlink(fs.Path("self")) 70 | if err != nil { 71 | return Proc{}, err 72 | } 73 | pid, err := strconv.Atoi(strings.Replace(p, string(fs), "", -1)) 74 | if err != nil { 75 | return Proc{}, err 76 | } 77 | return fs.NewProc(pid) 78 | } 79 | 80 | // NewProc returns a process for the given pid. 81 | func (fs FS) NewProc(pid int) (Proc, error) { 82 | if _, err := os.Stat(fs.Path(strconv.Itoa(pid))); err != nil { 83 | return Proc{}, err 84 | } 85 | return Proc{PID: pid, fs: fs}, nil 86 | } 87 | 88 | // AllProcs returns a list of all currently available processes. 89 | func (fs FS) AllProcs() (Procs, error) { 90 | d, err := os.Open(fs.Path()) 91 | if err != nil { 92 | return Procs{}, err 93 | } 94 | defer d.Close() 95 | 96 | names, err := d.Readdirnames(-1) 97 | if err != nil { 98 | return Procs{}, fmt.Errorf("could not read %s: %s", d.Name(), err) 99 | } 100 | 101 | p := Procs{} 102 | for _, n := range names { 103 | pid, err := strconv.ParseInt(n, 10, 64) 104 | if err != nil { 105 | continue 106 | } 107 | p = append(p, Proc{PID: int(pid), fs: fs}) 108 | } 109 | 110 | return p, nil 111 | } 112 | 113 | // CmdLine returns the command line of a process. 114 | func (p Proc) CmdLine() ([]string, error) { 115 | f, err := os.Open(p.path("cmdline")) 116 | if err != nil { 117 | return nil, err 118 | } 119 | defer f.Close() 120 | 121 | data, err := ioutil.ReadAll(f) 122 | if err != nil { 123 | return nil, err 124 | } 125 | 126 | if len(data) < 1 { 127 | return []string{}, nil 128 | } 129 | 130 | return strings.Split(string(bytes.TrimRight(data, string("\x00"))), string(byte(0))), nil 131 | } 132 | 133 | // Comm returns the command name of a process. 134 | func (p Proc) Comm() (string, error) { 135 | f, err := os.Open(p.path("comm")) 136 | if err != nil { 137 | return "", err 138 | } 139 | defer f.Close() 140 | 141 | data, err := ioutil.ReadAll(f) 142 | if err != nil { 143 | return "", err 144 | } 145 | 146 | return strings.TrimSpace(string(data)), nil 147 | } 148 | 149 | // Executable returns the absolute path of the executable command of a process. 150 | func (p Proc) Executable() (string, error) { 151 | exe, err := os.Readlink(p.path("exe")) 152 | if os.IsNotExist(err) { 153 | return "", nil 154 | } 155 | 156 | return exe, err 157 | } 158 | 159 | // FileDescriptors returns the currently open file descriptors of a process. 160 | func (p Proc) FileDescriptors() ([]uintptr, error) { 161 | names, err := p.fileDescriptors() 162 | if err != nil { 163 | return nil, err 164 | } 165 | 166 | fds := make([]uintptr, len(names)) 167 | for i, n := range names { 168 | fd, err := strconv.ParseInt(n, 10, 32) 169 | if err != nil { 170 | return nil, fmt.Errorf("could not parse fd %s: %s", n, err) 171 | } 172 | fds[i] = uintptr(fd) 173 | } 174 | 175 | return fds, nil 176 | } 177 | 178 | // FileDescriptorTargets returns the targets of all file descriptors of a process. 179 | // If a file descriptor is not a symlink to a file (like a socket), that value will be the empty string. 180 | func (p Proc) FileDescriptorTargets() ([]string, error) { 181 | names, err := p.fileDescriptors() 182 | if err != nil { 183 | return nil, err 184 | } 185 | 186 | targets := make([]string, len(names)) 187 | 188 | for i, name := range names { 189 | target, err := os.Readlink(p.path("fd", name)) 190 | if err == nil { 191 | targets[i] = target 192 | } 193 | } 194 | 195 | return targets, nil 196 | } 197 | 198 | // FileDescriptorsLen returns the number of currently open file descriptors of 199 | // a process. 200 | func (p Proc) FileDescriptorsLen() (int, error) { 201 | fds, err := p.fileDescriptors() 202 | if err != nil { 203 | return 0, err 204 | } 205 | 206 | return len(fds), nil 207 | } 208 | 209 | // MountStats retrieves statistics and configuration for mount points in a 210 | // process's namespace. 211 | func (p Proc) MountStats() ([]*Mount, error) { 212 | f, err := os.Open(p.path("mountstats")) 213 | if err != nil { 214 | return nil, err 215 | } 216 | defer f.Close() 217 | 218 | return parseMountStats(f) 219 | } 220 | 221 | func (p Proc) fileDescriptors() ([]string, error) { 222 | d, err := os.Open(p.path("fd")) 223 | if err != nil { 224 | return nil, err 225 | } 226 | defer d.Close() 227 | 228 | names, err := d.Readdirnames(-1) 229 | if err != nil { 230 | return nil, fmt.Errorf("could not read %s: %s", d.Name(), err) 231 | } 232 | 233 | return names, nil 234 | } 235 | 236 | func (p Proc) path(pa ...string) string { 237 | return p.fs.Path(append([]string{strconv.Itoa(p.PID)}, pa...)...) 238 | } 239 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_golang/prometheus/counter.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package prometheus 15 | 16 | import ( 17 | "errors" 18 | ) 19 | 20 | // Counter is a Metric that represents a single numerical value that only ever 21 | // goes up. That implies that it cannot be used to count items whose number can 22 | // also go down, e.g. the number of currently running goroutines. Those 23 | // "counters" are represented by Gauges. 24 | // 25 | // A Counter is typically used to count requests served, tasks completed, errors 26 | // occurred, etc. 27 | // 28 | // To create Counter instances, use NewCounter. 29 | type Counter interface { 30 | Metric 31 | Collector 32 | 33 | // Set is used to set the Counter to an arbitrary value. It is only used 34 | // if you have to transfer a value from an external counter into this 35 | // Prometheus metric. Do not use it for regular handling of a 36 | // Prometheus counter (as it can be used to break the contract of 37 | // monotonically increasing values). 38 | // 39 | // Deprecated: Use NewConstMetric to create a counter for an external 40 | // value. A Counter should never be set. 41 | Set(float64) 42 | // Inc increments the counter by 1. 43 | Inc() 44 | // Add adds the given value to the counter. It panics if the value is < 45 | // 0. 46 | Add(float64) 47 | } 48 | 49 | // CounterOpts is an alias for Opts. See there for doc comments. 50 | type CounterOpts Opts 51 | 52 | // NewCounter creates a new Counter based on the provided CounterOpts. 53 | func NewCounter(opts CounterOpts) Counter { 54 | desc := NewDesc( 55 | BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), 56 | opts.Help, 57 | nil, 58 | opts.ConstLabels, 59 | ) 60 | result := &counter{value: value{desc: desc, valType: CounterValue, labelPairs: desc.constLabelPairs}} 61 | result.init(result) // Init self-collection. 62 | return result 63 | } 64 | 65 | type counter struct { 66 | value 67 | } 68 | 69 | func (c *counter) Add(v float64) { 70 | if v < 0 { 71 | panic(errors.New("counter cannot decrease in value")) 72 | } 73 | c.value.Add(v) 74 | } 75 | 76 | // CounterVec is a Collector that bundles a set of Counters that all share the 77 | // same Desc, but have different values for their variable labels. This is used 78 | // if you want to count the same thing partitioned by various dimensions 79 | // (e.g. number of HTTP requests, partitioned by response code and 80 | // method). Create instances with NewCounterVec. 81 | // 82 | // CounterVec embeds MetricVec. See there for a full list of methods with 83 | // detailed documentation. 84 | type CounterVec struct { 85 | *MetricVec 86 | } 87 | 88 | // NewCounterVec creates a new CounterVec based on the provided CounterOpts and 89 | // partitioned by the given label names. At least one label name must be 90 | // provided. 91 | func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec { 92 | desc := NewDesc( 93 | BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), 94 | opts.Help, 95 | labelNames, 96 | opts.ConstLabels, 97 | ) 98 | return &CounterVec{ 99 | MetricVec: newMetricVec(desc, func(lvs ...string) Metric { 100 | result := &counter{value: value{ 101 | desc: desc, 102 | valType: CounterValue, 103 | labelPairs: makeLabelPairs(desc, lvs), 104 | }} 105 | result.init(result) // Init self-collection. 106 | return result 107 | }), 108 | } 109 | } 110 | 111 | // GetMetricWithLabelValues replaces the method of the same name in 112 | // MetricVec. The difference is that this method returns a Counter and not a 113 | // Metric so that no type conversion is required. 114 | func (m *CounterVec) GetMetricWithLabelValues(lvs ...string) (Counter, error) { 115 | metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...) 116 | if metric != nil { 117 | return metric.(Counter), err 118 | } 119 | return nil, err 120 | } 121 | 122 | // GetMetricWith replaces the method of the same name in MetricVec. The 123 | // difference is that this method returns a Counter and not a Metric so that no 124 | // type conversion is required. 125 | func (m *CounterVec) GetMetricWith(labels Labels) (Counter, error) { 126 | metric, err := m.MetricVec.GetMetricWith(labels) 127 | if metric != nil { 128 | return metric.(Counter), err 129 | } 130 | return nil, err 131 | } 132 | 133 | // WithLabelValues works as GetMetricWithLabelValues, but panics where 134 | // GetMetricWithLabelValues would have returned an error. By not returning an 135 | // error, WithLabelValues allows shortcuts like 136 | // myVec.WithLabelValues("404", "GET").Add(42) 137 | func (m *CounterVec) WithLabelValues(lvs ...string) Counter { 138 | return m.MetricVec.WithLabelValues(lvs...).(Counter) 139 | } 140 | 141 | // With works as GetMetricWith, but panics where GetMetricWithLabels would have 142 | // returned an error. By not returning an error, With allows shortcuts like 143 | // myVec.With(Labels{"code": "404", "method": "GET"}).Add(42) 144 | func (m *CounterVec) With(labels Labels) Counter { 145 | return m.MetricVec.With(labels).(Counter) 146 | } 147 | 148 | // CounterFunc is a Counter whose value is determined at collect time by calling a 149 | // provided function. 150 | // 151 | // To create CounterFunc instances, use NewCounterFunc. 152 | type CounterFunc interface { 153 | Metric 154 | Collector 155 | } 156 | 157 | // NewCounterFunc creates a new CounterFunc based on the provided 158 | // CounterOpts. The value reported is determined by calling the given function 159 | // from within the Write method. Take into account that metric collection may 160 | // happen concurrently. If that results in concurrent calls to Write, like in 161 | // the case where a CounterFunc is directly registered with Prometheus, the 162 | // provided function must be concurrency-safe. The function should also honor 163 | // the contract for a Counter (values only go up, not down), but compliance will 164 | // not be checked. 165 | func NewCounterFunc(opts CounterOpts, function func() float64) CounterFunc { 166 | return newValueFunc(NewDesc( 167 | BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), 168 | opts.Help, 169 | nil, 170 | opts.ConstLabels, 171 | ), CounterValue, function) 172 | } 173 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/model/labels.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package model 15 | 16 | import ( 17 | "encoding/json" 18 | "fmt" 19 | "regexp" 20 | "strings" 21 | "unicode/utf8" 22 | ) 23 | 24 | const ( 25 | // AlertNameLabel is the name of the label containing the an alert's name. 26 | AlertNameLabel = "alertname" 27 | 28 | // ExportedLabelPrefix is the prefix to prepend to the label names present in 29 | // exported metrics if a label of the same name is added by the server. 30 | ExportedLabelPrefix = "exported_" 31 | 32 | // MetricNameLabel is the label name indicating the metric name of a 33 | // timeseries. 34 | MetricNameLabel = "__name__" 35 | 36 | // SchemeLabel is the name of the label that holds the scheme on which to 37 | // scrape a target. 38 | SchemeLabel = "__scheme__" 39 | 40 | // AddressLabel is the name of the label that holds the address of 41 | // a scrape target. 42 | AddressLabel = "__address__" 43 | 44 | // MetricsPathLabel is the name of the label that holds the path on which to 45 | // scrape a target. 46 | MetricsPathLabel = "__metrics_path__" 47 | 48 | // ReservedLabelPrefix is a prefix which is not legal in user-supplied 49 | // label names. 50 | ReservedLabelPrefix = "__" 51 | 52 | // MetaLabelPrefix is a prefix for labels that provide meta information. 53 | // Labels with this prefix are used for intermediate label processing and 54 | // will not be attached to time series. 55 | MetaLabelPrefix = "__meta_" 56 | 57 | // TmpLabelPrefix is a prefix for temporary labels as part of relabelling. 58 | // Labels with this prefix are used for intermediate label processing and 59 | // will not be attached to time series. This is reserved for use in 60 | // Prometheus configuration files by users. 61 | TmpLabelPrefix = "__tmp_" 62 | 63 | // ParamLabelPrefix is a prefix for labels that provide URL parameters 64 | // used to scrape a target. 65 | ParamLabelPrefix = "__param_" 66 | 67 | // JobLabel is the label name indicating the job from which a timeseries 68 | // was scraped. 69 | JobLabel = "job" 70 | 71 | // InstanceLabel is the label name used for the instance label. 72 | InstanceLabel = "instance" 73 | 74 | // BucketLabel is used for the label that defines the upper bound of a 75 | // bucket of a histogram ("le" -> "less or equal"). 76 | BucketLabel = "le" 77 | 78 | // QuantileLabel is used for the label that defines the quantile in a 79 | // summary. 80 | QuantileLabel = "quantile" 81 | ) 82 | 83 | // LabelNameRE is a regular expression matching valid label names. Note that the 84 | // IsValid method of LabelName performs the same check but faster than a match 85 | // with this regular expression. 86 | var LabelNameRE = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$") 87 | 88 | // A LabelName is a key for a LabelSet or Metric. It has a value associated 89 | // therewith. 90 | type LabelName string 91 | 92 | // IsValid is true iff the label name matches the pattern of LabelNameRE. This 93 | // method, however, does not use LabelNameRE for the check but a much faster 94 | // hardcoded implementation. 95 | func (ln LabelName) IsValid() bool { 96 | if len(ln) == 0 { 97 | return false 98 | } 99 | for i, b := range ln { 100 | if !((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || (b >= '0' && b <= '9' && i > 0)) { 101 | return false 102 | } 103 | } 104 | return true 105 | } 106 | 107 | // UnmarshalYAML implements the yaml.Unmarshaler interface. 108 | func (ln *LabelName) UnmarshalYAML(unmarshal func(interface{}) error) error { 109 | var s string 110 | if err := unmarshal(&s); err != nil { 111 | return err 112 | } 113 | if !LabelName(s).IsValid() { 114 | return fmt.Errorf("%q is not a valid label name", s) 115 | } 116 | *ln = LabelName(s) 117 | return nil 118 | } 119 | 120 | // UnmarshalJSON implements the json.Unmarshaler interface. 121 | func (ln *LabelName) UnmarshalJSON(b []byte) error { 122 | var s string 123 | if err := json.Unmarshal(b, &s); err != nil { 124 | return err 125 | } 126 | if !LabelName(s).IsValid() { 127 | return fmt.Errorf("%q is not a valid label name", s) 128 | } 129 | *ln = LabelName(s) 130 | return nil 131 | } 132 | 133 | // LabelNames is a sortable LabelName slice. In implements sort.Interface. 134 | type LabelNames []LabelName 135 | 136 | func (l LabelNames) Len() int { 137 | return len(l) 138 | } 139 | 140 | func (l LabelNames) Less(i, j int) bool { 141 | return l[i] < l[j] 142 | } 143 | 144 | func (l LabelNames) Swap(i, j int) { 145 | l[i], l[j] = l[j], l[i] 146 | } 147 | 148 | func (l LabelNames) String() string { 149 | labelStrings := make([]string, 0, len(l)) 150 | for _, label := range l { 151 | labelStrings = append(labelStrings, string(label)) 152 | } 153 | return strings.Join(labelStrings, ", ") 154 | } 155 | 156 | // A LabelValue is an associated value for a LabelName. 157 | type LabelValue string 158 | 159 | // IsValid returns true iff the string is a valid UTF8. 160 | func (lv LabelValue) IsValid() bool { 161 | return utf8.ValidString(string(lv)) 162 | } 163 | 164 | // LabelValues is a sortable LabelValue slice. It implements sort.Interface. 165 | type LabelValues []LabelValue 166 | 167 | func (l LabelValues) Len() int { 168 | return len(l) 169 | } 170 | 171 | func (l LabelValues) Less(i, j int) bool { 172 | return string(l[i]) < string(l[j]) 173 | } 174 | 175 | func (l LabelValues) Swap(i, j int) { 176 | l[i], l[j] = l[j], l[i] 177 | } 178 | 179 | // LabelPair pairs a name with a value. 180 | type LabelPair struct { 181 | Name LabelName 182 | Value LabelValue 183 | } 184 | 185 | // LabelPairs is a sortable slice of LabelPair pointers. It implements 186 | // sort.Interface. 187 | type LabelPairs []*LabelPair 188 | 189 | func (l LabelPairs) Len() int { 190 | return len(l) 191 | } 192 | 193 | func (l LabelPairs) Less(i, j int) bool { 194 | switch { 195 | case l[i].Name > l[j].Name: 196 | return false 197 | case l[i].Name < l[j].Name: 198 | return true 199 | case l[i].Value > l[j].Value: 200 | return false 201 | case l[i].Value < l[j].Value: 202 | return true 203 | default: 204 | return false 205 | } 206 | } 207 | 208 | func (l LabelPairs) Swap(i, j int) { 209 | l[i], l[j] = l[j], l[i] 210 | } 211 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_golang/prometheus/metric.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package prometheus 15 | 16 | import ( 17 | "strings" 18 | 19 | dto "github.com/prometheus/client_model/go" 20 | ) 21 | 22 | const separatorByte byte = 255 23 | 24 | // A Metric models a single sample value with its meta data being exported to 25 | // Prometheus. Implementations of Metric in this package are Gauge, Counter, 26 | // Histogram, Summary, and Untyped. 27 | type Metric interface { 28 | // Desc returns the descriptor for the Metric. This method idempotently 29 | // returns the same descriptor throughout the lifetime of the 30 | // Metric. The returned descriptor is immutable by contract. A Metric 31 | // unable to describe itself must return an invalid descriptor (created 32 | // with NewInvalidDesc). 33 | Desc() *Desc 34 | // Write encodes the Metric into a "Metric" Protocol Buffer data 35 | // transmission object. 36 | // 37 | // Metric implementations must observe concurrency safety as reads of 38 | // this metric may occur at any time, and any blocking occurs at the 39 | // expense of total performance of rendering all registered 40 | // metrics. Ideally, Metric implementations should support concurrent 41 | // readers. 42 | // 43 | // While populating dto.Metric, it is the responsibility of the 44 | // implementation to ensure validity of the Metric protobuf (like valid 45 | // UTF-8 strings or syntactically valid metric and label names). It is 46 | // recommended to sort labels lexicographically. (Implementers may find 47 | // LabelPairSorter useful for that.) Callers of Write should still make 48 | // sure of sorting if they depend on it. 49 | Write(*dto.Metric) error 50 | // TODO(beorn7): The original rationale of passing in a pre-allocated 51 | // dto.Metric protobuf to save allocations has disappeared. The 52 | // signature of this method should be changed to "Write() (*dto.Metric, 53 | // error)". 54 | } 55 | 56 | // Opts bundles the options for creating most Metric types. Each metric 57 | // implementation XXX has its own XXXOpts type, but in most cases, it is just be 58 | // an alias of this type (which might change when the requirement arises.) 59 | // 60 | // It is mandatory to set Name and Help to a non-empty string. All other fields 61 | // are optional and can safely be left at their zero value. 62 | type Opts struct { 63 | // Namespace, Subsystem, and Name are components of the fully-qualified 64 | // name of the Metric (created by joining these components with 65 | // "_"). Only Name is mandatory, the others merely help structuring the 66 | // name. Note that the fully-qualified name of the metric must be a 67 | // valid Prometheus metric name. 68 | Namespace string 69 | Subsystem string 70 | Name string 71 | 72 | // Help provides information about this metric. Mandatory! 73 | // 74 | // Metrics with the same fully-qualified name must have the same Help 75 | // string. 76 | Help string 77 | 78 | // ConstLabels are used to attach fixed labels to this metric. Metrics 79 | // with the same fully-qualified name must have the same label names in 80 | // their ConstLabels. 81 | // 82 | // Note that in most cases, labels have a value that varies during the 83 | // lifetime of a process. Those labels are usually managed with a metric 84 | // vector collector (like CounterVec, GaugeVec, UntypedVec). ConstLabels 85 | // serve only special purposes. One is for the special case where the 86 | // value of a label does not change during the lifetime of a process, 87 | // e.g. if the revision of the running binary is put into a 88 | // label. Another, more advanced purpose is if more than one Collector 89 | // needs to collect Metrics with the same fully-qualified name. In that 90 | // case, those Metrics must differ in the values of their 91 | // ConstLabels. See the Collector examples. 92 | // 93 | // If the value of a label never changes (not even between binaries), 94 | // that label most likely should not be a label at all (but part of the 95 | // metric name). 96 | ConstLabels Labels 97 | } 98 | 99 | // BuildFQName joins the given three name components by "_". Empty name 100 | // components are ignored. If the name parameter itself is empty, an empty 101 | // string is returned, no matter what. Metric implementations included in this 102 | // library use this function internally to generate the fully-qualified metric 103 | // name from the name component in their Opts. Users of the library will only 104 | // need this function if they implement their own Metric or instantiate a Desc 105 | // (with NewDesc) directly. 106 | func BuildFQName(namespace, subsystem, name string) string { 107 | if name == "" { 108 | return "" 109 | } 110 | switch { 111 | case namespace != "" && subsystem != "": 112 | return strings.Join([]string{namespace, subsystem, name}, "_") 113 | case namespace != "": 114 | return strings.Join([]string{namespace, name}, "_") 115 | case subsystem != "": 116 | return strings.Join([]string{subsystem, name}, "_") 117 | } 118 | return name 119 | } 120 | 121 | // LabelPairSorter implements sort.Interface. It is used to sort a slice of 122 | // dto.LabelPair pointers. This is useful for implementing the Write method of 123 | // custom metrics. 124 | type LabelPairSorter []*dto.LabelPair 125 | 126 | func (s LabelPairSorter) Len() int { 127 | return len(s) 128 | } 129 | 130 | func (s LabelPairSorter) Swap(i, j int) { 131 | s[i], s[j] = s[j], s[i] 132 | } 133 | 134 | func (s LabelPairSorter) Less(i, j int) bool { 135 | return s[i].GetName() < s[j].GetName() 136 | } 137 | 138 | type hashSorter []uint64 139 | 140 | func (s hashSorter) Len() int { 141 | return len(s) 142 | } 143 | 144 | func (s hashSorter) Swap(i, j int) { 145 | s[i], s[j] = s[j], s[i] 146 | } 147 | 148 | func (s hashSorter) Less(i, j int) bool { 149 | return s[i] < s[j] 150 | } 151 | 152 | type invalidMetric struct { 153 | desc *Desc 154 | err error 155 | } 156 | 157 | // NewInvalidMetric returns a metric whose Write method always returns the 158 | // provided error. It is useful if a Collector finds itself unable to collect 159 | // a metric and wishes to report an error to the registry. 160 | func NewInvalidMetric(desc *Desc, err error) Metric { 161 | return &invalidMetric{desc, err} 162 | } 163 | 164 | func (m *invalidMetric) Desc() *Desc { return m.desc } 165 | 166 | func (m *invalidMetric) Write(*dto.Metric) error { return m.err } 167 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/nfs/nfs.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // Package nfs implements parsing of /proc/net/rpc/nfsd. 15 | // Fields are documented in https://www.svennd.be/nfsd-stats-explained-procnetrpcnfsd/ 16 | package nfs 17 | 18 | // ReplyCache models the "rc" line. 19 | type ReplyCache struct { 20 | Hits uint64 21 | Misses uint64 22 | NoCache uint64 23 | } 24 | 25 | // FileHandles models the "fh" line. 26 | type FileHandles struct { 27 | Stale uint64 28 | TotalLookups uint64 29 | AnonLookups uint64 30 | DirNoCache uint64 31 | NoDirNoCache uint64 32 | } 33 | 34 | // InputOutput models the "io" line. 35 | type InputOutput struct { 36 | Read uint64 37 | Write uint64 38 | } 39 | 40 | // Threads models the "th" line. 41 | type Threads struct { 42 | Threads uint64 43 | FullCnt uint64 44 | } 45 | 46 | // ReadAheadCache models the "ra" line. 47 | type ReadAheadCache struct { 48 | CacheSize uint64 49 | CacheHistogram []uint64 50 | NotFound uint64 51 | } 52 | 53 | // Network models the "net" line. 54 | type Network struct { 55 | NetCount uint64 56 | UDPCount uint64 57 | TCPCount uint64 58 | TCPConnect uint64 59 | } 60 | 61 | // ClientRPC models the nfs "rpc" line. 62 | type ClientRPC struct { 63 | RPCCount uint64 64 | Retransmissions uint64 65 | AuthRefreshes uint64 66 | } 67 | 68 | // ServerRPC models the nfsd "rpc" line. 69 | type ServerRPC struct { 70 | RPCCount uint64 71 | BadCnt uint64 72 | BadFmt uint64 73 | BadAuth uint64 74 | BadcInt uint64 75 | } 76 | 77 | // V2Stats models the "proc2" line. 78 | type V2Stats struct { 79 | Null uint64 80 | GetAttr uint64 81 | SetAttr uint64 82 | Root uint64 83 | Lookup uint64 84 | ReadLink uint64 85 | Read uint64 86 | WrCache uint64 87 | Write uint64 88 | Create uint64 89 | Remove uint64 90 | Rename uint64 91 | Link uint64 92 | SymLink uint64 93 | MkDir uint64 94 | RmDir uint64 95 | ReadDir uint64 96 | FsStat uint64 97 | } 98 | 99 | // V3Stats models the "proc3" line. 100 | type V3Stats struct { 101 | Null uint64 102 | GetAttr uint64 103 | SetAttr uint64 104 | Lookup uint64 105 | Access uint64 106 | ReadLink uint64 107 | Read uint64 108 | Write uint64 109 | Create uint64 110 | MkDir uint64 111 | SymLink uint64 112 | MkNod uint64 113 | Remove uint64 114 | RmDir uint64 115 | Rename uint64 116 | Link uint64 117 | ReadDir uint64 118 | ReadDirPlus uint64 119 | FsStat uint64 120 | FsInfo uint64 121 | PathConf uint64 122 | Commit uint64 123 | } 124 | 125 | // ClientV4Stats models the nfs "proc4" line. 126 | type ClientV4Stats struct { 127 | Null uint64 128 | Read uint64 129 | Write uint64 130 | Commit uint64 131 | Open uint64 132 | OpenConfirm uint64 133 | OpenNoattr uint64 134 | OpenDowngrade uint64 135 | Close uint64 136 | Setattr uint64 137 | FsInfo uint64 138 | Renew uint64 139 | SetClientID uint64 140 | SetClientIDConfirm uint64 141 | Lock uint64 142 | Lockt uint64 143 | Locku uint64 144 | Access uint64 145 | Getattr uint64 146 | Lookup uint64 147 | LookupRoot uint64 148 | Remove uint64 149 | Rename uint64 150 | Link uint64 151 | Symlink uint64 152 | Create uint64 153 | Pathconf uint64 154 | StatFs uint64 155 | ReadLink uint64 156 | ReadDir uint64 157 | ServerCaps uint64 158 | DelegReturn uint64 159 | GetACL uint64 160 | SetACL uint64 161 | FsLocations uint64 162 | ReleaseLockowner uint64 163 | Secinfo uint64 164 | FsidPresent uint64 165 | ExchangeID uint64 166 | CreateSession uint64 167 | DestroySession uint64 168 | Sequence uint64 169 | GetLeaseTime uint64 170 | ReclaimComplete uint64 171 | LayoutGet uint64 172 | GetDeviceInfo uint64 173 | LayoutCommit uint64 174 | LayoutReturn uint64 175 | SecinfoNoName uint64 176 | TestStateID uint64 177 | FreeStateID uint64 178 | GetDeviceList uint64 179 | BindConnToSession uint64 180 | DestroyClientID uint64 181 | Seek uint64 182 | Allocate uint64 183 | DeAllocate uint64 184 | LayoutStats uint64 185 | Clone uint64 186 | } 187 | 188 | // ServerV4Stats models the nfsd "proc4" line. 189 | type ServerV4Stats struct { 190 | Null uint64 191 | Compound uint64 192 | } 193 | 194 | // V4Ops models the "proc4ops" line: NFSv4 operations 195 | // Variable list, see: 196 | // v4.0 https://tools.ietf.org/html/rfc3010 (38 operations) 197 | // v4.1 https://tools.ietf.org/html/rfc5661 (58 operations) 198 | // v4.2 https://tools.ietf.org/html/draft-ietf-nfsv4-minorversion2-41 (71 operations) 199 | type V4Ops struct { 200 | //Values uint64 // Variable depending on v4.x sub-version. TODO: Will this always at least include the fields in this struct? 201 | Op0Unused uint64 202 | Op1Unused uint64 203 | Op2Future uint64 204 | Access uint64 205 | Close uint64 206 | Commit uint64 207 | Create uint64 208 | DelegPurge uint64 209 | DelegReturn uint64 210 | GetAttr uint64 211 | GetFH uint64 212 | Link uint64 213 | Lock uint64 214 | Lockt uint64 215 | Locku uint64 216 | Lookup uint64 217 | LookupRoot uint64 218 | Nverify uint64 219 | Open uint64 220 | OpenAttr uint64 221 | OpenConfirm uint64 222 | OpenDgrd uint64 223 | PutFH uint64 224 | PutPubFH uint64 225 | PutRootFH uint64 226 | Read uint64 227 | ReadDir uint64 228 | ReadLink uint64 229 | Remove uint64 230 | Rename uint64 231 | Renew uint64 232 | RestoreFH uint64 233 | SaveFH uint64 234 | SecInfo uint64 235 | SetAttr uint64 236 | Verify uint64 237 | Write uint64 238 | RelLockOwner uint64 239 | } 240 | 241 | // ClientRPCStats models all stats from /proc/net/rpc/nfs. 242 | type ClientRPCStats struct { 243 | Network Network 244 | ClientRPC ClientRPC 245 | V2Stats V2Stats 246 | V3Stats V3Stats 247 | ClientV4Stats ClientV4Stats 248 | } 249 | 250 | // ServerRPCStats models all stats from /proc/net/rpc/nfsd. 251 | type ServerRPCStats struct { 252 | ReplyCache ReplyCache 253 | FileHandles FileHandles 254 | InputOutput InputOutput 255 | Threads Threads 256 | ReadAheadCache ReadAheadCache 257 | Network Network 258 | ServerRPC ServerRPC 259 | V2Stats V2Stats 260 | V3Stats V3Stats 261 | ServerV4Stats ServerV4Stats 262 | V4Ops V4Ops 263 | } 264 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/net_dev.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package procfs 15 | 16 | import ( 17 | "bufio" 18 | "errors" 19 | "os" 20 | "sort" 21 | "strconv" 22 | "strings" 23 | ) 24 | 25 | // NetDevLine is single line parsed from /proc/net/dev or /proc/[pid]/net/dev. 26 | type NetDevLine struct { 27 | Name string `json:"name"` // The name of the interface. 28 | RxBytes uint64 `json:"rx_bytes"` // Cumulative count of bytes received. 29 | RxPackets uint64 `json:"rx_packets"` // Cumulative count of packets received. 30 | RxErrors uint64 `json:"rx_errors"` // Cumulative count of receive errors encountered. 31 | RxDropped uint64 `json:"rx_dropped"` // Cumulative count of packets dropped while receiving. 32 | RxFIFO uint64 `json:"rx_fifo"` // Cumulative count of FIFO buffer errors. 33 | RxFrame uint64 `json:"rx_frame"` // Cumulative count of packet framing errors. 34 | RxCompressed uint64 `json:"rx_compressed"` // Cumulative count of compressed packets received by the device driver. 35 | RxMulticast uint64 `json:"rx_multicast"` // Cumulative count of multicast frames received by the device driver. 36 | TxBytes uint64 `json:"tx_bytes"` // Cumulative count of bytes transmitted. 37 | TxPackets uint64 `json:"tx_packets"` // Cumulative count of packets transmitted. 38 | TxErrors uint64 `json:"tx_errors"` // Cumulative count of transmit errors encountered. 39 | TxDropped uint64 `json:"tx_dropped"` // Cumulative count of packets dropped while transmitting. 40 | TxFIFO uint64 `json:"tx_fifo"` // Cumulative count of FIFO buffer errors. 41 | TxCollisions uint64 `json:"tx_collisions"` // Cumulative count of collisions detected on the interface. 42 | TxCarrier uint64 `json:"tx_carrier"` // Cumulative count of carrier losses detected by the device driver. 43 | TxCompressed uint64 `json:"tx_compressed"` // Cumulative count of compressed packets transmitted by the device driver. 44 | } 45 | 46 | // NetDev is parsed from /proc/net/dev or /proc/[pid]/net/dev. The map keys 47 | // are interface names. 48 | type NetDev map[string]NetDevLine 49 | 50 | // NewNetDev returns kernel/system statistics read from /proc/net/dev. 51 | func NewNetDev() (NetDev, error) { 52 | fs, err := NewFS(DefaultMountPoint) 53 | if err != nil { 54 | return nil, err 55 | } 56 | 57 | return fs.NewNetDev() 58 | } 59 | 60 | // NewNetDev returns kernel/system statistics read from /proc/net/dev. 61 | func (fs FS) NewNetDev() (NetDev, error) { 62 | return newNetDev(fs.Path("net/dev")) 63 | } 64 | 65 | // NewNetDev returns kernel/system statistics read from /proc/[pid]/net/dev. 66 | func (p Proc) NewNetDev() (NetDev, error) { 67 | return newNetDev(p.path("net/dev")) 68 | } 69 | 70 | // newNetDev creates a new NetDev from the contents of the given file. 71 | func newNetDev(file string) (NetDev, error) { 72 | f, err := os.Open(file) 73 | if err != nil { 74 | return NetDev{}, err 75 | } 76 | defer f.Close() 77 | 78 | nd := NetDev{} 79 | s := bufio.NewScanner(f) 80 | for n := 0; s.Scan(); n++ { 81 | // Skip the 2 header lines. 82 | if n < 2 { 83 | continue 84 | } 85 | 86 | line, err := nd.parseLine(s.Text()) 87 | if err != nil { 88 | return nd, err 89 | } 90 | 91 | nd[line.Name] = *line 92 | } 93 | 94 | return nd, s.Err() 95 | } 96 | 97 | // parseLine parses a single line from the /proc/net/dev file. Header lines 98 | // must be filtered prior to calling this method. 99 | func (nd NetDev) parseLine(rawLine string) (*NetDevLine, error) { 100 | parts := strings.SplitN(rawLine, ":", 2) 101 | if len(parts) != 2 { 102 | return nil, errors.New("invalid net/dev line, missing colon") 103 | } 104 | fields := strings.Fields(strings.TrimSpace(parts[1])) 105 | 106 | var err error 107 | line := &NetDevLine{} 108 | 109 | // Interface Name 110 | line.Name = strings.TrimSpace(parts[0]) 111 | if line.Name == "" { 112 | return nil, errors.New("invalid net/dev line, empty interface name") 113 | } 114 | 115 | // RX 116 | line.RxBytes, err = strconv.ParseUint(fields[0], 10, 64) 117 | if err != nil { 118 | return nil, err 119 | } 120 | line.RxPackets, err = strconv.ParseUint(fields[1], 10, 64) 121 | if err != nil { 122 | return nil, err 123 | } 124 | line.RxErrors, err = strconv.ParseUint(fields[2], 10, 64) 125 | if err != nil { 126 | return nil, err 127 | } 128 | line.RxDropped, err = strconv.ParseUint(fields[3], 10, 64) 129 | if err != nil { 130 | return nil, err 131 | } 132 | line.RxFIFO, err = strconv.ParseUint(fields[4], 10, 64) 133 | if err != nil { 134 | return nil, err 135 | } 136 | line.RxFrame, err = strconv.ParseUint(fields[5], 10, 64) 137 | if err != nil { 138 | return nil, err 139 | } 140 | line.RxCompressed, err = strconv.ParseUint(fields[6], 10, 64) 141 | if err != nil { 142 | return nil, err 143 | } 144 | line.RxMulticast, err = strconv.ParseUint(fields[7], 10, 64) 145 | if err != nil { 146 | return nil, err 147 | } 148 | 149 | // TX 150 | line.TxBytes, err = strconv.ParseUint(fields[8], 10, 64) 151 | if err != nil { 152 | return nil, err 153 | } 154 | line.TxPackets, err = strconv.ParseUint(fields[9], 10, 64) 155 | if err != nil { 156 | return nil, err 157 | } 158 | line.TxErrors, err = strconv.ParseUint(fields[10], 10, 64) 159 | if err != nil { 160 | return nil, err 161 | } 162 | line.TxDropped, err = strconv.ParseUint(fields[11], 10, 64) 163 | if err != nil { 164 | return nil, err 165 | } 166 | line.TxFIFO, err = strconv.ParseUint(fields[12], 10, 64) 167 | if err != nil { 168 | return nil, err 169 | } 170 | line.TxCollisions, err = strconv.ParseUint(fields[13], 10, 64) 171 | if err != nil { 172 | return nil, err 173 | } 174 | line.TxCarrier, err = strconv.ParseUint(fields[14], 10, 64) 175 | if err != nil { 176 | return nil, err 177 | } 178 | line.TxCompressed, err = strconv.ParseUint(fields[15], 10, 64) 179 | if err != nil { 180 | return nil, err 181 | } 182 | 183 | return line, nil 184 | } 185 | 186 | // Total aggregates the values across interfaces and returns a new NetDevLine. 187 | // The Name field will be a sorted comma separated list of interface names. 188 | func (nd NetDev) Total() NetDevLine { 189 | total := NetDevLine{} 190 | 191 | names := make([]string, 0, len(nd)) 192 | for _, ifc := range nd { 193 | names = append(names, ifc.Name) 194 | total.RxBytes += ifc.RxBytes 195 | total.RxPackets += ifc.RxPackets 196 | total.RxPackets += ifc.RxPackets 197 | total.RxErrors += ifc.RxErrors 198 | total.RxDropped += ifc.RxDropped 199 | total.RxFIFO += ifc.RxFIFO 200 | total.RxFrame += ifc.RxFrame 201 | total.RxCompressed += ifc.RxCompressed 202 | total.RxMulticast += ifc.RxMulticast 203 | total.TxBytes += ifc.TxBytes 204 | total.TxPackets += ifc.TxPackets 205 | total.TxErrors += ifc.TxErrors 206 | total.TxDropped += ifc.TxDropped 207 | total.TxFIFO += ifc.TxFIFO 208 | total.TxCollisions += ifc.TxCollisions 209 | total.TxCarrier += ifc.TxCarrier 210 | total.TxCompressed += ifc.TxCompressed 211 | } 212 | sort.Strings(names) 213 | total.Name = strings.Join(names, ", ") 214 | 215 | return total 216 | } 217 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/procfs/ipvs.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package procfs 15 | 16 | import ( 17 | "bufio" 18 | "encoding/hex" 19 | "errors" 20 | "fmt" 21 | "io" 22 | "io/ioutil" 23 | "net" 24 | "os" 25 | "strconv" 26 | "strings" 27 | ) 28 | 29 | // IPVSStats holds IPVS statistics, as exposed by the kernel in `/proc/net/ip_vs_stats`. 30 | type IPVSStats struct { 31 | // Total count of connections. 32 | Connections uint64 33 | // Total incoming packages processed. 34 | IncomingPackets uint64 35 | // Total outgoing packages processed. 36 | OutgoingPackets uint64 37 | // Total incoming traffic. 38 | IncomingBytes uint64 39 | // Total outgoing traffic. 40 | OutgoingBytes uint64 41 | } 42 | 43 | // IPVSBackendStatus holds current metrics of one virtual / real address pair. 44 | type IPVSBackendStatus struct { 45 | // The local (virtual) IP address. 46 | LocalAddress net.IP 47 | // The remote (real) IP address. 48 | RemoteAddress net.IP 49 | // The local (virtual) port. 50 | LocalPort uint16 51 | // The remote (real) port. 52 | RemotePort uint16 53 | // The local firewall mark 54 | LocalMark string 55 | // The transport protocol (TCP, UDP). 56 | Proto string 57 | // The current number of active connections for this virtual/real address pair. 58 | ActiveConn uint64 59 | // The current number of inactive connections for this virtual/real address pair. 60 | InactConn uint64 61 | // The current weight of this virtual/real address pair. 62 | Weight uint64 63 | } 64 | 65 | // NewIPVSStats reads the IPVS statistics. 66 | func NewIPVSStats() (IPVSStats, error) { 67 | fs, err := NewFS(DefaultMountPoint) 68 | if err != nil { 69 | return IPVSStats{}, err 70 | } 71 | 72 | return fs.NewIPVSStats() 73 | } 74 | 75 | // NewIPVSStats reads the IPVS statistics from the specified `proc` filesystem. 76 | func (fs FS) NewIPVSStats() (IPVSStats, error) { 77 | file, err := os.Open(fs.Path("net/ip_vs_stats")) 78 | if err != nil { 79 | return IPVSStats{}, err 80 | } 81 | defer file.Close() 82 | 83 | return parseIPVSStats(file) 84 | } 85 | 86 | // parseIPVSStats performs the actual parsing of `ip_vs_stats`. 87 | func parseIPVSStats(file io.Reader) (IPVSStats, error) { 88 | var ( 89 | statContent []byte 90 | statLines []string 91 | statFields []string 92 | stats IPVSStats 93 | ) 94 | 95 | statContent, err := ioutil.ReadAll(file) 96 | if err != nil { 97 | return IPVSStats{}, err 98 | } 99 | 100 | statLines = strings.SplitN(string(statContent), "\n", 4) 101 | if len(statLines) != 4 { 102 | return IPVSStats{}, errors.New("ip_vs_stats corrupt: too short") 103 | } 104 | 105 | statFields = strings.Fields(statLines[2]) 106 | if len(statFields) != 5 { 107 | return IPVSStats{}, errors.New("ip_vs_stats corrupt: unexpected number of fields") 108 | } 109 | 110 | stats.Connections, err = strconv.ParseUint(statFields[0], 16, 64) 111 | if err != nil { 112 | return IPVSStats{}, err 113 | } 114 | stats.IncomingPackets, err = strconv.ParseUint(statFields[1], 16, 64) 115 | if err != nil { 116 | return IPVSStats{}, err 117 | } 118 | stats.OutgoingPackets, err = strconv.ParseUint(statFields[2], 16, 64) 119 | if err != nil { 120 | return IPVSStats{}, err 121 | } 122 | stats.IncomingBytes, err = strconv.ParseUint(statFields[3], 16, 64) 123 | if err != nil { 124 | return IPVSStats{}, err 125 | } 126 | stats.OutgoingBytes, err = strconv.ParseUint(statFields[4], 16, 64) 127 | if err != nil { 128 | return IPVSStats{}, err 129 | } 130 | 131 | return stats, nil 132 | } 133 | 134 | // NewIPVSBackendStatus reads and returns the status of all (virtual,real) server pairs. 135 | func NewIPVSBackendStatus() ([]IPVSBackendStatus, error) { 136 | fs, err := NewFS(DefaultMountPoint) 137 | if err != nil { 138 | return []IPVSBackendStatus{}, err 139 | } 140 | 141 | return fs.NewIPVSBackendStatus() 142 | } 143 | 144 | // NewIPVSBackendStatus reads and returns the status of all (virtual,real) server pairs from the specified `proc` filesystem. 145 | func (fs FS) NewIPVSBackendStatus() ([]IPVSBackendStatus, error) { 146 | file, err := os.Open(fs.Path("net/ip_vs")) 147 | if err != nil { 148 | return nil, err 149 | } 150 | defer file.Close() 151 | 152 | return parseIPVSBackendStatus(file) 153 | } 154 | 155 | func parseIPVSBackendStatus(file io.Reader) ([]IPVSBackendStatus, error) { 156 | var ( 157 | status []IPVSBackendStatus 158 | scanner = bufio.NewScanner(file) 159 | proto string 160 | localMark string 161 | localAddress net.IP 162 | localPort uint16 163 | err error 164 | ) 165 | 166 | for scanner.Scan() { 167 | fields := strings.Fields(scanner.Text()) 168 | if len(fields) == 0 { 169 | continue 170 | } 171 | switch { 172 | case fields[0] == "IP" || fields[0] == "Prot" || fields[1] == "RemoteAddress:Port": 173 | continue 174 | case fields[0] == "TCP" || fields[0] == "UDP": 175 | if len(fields) < 2 { 176 | continue 177 | } 178 | proto = fields[0] 179 | localMark = "" 180 | localAddress, localPort, err = parseIPPort(fields[1]) 181 | if err != nil { 182 | return nil, err 183 | } 184 | case fields[0] == "FWM": 185 | if len(fields) < 2 { 186 | continue 187 | } 188 | proto = fields[0] 189 | localMark = fields[1] 190 | localAddress = nil 191 | localPort = 0 192 | case fields[0] == "->": 193 | if len(fields) < 6 { 194 | continue 195 | } 196 | remoteAddress, remotePort, err := parseIPPort(fields[1]) 197 | if err != nil { 198 | return nil, err 199 | } 200 | weight, err := strconv.ParseUint(fields[3], 10, 64) 201 | if err != nil { 202 | return nil, err 203 | } 204 | activeConn, err := strconv.ParseUint(fields[4], 10, 64) 205 | if err != nil { 206 | return nil, err 207 | } 208 | inactConn, err := strconv.ParseUint(fields[5], 10, 64) 209 | if err != nil { 210 | return nil, err 211 | } 212 | status = append(status, IPVSBackendStatus{ 213 | LocalAddress: localAddress, 214 | LocalPort: localPort, 215 | LocalMark: localMark, 216 | RemoteAddress: remoteAddress, 217 | RemotePort: remotePort, 218 | Proto: proto, 219 | Weight: weight, 220 | ActiveConn: activeConn, 221 | InactConn: inactConn, 222 | }) 223 | } 224 | } 225 | return status, nil 226 | } 227 | 228 | func parseIPPort(s string) (net.IP, uint16, error) { 229 | var ( 230 | ip net.IP 231 | err error 232 | ) 233 | 234 | switch len(s) { 235 | case 13: 236 | ip, err = hex.DecodeString(s[0:8]) 237 | if err != nil { 238 | return nil, 0, err 239 | } 240 | case 46: 241 | ip = net.ParseIP(s[1:40]) 242 | if ip == nil { 243 | return nil, 0, fmt.Errorf("invalid IPv6 address: %s", s[1:40]) 244 | } 245 | default: 246 | return nil, 0, fmt.Errorf("unexpected IP:Port: %s", s) 247 | } 248 | 249 | portString := s[len(s)-4:] 250 | if len(portString) != 4 { 251 | return nil, 0, fmt.Errorf("unexpected port string format: %s", portString) 252 | } 253 | port, err := strconv.ParseUint(portString, 16, 16) 254 | if err != nil { 255 | return nil, 0, err 256 | } 257 | 258 | return ip, uint16(port), nil 259 | } 260 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/common/model/time.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package model 15 | 16 | import ( 17 | "fmt" 18 | "math" 19 | "regexp" 20 | "strconv" 21 | "strings" 22 | "time" 23 | ) 24 | 25 | const ( 26 | // MinimumTick is the minimum supported time resolution. This has to be 27 | // at least time.Second in order for the code below to work. 28 | minimumTick = time.Millisecond 29 | // second is the Time duration equivalent to one second. 30 | second = int64(time.Second / minimumTick) 31 | // The number of nanoseconds per minimum tick. 32 | nanosPerTick = int64(minimumTick / time.Nanosecond) 33 | 34 | // Earliest is the earliest Time representable. Handy for 35 | // initializing a high watermark. 36 | Earliest = Time(math.MinInt64) 37 | // Latest is the latest Time representable. Handy for initializing 38 | // a low watermark. 39 | Latest = Time(math.MaxInt64) 40 | ) 41 | 42 | // Time is the number of milliseconds since the epoch 43 | // (1970-01-01 00:00 UTC) excluding leap seconds. 44 | type Time int64 45 | 46 | // Interval describes and interval between two timestamps. 47 | type Interval struct { 48 | Start, End Time 49 | } 50 | 51 | // Now returns the current time as a Time. 52 | func Now() Time { 53 | return TimeFromUnixNano(time.Now().UnixNano()) 54 | } 55 | 56 | // TimeFromUnix returns the Time equivalent to the Unix Time t 57 | // provided in seconds. 58 | func TimeFromUnix(t int64) Time { 59 | return Time(t * second) 60 | } 61 | 62 | // TimeFromUnixNano returns the Time equivalent to the Unix Time 63 | // t provided in nanoseconds. 64 | func TimeFromUnixNano(t int64) Time { 65 | return Time(t / nanosPerTick) 66 | } 67 | 68 | // Equal reports whether two Times represent the same instant. 69 | func (t Time) Equal(o Time) bool { 70 | return t == o 71 | } 72 | 73 | // Before reports whether the Time t is before o. 74 | func (t Time) Before(o Time) bool { 75 | return t < o 76 | } 77 | 78 | // After reports whether the Time t is after o. 79 | func (t Time) After(o Time) bool { 80 | return t > o 81 | } 82 | 83 | // Add returns the Time t + d. 84 | func (t Time) Add(d time.Duration) Time { 85 | return t + Time(d/minimumTick) 86 | } 87 | 88 | // Sub returns the Duration t - o. 89 | func (t Time) Sub(o Time) time.Duration { 90 | return time.Duration(t-o) * minimumTick 91 | } 92 | 93 | // Time returns the time.Time representation of t. 94 | func (t Time) Time() time.Time { 95 | return time.Unix(int64(t)/second, (int64(t)%second)*nanosPerTick) 96 | } 97 | 98 | // Unix returns t as a Unix time, the number of seconds elapsed 99 | // since January 1, 1970 UTC. 100 | func (t Time) Unix() int64 { 101 | return int64(t) / second 102 | } 103 | 104 | // UnixNano returns t as a Unix time, the number of nanoseconds elapsed 105 | // since January 1, 1970 UTC. 106 | func (t Time) UnixNano() int64 { 107 | return int64(t) * nanosPerTick 108 | } 109 | 110 | // The number of digits after the dot. 111 | var dotPrecision = int(math.Log10(float64(second))) 112 | 113 | // String returns a string representation of the Time. 114 | func (t Time) String() string { 115 | return strconv.FormatFloat(float64(t)/float64(second), 'f', -1, 64) 116 | } 117 | 118 | // MarshalJSON implements the json.Marshaler interface. 119 | func (t Time) MarshalJSON() ([]byte, error) { 120 | return []byte(t.String()), nil 121 | } 122 | 123 | // UnmarshalJSON implements the json.Unmarshaler interface. 124 | func (t *Time) UnmarshalJSON(b []byte) error { 125 | p := strings.Split(string(b), ".") 126 | switch len(p) { 127 | case 1: 128 | v, err := strconv.ParseInt(string(p[0]), 10, 64) 129 | if err != nil { 130 | return err 131 | } 132 | *t = Time(v * second) 133 | 134 | case 2: 135 | v, err := strconv.ParseInt(string(p[0]), 10, 64) 136 | if err != nil { 137 | return err 138 | } 139 | v *= second 140 | 141 | prec := dotPrecision - len(p[1]) 142 | if prec < 0 { 143 | p[1] = p[1][:dotPrecision] 144 | } else if prec > 0 { 145 | p[1] = p[1] + strings.Repeat("0", prec) 146 | } 147 | 148 | va, err := strconv.ParseInt(p[1], 10, 32) 149 | if err != nil { 150 | return err 151 | } 152 | 153 | *t = Time(v + va) 154 | 155 | default: 156 | return fmt.Errorf("invalid time %q", string(b)) 157 | } 158 | return nil 159 | } 160 | 161 | // Duration wraps time.Duration. It is used to parse the custom duration format 162 | // from YAML. 163 | // This type should not propagate beyond the scope of input/output processing. 164 | type Duration time.Duration 165 | 166 | // Set implements pflag/flag.Value 167 | func (d *Duration) Set(s string) error { 168 | var err error 169 | *d, err = ParseDuration(s) 170 | return err 171 | } 172 | 173 | // Type implements pflag.Value 174 | func (d *Duration) Type() string { 175 | return "duration" 176 | } 177 | 178 | var durationRE = regexp.MustCompile("^([0-9]+)(y|w|d|h|m|s|ms)$") 179 | 180 | // ParseDuration parses a string into a time.Duration, assuming that a year 181 | // always has 365d, a week always has 7d, and a day always has 24h. 182 | func ParseDuration(durationStr string) (Duration, error) { 183 | matches := durationRE.FindStringSubmatch(durationStr) 184 | if len(matches) != 3 { 185 | return 0, fmt.Errorf("not a valid duration string: %q", durationStr) 186 | } 187 | var ( 188 | n, _ = strconv.Atoi(matches[1]) 189 | dur = time.Duration(n) * time.Millisecond 190 | ) 191 | switch unit := matches[2]; unit { 192 | case "y": 193 | dur *= 1000 * 60 * 60 * 24 * 365 194 | case "w": 195 | dur *= 1000 * 60 * 60 * 24 * 7 196 | case "d": 197 | dur *= 1000 * 60 * 60 * 24 198 | case "h": 199 | dur *= 1000 * 60 * 60 200 | case "m": 201 | dur *= 1000 * 60 202 | case "s": 203 | dur *= 1000 204 | case "ms": 205 | // Value already correct 206 | default: 207 | return 0, fmt.Errorf("invalid time unit in duration string: %q", unit) 208 | } 209 | return Duration(dur), nil 210 | } 211 | 212 | func (d Duration) String() string { 213 | var ( 214 | ms = int64(time.Duration(d) / time.Millisecond) 215 | unit = "ms" 216 | ) 217 | if ms == 0 { 218 | return "0s" 219 | } 220 | factors := map[string]int64{ 221 | "y": 1000 * 60 * 60 * 24 * 365, 222 | "w": 1000 * 60 * 60 * 24 * 7, 223 | "d": 1000 * 60 * 60 * 24, 224 | "h": 1000 * 60 * 60, 225 | "m": 1000 * 60, 226 | "s": 1000, 227 | "ms": 1, 228 | } 229 | 230 | switch int64(0) { 231 | case ms % factors["y"]: 232 | unit = "y" 233 | case ms % factors["w"]: 234 | unit = "w" 235 | case ms % factors["d"]: 236 | unit = "d" 237 | case ms % factors["h"]: 238 | unit = "h" 239 | case ms % factors["m"]: 240 | unit = "m" 241 | case ms % factors["s"]: 242 | unit = "s" 243 | } 244 | return fmt.Sprintf("%v%v", ms/factors[unit], unit) 245 | } 246 | 247 | // MarshalYAML implements the yaml.Marshaler interface. 248 | func (d Duration) MarshalYAML() (interface{}, error) { 249 | return d.String(), nil 250 | } 251 | 252 | // UnmarshalYAML implements the yaml.Unmarshaler interface. 253 | func (d *Duration) UnmarshalYAML(unmarshal func(interface{}) error) error { 254 | var s string 255 | if err := unmarshal(&s); err != nil { 256 | return err 257 | } 258 | dur, err := ParseDuration(s) 259 | if err != nil { 260 | return err 261 | } 262 | *d = dur 263 | return nil 264 | } 265 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // Copyright (c) 2013, The Prometheus Authors 15 | // All rights reserved. 16 | // 17 | // Use of this source code is governed by a BSD-style license that can be found 18 | // in the LICENSE file. 19 | 20 | // Package promhttp contains functions to create http.Handler instances to 21 | // expose Prometheus metrics via HTTP. In later versions of this package, it 22 | // will also contain tooling to instrument instances of http.Handler and 23 | // http.RoundTripper. 24 | // 25 | // promhttp.Handler acts on the prometheus.DefaultGatherer. With HandlerFor, 26 | // you can create a handler for a custom registry or anything that implements 27 | // the Gatherer interface. It also allows to create handlers that act 28 | // differently on errors or allow to log errors. 29 | package promhttp 30 | 31 | import ( 32 | "bytes" 33 | "compress/gzip" 34 | "fmt" 35 | "io" 36 | "net/http" 37 | "strings" 38 | "sync" 39 | 40 | "github.com/prometheus/common/expfmt" 41 | 42 | "github.com/prometheus/client_golang/prometheus" 43 | ) 44 | 45 | const ( 46 | contentTypeHeader = "Content-Type" 47 | contentLengthHeader = "Content-Length" 48 | contentEncodingHeader = "Content-Encoding" 49 | acceptEncodingHeader = "Accept-Encoding" 50 | ) 51 | 52 | var bufPool sync.Pool 53 | 54 | func getBuf() *bytes.Buffer { 55 | buf := bufPool.Get() 56 | if buf == nil { 57 | return &bytes.Buffer{} 58 | } 59 | return buf.(*bytes.Buffer) 60 | } 61 | 62 | func giveBuf(buf *bytes.Buffer) { 63 | buf.Reset() 64 | bufPool.Put(buf) 65 | } 66 | 67 | // Handler returns an HTTP handler for the prometheus.DefaultGatherer. The 68 | // Handler uses the default HandlerOpts, i.e. report the first error as an HTTP 69 | // error, no error logging, and compression if requested by the client. 70 | // 71 | // If you want to create a Handler for the DefaultGatherer with different 72 | // HandlerOpts, create it with HandlerFor with prometheus.DefaultGatherer and 73 | // your desired HandlerOpts. 74 | func Handler() http.Handler { 75 | return HandlerFor(prometheus.DefaultGatherer, HandlerOpts{}) 76 | } 77 | 78 | // HandlerFor returns an http.Handler for the provided Gatherer. The behavior 79 | // of the Handler is defined by the provided HandlerOpts. 80 | func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler { 81 | return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 82 | mfs, err := reg.Gather() 83 | if err != nil { 84 | if opts.ErrorLog != nil { 85 | opts.ErrorLog.Println("error gathering metrics:", err) 86 | } 87 | switch opts.ErrorHandling { 88 | case PanicOnError: 89 | panic(err) 90 | case ContinueOnError: 91 | if len(mfs) == 0 { 92 | http.Error(w, "No metrics gathered, last error:\n\n"+err.Error(), http.StatusInternalServerError) 93 | return 94 | } 95 | case HTTPErrorOnError: 96 | http.Error(w, "An error has occurred during metrics gathering:\n\n"+err.Error(), http.StatusInternalServerError) 97 | return 98 | } 99 | } 100 | 101 | contentType := expfmt.Negotiate(req.Header) 102 | buf := getBuf() 103 | defer giveBuf(buf) 104 | writer, encoding := decorateWriter(req, buf, opts.DisableCompression) 105 | enc := expfmt.NewEncoder(writer, contentType) 106 | var lastErr error 107 | for _, mf := range mfs { 108 | if err := enc.Encode(mf); err != nil { 109 | lastErr = err 110 | if opts.ErrorLog != nil { 111 | opts.ErrorLog.Println("error encoding metric family:", err) 112 | } 113 | switch opts.ErrorHandling { 114 | case PanicOnError: 115 | panic(err) 116 | case ContinueOnError: 117 | // Handled later. 118 | case HTTPErrorOnError: 119 | http.Error(w, "An error has occurred during metrics encoding:\n\n"+err.Error(), http.StatusInternalServerError) 120 | return 121 | } 122 | } 123 | } 124 | if closer, ok := writer.(io.Closer); ok { 125 | closer.Close() 126 | } 127 | if lastErr != nil && buf.Len() == 0 { 128 | http.Error(w, "No metrics encoded, last error:\n\n"+err.Error(), http.StatusInternalServerError) 129 | return 130 | } 131 | header := w.Header() 132 | header.Set(contentTypeHeader, string(contentType)) 133 | header.Set(contentLengthHeader, fmt.Sprint(buf.Len())) 134 | if encoding != "" { 135 | header.Set(contentEncodingHeader, encoding) 136 | } 137 | w.Write(buf.Bytes()) 138 | // TODO(beorn7): Consider streaming serving of metrics. 139 | }) 140 | } 141 | 142 | // HandlerErrorHandling defines how a Handler serving metrics will handle 143 | // errors. 144 | type HandlerErrorHandling int 145 | 146 | // These constants cause handlers serving metrics to behave as described if 147 | // errors are encountered. 148 | const ( 149 | // Serve an HTTP status code 500 upon the first error 150 | // encountered. Report the error message in the body. 151 | HTTPErrorOnError HandlerErrorHandling = iota 152 | // Ignore errors and try to serve as many metrics as possible. However, 153 | // if no metrics can be served, serve an HTTP status code 500 and the 154 | // last error message in the body. Only use this in deliberate "best 155 | // effort" metrics collection scenarios. It is recommended to at least 156 | // log errors (by providing an ErrorLog in HandlerOpts) to not mask 157 | // errors completely. 158 | ContinueOnError 159 | // Panic upon the first error encountered (useful for "crash only" apps). 160 | PanicOnError 161 | ) 162 | 163 | // Logger is the minimal interface HandlerOpts needs for logging. Note that 164 | // log.Logger from the standard library implements this interface, and it is 165 | // easy to implement by custom loggers, if they don't do so already anyway. 166 | type Logger interface { 167 | Println(v ...interface{}) 168 | } 169 | 170 | // HandlerOpts specifies options how to serve metrics via an http.Handler. The 171 | // zero value of HandlerOpts is a reasonable default. 172 | type HandlerOpts struct { 173 | // ErrorLog specifies an optional logger for errors collecting and 174 | // serving metrics. If nil, errors are not logged at all. 175 | ErrorLog Logger 176 | // ErrorHandling defines how errors are handled. Note that errors are 177 | // logged regardless of the configured ErrorHandling provided ErrorLog 178 | // is not nil. 179 | ErrorHandling HandlerErrorHandling 180 | // If DisableCompression is true, the handler will never compress the 181 | // response, even if requested by the client. 182 | DisableCompression bool 183 | } 184 | 185 | // decorateWriter wraps a writer to handle gzip compression if requested. It 186 | // returns the decorated writer and the appropriate "Content-Encoding" header 187 | // (which is empty if no compression is enabled). 188 | func decorateWriter(request *http.Request, writer io.Writer, compressionDisabled bool) (io.Writer, string) { 189 | if compressionDisabled { 190 | return writer, "" 191 | } 192 | header := request.Header.Get(acceptEncodingHeader) 193 | parts := strings.Split(header, ",") 194 | for _, part := range parts { 195 | part := strings.TrimSpace(part) 196 | if part == "gzip" || strings.HasPrefix(part, "gzip;") { 197 | return gzip.NewWriter(writer), "gzip" 198 | } 199 | } 200 | return writer, "" 201 | } 202 | -------------------------------------------------------------------------------- /vendor/github.com/prometheus/client_golang/prometheus/value.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package prometheus 15 | 16 | import ( 17 | "errors" 18 | "fmt" 19 | "math" 20 | "sort" 21 | "sync/atomic" 22 | 23 | dto "github.com/prometheus/client_model/go" 24 | 25 | "github.com/golang/protobuf/proto" 26 | ) 27 | 28 | // ValueType is an enumeration of metric types that represent a simple value. 29 | type ValueType int 30 | 31 | // Possible values for the ValueType enum. 32 | const ( 33 | _ ValueType = iota 34 | CounterValue 35 | GaugeValue 36 | UntypedValue 37 | ) 38 | 39 | var errInconsistentCardinality = errors.New("inconsistent label cardinality") 40 | 41 | // value is a generic metric for simple values. It implements Metric, Collector, 42 | // Counter, Gauge, and Untyped. Its effective type is determined by 43 | // ValueType. This is a low-level building block used by the library to back the 44 | // implementations of Counter, Gauge, and Untyped. 45 | type value struct { 46 | // valBits containst the bits of the represented float64 value. It has 47 | // to go first in the struct to guarantee alignment for atomic 48 | // operations. http://golang.org/pkg/sync/atomic/#pkg-note-BUG 49 | valBits uint64 50 | 51 | selfCollector 52 | 53 | desc *Desc 54 | valType ValueType 55 | labelPairs []*dto.LabelPair 56 | } 57 | 58 | // newValue returns a newly allocated value with the given Desc, ValueType, 59 | // sample value and label values. It panics if the number of label 60 | // values is different from the number of variable labels in Desc. 61 | func newValue(desc *Desc, valueType ValueType, val float64, labelValues ...string) *value { 62 | if len(labelValues) != len(desc.variableLabels) { 63 | panic(errInconsistentCardinality) 64 | } 65 | result := &value{ 66 | desc: desc, 67 | valType: valueType, 68 | valBits: math.Float64bits(val), 69 | labelPairs: makeLabelPairs(desc, labelValues), 70 | } 71 | result.init(result) 72 | return result 73 | } 74 | 75 | func (v *value) Desc() *Desc { 76 | return v.desc 77 | } 78 | 79 | func (v *value) Set(val float64) { 80 | atomic.StoreUint64(&v.valBits, math.Float64bits(val)) 81 | } 82 | 83 | func (v *value) Inc() { 84 | v.Add(1) 85 | } 86 | 87 | func (v *value) Dec() { 88 | v.Add(-1) 89 | } 90 | 91 | func (v *value) Add(val float64) { 92 | for { 93 | oldBits := atomic.LoadUint64(&v.valBits) 94 | newBits := math.Float64bits(math.Float64frombits(oldBits) + val) 95 | if atomic.CompareAndSwapUint64(&v.valBits, oldBits, newBits) { 96 | return 97 | } 98 | } 99 | } 100 | 101 | func (v *value) Sub(val float64) { 102 | v.Add(val * -1) 103 | } 104 | 105 | func (v *value) Write(out *dto.Metric) error { 106 | val := math.Float64frombits(atomic.LoadUint64(&v.valBits)) 107 | return populateMetric(v.valType, val, v.labelPairs, out) 108 | } 109 | 110 | // valueFunc is a generic metric for simple values retrieved on collect time 111 | // from a function. It implements Metric and Collector. Its effective type is 112 | // determined by ValueType. This is a low-level building block used by the 113 | // library to back the implementations of CounterFunc, GaugeFunc, and 114 | // UntypedFunc. 115 | type valueFunc struct { 116 | selfCollector 117 | 118 | desc *Desc 119 | valType ValueType 120 | function func() float64 121 | labelPairs []*dto.LabelPair 122 | } 123 | 124 | // newValueFunc returns a newly allocated valueFunc with the given Desc and 125 | // ValueType. The value reported is determined by calling the given function 126 | // from within the Write method. Take into account that metric collection may 127 | // happen concurrently. If that results in concurrent calls to Write, like in 128 | // the case where a valueFunc is directly registered with Prometheus, the 129 | // provided function must be concurrency-safe. 130 | func newValueFunc(desc *Desc, valueType ValueType, function func() float64) *valueFunc { 131 | result := &valueFunc{ 132 | desc: desc, 133 | valType: valueType, 134 | function: function, 135 | labelPairs: makeLabelPairs(desc, nil), 136 | } 137 | result.init(result) 138 | return result 139 | } 140 | 141 | func (v *valueFunc) Desc() *Desc { 142 | return v.desc 143 | } 144 | 145 | func (v *valueFunc) Write(out *dto.Metric) error { 146 | return populateMetric(v.valType, v.function(), v.labelPairs, out) 147 | } 148 | 149 | // NewConstMetric returns a metric with one fixed value that cannot be 150 | // changed. Users of this package will not have much use for it in regular 151 | // operations. However, when implementing custom Collectors, it is useful as a 152 | // throw-away metric that is generated on the fly to send it to Prometheus in 153 | // the Collect method. NewConstMetric returns an error if the length of 154 | // labelValues is not consistent with the variable labels in Desc. 155 | func NewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) (Metric, error) { 156 | if len(desc.variableLabels) != len(labelValues) { 157 | return nil, errInconsistentCardinality 158 | } 159 | return &constMetric{ 160 | desc: desc, 161 | valType: valueType, 162 | val: value, 163 | labelPairs: makeLabelPairs(desc, labelValues), 164 | }, nil 165 | } 166 | 167 | // MustNewConstMetric is a version of NewConstMetric that panics where 168 | // NewConstMetric would have returned an error. 169 | func MustNewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) Metric { 170 | m, err := NewConstMetric(desc, valueType, value, labelValues...) 171 | if err != nil { 172 | panic(err) 173 | } 174 | return m 175 | } 176 | 177 | type constMetric struct { 178 | desc *Desc 179 | valType ValueType 180 | val float64 181 | labelPairs []*dto.LabelPair 182 | } 183 | 184 | func (m *constMetric) Desc() *Desc { 185 | return m.desc 186 | } 187 | 188 | func (m *constMetric) Write(out *dto.Metric) error { 189 | return populateMetric(m.valType, m.val, m.labelPairs, out) 190 | } 191 | 192 | func populateMetric( 193 | t ValueType, 194 | v float64, 195 | labelPairs []*dto.LabelPair, 196 | m *dto.Metric, 197 | ) error { 198 | m.Label = labelPairs 199 | switch t { 200 | case CounterValue: 201 | m.Counter = &dto.Counter{Value: proto.Float64(v)} 202 | case GaugeValue: 203 | m.Gauge = &dto.Gauge{Value: proto.Float64(v)} 204 | case UntypedValue: 205 | m.Untyped = &dto.Untyped{Value: proto.Float64(v)} 206 | default: 207 | return fmt.Errorf("encountered unknown type %v", t) 208 | } 209 | return nil 210 | } 211 | 212 | func makeLabelPairs(desc *Desc, labelValues []string) []*dto.LabelPair { 213 | totalLen := len(desc.variableLabels) + len(desc.constLabelPairs) 214 | if totalLen == 0 { 215 | // Super fast path. 216 | return nil 217 | } 218 | if len(desc.variableLabels) == 0 { 219 | // Moderately fast path. 220 | return desc.constLabelPairs 221 | } 222 | labelPairs := make([]*dto.LabelPair, 0, totalLen) 223 | for i, n := range desc.variableLabels { 224 | labelPairs = append(labelPairs, &dto.LabelPair{ 225 | Name: proto.String(n), 226 | Value: proto.String(labelValues[i]), 227 | }) 228 | } 229 | for _, lp := range desc.constLabelPairs { 230 | labelPairs = append(labelPairs, lp) 231 | } 232 | sort.Sort(LabelPairSorter(labelPairs)) 233 | return labelPairs 234 | } 235 | -------------------------------------------------------------------------------- /vendor/github.com/golang/protobuf/proto/encode.go: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2010 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | package proto 33 | 34 | /* 35 | * Routines for encoding data into the wire format for protocol buffers. 36 | */ 37 | 38 | import ( 39 | "errors" 40 | "fmt" 41 | "reflect" 42 | ) 43 | 44 | // RequiredNotSetError is the error returned if Marshal is called with 45 | // a protocol buffer struct whose required fields have not 46 | // all been initialized. It is also the error returned if Unmarshal is 47 | // called with an encoded protocol buffer that does not include all the 48 | // required fields. 49 | // 50 | // When printed, RequiredNotSetError reports the first unset required field in a 51 | // message. If the field cannot be precisely determined, it is reported as 52 | // "{Unknown}". 53 | type RequiredNotSetError struct { 54 | field string 55 | } 56 | 57 | func (e *RequiredNotSetError) Error() string { 58 | return fmt.Sprintf("proto: required field %q not set", e.field) 59 | } 60 | 61 | var ( 62 | // errRepeatedHasNil is the error returned if Marshal is called with 63 | // a struct with a repeated field containing a nil element. 64 | errRepeatedHasNil = errors.New("proto: repeated field has nil element") 65 | 66 | // errOneofHasNil is the error returned if Marshal is called with 67 | // a struct with a oneof field containing a nil element. 68 | errOneofHasNil = errors.New("proto: oneof field has nil value") 69 | 70 | // ErrNil is the error returned if Marshal is called with nil. 71 | ErrNil = errors.New("proto: Marshal called with nil") 72 | 73 | // ErrTooLarge is the error returned if Marshal is called with a 74 | // message that encodes to >2GB. 75 | ErrTooLarge = errors.New("proto: message encodes to over 2 GB") 76 | ) 77 | 78 | // The fundamental encoders that put bytes on the wire. 79 | // Those that take integer types all accept uint64 and are 80 | // therefore of type valueEncoder. 81 | 82 | const maxVarintBytes = 10 // maximum length of a varint 83 | 84 | // EncodeVarint returns the varint encoding of x. 85 | // This is the format for the 86 | // int32, int64, uint32, uint64, bool, and enum 87 | // protocol buffer types. 88 | // Not used by the package itself, but helpful to clients 89 | // wishing to use the same encoding. 90 | func EncodeVarint(x uint64) []byte { 91 | var buf [maxVarintBytes]byte 92 | var n int 93 | for n = 0; x > 127; n++ { 94 | buf[n] = 0x80 | uint8(x&0x7F) 95 | x >>= 7 96 | } 97 | buf[n] = uint8(x) 98 | n++ 99 | return buf[0:n] 100 | } 101 | 102 | // EncodeVarint writes a varint-encoded integer to the Buffer. 103 | // This is the format for the 104 | // int32, int64, uint32, uint64, bool, and enum 105 | // protocol buffer types. 106 | func (p *Buffer) EncodeVarint(x uint64) error { 107 | for x >= 1<<7 { 108 | p.buf = append(p.buf, uint8(x&0x7f|0x80)) 109 | x >>= 7 110 | } 111 | p.buf = append(p.buf, uint8(x)) 112 | return nil 113 | } 114 | 115 | // SizeVarint returns the varint encoding size of an integer. 116 | func SizeVarint(x uint64) int { 117 | switch { 118 | case x < 1<<7: 119 | return 1 120 | case x < 1<<14: 121 | return 2 122 | case x < 1<<21: 123 | return 3 124 | case x < 1<<28: 125 | return 4 126 | case x < 1<<35: 127 | return 5 128 | case x < 1<<42: 129 | return 6 130 | case x < 1<<49: 131 | return 7 132 | case x < 1<<56: 133 | return 8 134 | case x < 1<<63: 135 | return 9 136 | } 137 | return 10 138 | } 139 | 140 | // EncodeFixed64 writes a 64-bit integer to the Buffer. 141 | // This is the format for the 142 | // fixed64, sfixed64, and double protocol buffer types. 143 | func (p *Buffer) EncodeFixed64(x uint64) error { 144 | p.buf = append(p.buf, 145 | uint8(x), 146 | uint8(x>>8), 147 | uint8(x>>16), 148 | uint8(x>>24), 149 | uint8(x>>32), 150 | uint8(x>>40), 151 | uint8(x>>48), 152 | uint8(x>>56)) 153 | return nil 154 | } 155 | 156 | // EncodeFixed32 writes a 32-bit integer to the Buffer. 157 | // This is the format for the 158 | // fixed32, sfixed32, and float protocol buffer types. 159 | func (p *Buffer) EncodeFixed32(x uint64) error { 160 | p.buf = append(p.buf, 161 | uint8(x), 162 | uint8(x>>8), 163 | uint8(x>>16), 164 | uint8(x>>24)) 165 | return nil 166 | } 167 | 168 | // EncodeZigzag64 writes a zigzag-encoded 64-bit integer 169 | // to the Buffer. 170 | // This is the format used for the sint64 protocol buffer type. 171 | func (p *Buffer) EncodeZigzag64(x uint64) error { 172 | // use signed number to get arithmetic right shift. 173 | return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63)))) 174 | } 175 | 176 | // EncodeZigzag32 writes a zigzag-encoded 32-bit integer 177 | // to the Buffer. 178 | // This is the format used for the sint32 protocol buffer type. 179 | func (p *Buffer) EncodeZigzag32(x uint64) error { 180 | // use signed number to get arithmetic right shift. 181 | return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31)))) 182 | } 183 | 184 | // EncodeRawBytes writes a count-delimited byte buffer to the Buffer. 185 | // This is the format used for the bytes protocol buffer 186 | // type and for embedded messages. 187 | func (p *Buffer) EncodeRawBytes(b []byte) error { 188 | p.EncodeVarint(uint64(len(b))) 189 | p.buf = append(p.buf, b...) 190 | return nil 191 | } 192 | 193 | // EncodeStringBytes writes an encoded string to the Buffer. 194 | // This is the format used for the proto2 string type. 195 | func (p *Buffer) EncodeStringBytes(s string) error { 196 | p.EncodeVarint(uint64(len(s))) 197 | p.buf = append(p.buf, s...) 198 | return nil 199 | } 200 | 201 | // Marshaler is the interface representing objects that can marshal themselves. 202 | type Marshaler interface { 203 | Marshal() ([]byte, error) 204 | } 205 | 206 | // EncodeMessage writes the protocol buffer to the Buffer, 207 | // prefixed by a varint-encoded length. 208 | func (p *Buffer) EncodeMessage(pb Message) error { 209 | siz := Size(pb) 210 | p.EncodeVarint(uint64(siz)) 211 | return p.Marshal(pb) 212 | } 213 | 214 | // All protocol buffer fields are nillable, but be careful. 215 | func isNil(v reflect.Value) bool { 216 | switch v.Kind() { 217 | case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: 218 | return v.IsNil() 219 | } 220 | return false 221 | } 222 | --------------------------------------------------------------------------------