mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-06 10:43:56 +00:00
Merge pull request #22316 from vishh/godeps-cadvisor
Auto commit by PR queue bot
This commit is contained in:
commit
83f9c0d4fd
72
Godeps/Godeps.json
generated
72
Godeps/Godeps.json
generated
@ -578,93 +578,93 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/api",
|
"ImportPath": "github.com/google/cadvisor/api",
|
||||||
"Comment": "v0.21.1",
|
"Comment": "v0.22.0",
|
||||||
"Rev": "49a08d5139ae0111757a110ea3b55fe9a607873d"
|
"Rev": "e39fb02c89f2b39808bc1723108cde5bb510e102"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/cache/memory",
|
"ImportPath": "github.com/google/cadvisor/cache/memory",
|
||||||
"Comment": "v0.21.1",
|
"Comment": "v0.22.0",
|
||||||
"Rev": "49a08d5139ae0111757a110ea3b55fe9a607873d"
|
"Rev": "e39fb02c89f2b39808bc1723108cde5bb510e102"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/collector",
|
"ImportPath": "github.com/google/cadvisor/collector",
|
||||||
"Comment": "v0.21.1",
|
"Comment": "v0.22.0",
|
||||||
"Rev": "49a08d5139ae0111757a110ea3b55fe9a607873d"
|
"Rev": "e39fb02c89f2b39808bc1723108cde5bb510e102"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/container",
|
"ImportPath": "github.com/google/cadvisor/container",
|
||||||
"Comment": "v0.21.1",
|
"Comment": "v0.22.0",
|
||||||
"Rev": "49a08d5139ae0111757a110ea3b55fe9a607873d"
|
"Rev": "e39fb02c89f2b39808bc1723108cde5bb510e102"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/events",
|
"ImportPath": "github.com/google/cadvisor/events",
|
||||||
"Comment": "v0.21.1",
|
"Comment": "v0.22.0",
|
||||||
"Rev": "49a08d5139ae0111757a110ea3b55fe9a607873d"
|
"Rev": "e39fb02c89f2b39808bc1723108cde5bb510e102"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/fs",
|
"ImportPath": "github.com/google/cadvisor/fs",
|
||||||
"Comment": "v0.21.1",
|
"Comment": "v0.22.0",
|
||||||
"Rev": "49a08d5139ae0111757a110ea3b55fe9a607873d"
|
"Rev": "e39fb02c89f2b39808bc1723108cde5bb510e102"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/healthz",
|
"ImportPath": "github.com/google/cadvisor/healthz",
|
||||||
"Comment": "v0.21.1",
|
"Comment": "v0.22.0",
|
||||||
"Rev": "49a08d5139ae0111757a110ea3b55fe9a607873d"
|
"Rev": "e39fb02c89f2b39808bc1723108cde5bb510e102"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/http",
|
"ImportPath": "github.com/google/cadvisor/http",
|
||||||
"Comment": "v0.21.1",
|
"Comment": "v0.22.0",
|
||||||
"Rev": "49a08d5139ae0111757a110ea3b55fe9a607873d"
|
"Rev": "e39fb02c89f2b39808bc1723108cde5bb510e102"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/info/v1",
|
"ImportPath": "github.com/google/cadvisor/info/v1",
|
||||||
"Comment": "v0.21.1",
|
"Comment": "v0.22.0",
|
||||||
"Rev": "49a08d5139ae0111757a110ea3b55fe9a607873d"
|
"Rev": "e39fb02c89f2b39808bc1723108cde5bb510e102"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/info/v2",
|
"ImportPath": "github.com/google/cadvisor/info/v2",
|
||||||
"Comment": "v0.21.1",
|
"Comment": "v0.22.0",
|
||||||
"Rev": "49a08d5139ae0111757a110ea3b55fe9a607873d"
|
"Rev": "e39fb02c89f2b39808bc1723108cde5bb510e102"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/manager",
|
"ImportPath": "github.com/google/cadvisor/manager",
|
||||||
"Comment": "v0.21.1",
|
"Comment": "v0.22.0",
|
||||||
"Rev": "49a08d5139ae0111757a110ea3b55fe9a607873d"
|
"Rev": "e39fb02c89f2b39808bc1723108cde5bb510e102"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/metrics",
|
"ImportPath": "github.com/google/cadvisor/metrics",
|
||||||
"Comment": "v0.21.1",
|
"Comment": "v0.22.0",
|
||||||
"Rev": "49a08d5139ae0111757a110ea3b55fe9a607873d"
|
"Rev": "e39fb02c89f2b39808bc1723108cde5bb510e102"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/pages",
|
"ImportPath": "github.com/google/cadvisor/pages",
|
||||||
"Comment": "v0.21.1",
|
"Comment": "v0.22.0",
|
||||||
"Rev": "49a08d5139ae0111757a110ea3b55fe9a607873d"
|
"Rev": "e39fb02c89f2b39808bc1723108cde5bb510e102"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/storage",
|
"ImportPath": "github.com/google/cadvisor/storage",
|
||||||
"Comment": "v0.21.1",
|
"Comment": "v0.22.0",
|
||||||
"Rev": "49a08d5139ae0111757a110ea3b55fe9a607873d"
|
"Rev": "e39fb02c89f2b39808bc1723108cde5bb510e102"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/summary",
|
"ImportPath": "github.com/google/cadvisor/summary",
|
||||||
"Comment": "v0.21.1",
|
"Comment": "v0.22.0",
|
||||||
"Rev": "49a08d5139ae0111757a110ea3b55fe9a607873d"
|
"Rev": "e39fb02c89f2b39808bc1723108cde5bb510e102"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/utils",
|
"ImportPath": "github.com/google/cadvisor/utils",
|
||||||
"Comment": "v0.21.1",
|
"Comment": "v0.22.0",
|
||||||
"Rev": "49a08d5139ae0111757a110ea3b55fe9a607873d"
|
"Rev": "e39fb02c89f2b39808bc1723108cde5bb510e102"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/validate",
|
"ImportPath": "github.com/google/cadvisor/validate",
|
||||||
"Comment": "v0.21.1",
|
"Comment": "v0.22.0",
|
||||||
"Rev": "49a08d5139ae0111757a110ea3b55fe9a607873d"
|
"Rev": "e39fb02c89f2b39808bc1723108cde5bb510e102"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/version",
|
"ImportPath": "github.com/google/cadvisor/version",
|
||||||
"Comment": "v0.21.1",
|
"Comment": "v0.22.0",
|
||||||
"Rev": "49a08d5139ae0111757a110ea3b55fe9a607873d"
|
"Rev": "e39fb02c89f2b39808bc1723108cde5bb510e102"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/gofuzz",
|
"ImportPath": "github.com/google/gofuzz",
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
"endpoint" : "http://localhost:8080/metrics",
|
"endpoint" : "http://localhost:8080/metrics",
|
||||||
"polling_frequency" : 10,
|
"polling_frequency" : 10,
|
||||||
"metrics_config" : [
|
"metrics_config" : [
|
||||||
"go_goroutines"
|
"go_goroutines",
|
||||||
|
"qps"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
15
Godeps/_workspace/src/github.com/google/cadvisor/collector/generic_collector.go
generated
vendored
15
Godeps/_workspace/src/github.com/google/cadvisor/collector/generic_collector.go
generated
vendored
@ -44,10 +44,14 @@ type collectorInfo struct {
|
|||||||
|
|
||||||
//regular expresssions for all metrics
|
//regular expresssions for all metrics
|
||||||
regexps []*regexp.Regexp
|
regexps []*regexp.Regexp
|
||||||
|
|
||||||
|
// Limit for the number of srcaped metrics. If the count is higher,
|
||||||
|
// no metrics will be returned.
|
||||||
|
metricCountLimit int
|
||||||
}
|
}
|
||||||
|
|
||||||
//Returns a new collector using the information extracted from the configfile
|
//Returns a new collector using the information extracted from the configfile
|
||||||
func NewCollector(collectorName string, configFile []byte) (*GenericCollector, error) {
|
func NewCollector(collectorName string, configFile []byte, metricCountLimit int) (*GenericCollector, error) {
|
||||||
var configInJSON Config
|
var configInJSON Config
|
||||||
err := json.Unmarshal(configFile, &configInJSON)
|
err := json.Unmarshal(configFile, &configInJSON)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -83,12 +87,18 @@ func NewCollector(collectorName string, configFile []byte) (*GenericCollector, e
|
|||||||
minPollFrequency = minSupportedFrequency
|
minPollFrequency = minSupportedFrequency
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(configInJSON.MetricsConfig) > metricCountLimit {
|
||||||
|
return nil, fmt.Errorf("Too many metrics defined: %d limit: %d", len(configInJSON.MetricsConfig), metricCountLimit)
|
||||||
|
}
|
||||||
|
|
||||||
return &GenericCollector{
|
return &GenericCollector{
|
||||||
name: collectorName,
|
name: collectorName,
|
||||||
configFile: configInJSON,
|
configFile: configInJSON,
|
||||||
info: &collectorInfo{
|
info: &collectorInfo{
|
||||||
minPollingFrequency: minPollFrequency,
|
minPollingFrequency: minPollFrequency,
|
||||||
regexps: regexprs},
|
regexps: regexprs,
|
||||||
|
metricCountLimit: metricCountLimit,
|
||||||
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,6 +144,7 @@ func (collector *GenericCollector) Collect(metrics map[string][]v1.MetricVal) (t
|
|||||||
}
|
}
|
||||||
|
|
||||||
var errorSlice []error
|
var errorSlice []error
|
||||||
|
|
||||||
for ind, metricConfig := range collector.configFile.MetricsConfig {
|
for ind, metricConfig := range collector.configFile.MetricsConfig {
|
||||||
matchString := collector.info.regexps[ind].FindStringSubmatch(string(pageContent))
|
matchString := collector.info.regexps[ind].FindStringSubmatch(string(pageContent))
|
||||||
if matchString != nil {
|
if matchString != nil {
|
||||||
|
27
Godeps/_workspace/src/github.com/google/cadvisor/collector/prometheus_collector.go
generated
vendored
27
Godeps/_workspace/src/github.com/google/cadvisor/collector/prometheus_collector.go
generated
vendored
@ -16,6 +16,7 @@ package collector
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math"
|
"math"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -38,10 +39,14 @@ type PrometheusCollector struct {
|
|||||||
|
|
||||||
// the metrics to gather (uses a map as a set)
|
// the metrics to gather (uses a map as a set)
|
||||||
metricsSet map[string]bool
|
metricsSet map[string]bool
|
||||||
|
|
||||||
|
// Limit for the number of scaped metrics. If the count is higher,
|
||||||
|
// no metrics will be returned.
|
||||||
|
metricCountLimit int
|
||||||
}
|
}
|
||||||
|
|
||||||
//Returns a new collector using the information extracted from the configfile
|
//Returns a new collector using the information extracted from the configfile
|
||||||
func NewPrometheusCollector(collectorName string, configFile []byte) (*PrometheusCollector, error) {
|
func NewPrometheusCollector(collectorName string, configFile []byte, metricCountLimit int) (*PrometheusCollector, error) {
|
||||||
var configInJSON Prometheus
|
var configInJSON Prometheus
|
||||||
err := json.Unmarshal(configFile, &configInJSON)
|
err := json.Unmarshal(configFile, &configInJSON)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -57,6 +62,10 @@ func NewPrometheusCollector(collectorName string, configFile []byte) (*Prometheu
|
|||||||
minPollingFrequency = minSupportedFrequency
|
minPollingFrequency = minSupportedFrequency
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if metricCountLimit < 0 {
|
||||||
|
return nil, fmt.Errorf("Metric count limit must be greater than 0")
|
||||||
|
}
|
||||||
|
|
||||||
var metricsSet map[string]bool
|
var metricsSet map[string]bool
|
||||||
if len(configInJSON.MetricsConfig) > 0 {
|
if len(configInJSON.MetricsConfig) > 0 {
|
||||||
metricsSet = make(map[string]bool, len(configInJSON.MetricsConfig))
|
metricsSet = make(map[string]bool, len(configInJSON.MetricsConfig))
|
||||||
@ -65,12 +74,17 @@ func NewPrometheusCollector(collectorName string, configFile []byte) (*Prometheu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(configInJSON.MetricsConfig) > metricCountLimit {
|
||||||
|
return nil, fmt.Errorf("Too many metrics defined: %d limit %d", len(configInJSON.MetricsConfig), metricCountLimit)
|
||||||
|
}
|
||||||
|
|
||||||
//TODO : Add checks for validity of config file (eg : Accurate JSON fields)
|
//TODO : Add checks for validity of config file (eg : Accurate JSON fields)
|
||||||
return &PrometheusCollector{
|
return &PrometheusCollector{
|
||||||
name: collectorName,
|
name: collectorName,
|
||||||
pollingFrequency: minPollingFrequency,
|
pollingFrequency: minPollingFrequency,
|
||||||
configFile: configInJSON,
|
configFile: configInJSON,
|
||||||
metricsSet: metricsSet,
|
metricsSet: metricsSet,
|
||||||
|
metricCountLimit: metricCountLimit,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,6 +162,8 @@ func (collector *PrometheusCollector) Collect(metrics map[string][]v1.MetricVal)
|
|||||||
var errorSlice []error
|
var errorSlice []error
|
||||||
lines := strings.Split(string(pageContent), "\n")
|
lines := strings.Split(string(pageContent), "\n")
|
||||||
|
|
||||||
|
newMetrics := make(map[string][]v1.MetricVal)
|
||||||
|
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
if line == "" {
|
if line == "" {
|
||||||
break
|
break
|
||||||
@ -182,8 +198,15 @@ func (collector *PrometheusCollector) Collect(metrics map[string][]v1.MetricVal)
|
|||||||
FloatValue: metVal,
|
FloatValue: metVal,
|
||||||
Timestamp: currentTime,
|
Timestamp: currentTime,
|
||||||
}
|
}
|
||||||
metrics[metName] = append(metrics[metName], metric)
|
newMetrics[metName] = append(newMetrics[metName], metric)
|
||||||
|
if len(newMetrics) > collector.metricCountLimit {
|
||||||
|
return nextCollectionTime, nil, fmt.Errorf("too many metrics to collect")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
for key, val := range newMetrics {
|
||||||
|
metrics[key] = append(metrics[key], val...)
|
||||||
|
}
|
||||||
|
|
||||||
return nextCollectionTime, metrics, compileErrors(errorSlice)
|
return nextCollectionTime, metrics, compileErrors(errorSlice)
|
||||||
}
|
}
|
||||||
|
52
Godeps/_workspace/src/github.com/google/cadvisor/container/docker/factory.go
generated
vendored
52
Godeps/_workspace/src/github.com/google/cadvisor/container/docker/factory.go
generated
vendored
@ -21,17 +21,14 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/google/cadvisor/container"
|
"github.com/google/cadvisor/container"
|
||||||
"github.com/google/cadvisor/container/libcontainer"
|
"github.com/google/cadvisor/container/libcontainer"
|
||||||
"github.com/google/cadvisor/fs"
|
"github.com/google/cadvisor/fs"
|
||||||
info "github.com/google/cadvisor/info/v1"
|
info "github.com/google/cadvisor/info/v1"
|
||||||
"github.com/google/cadvisor/utils"
|
|
||||||
|
|
||||||
"github.com/fsouza/go-dockerclient"
|
"github.com/fsouza/go-dockerclient"
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var ArgDockerEndpoint = flag.String("docker", "unix:///var/run/docker.sock", "docker endpoint")
|
var ArgDockerEndpoint = flag.String("docker", "unix:///var/run/docker.sock", "docker endpoint")
|
||||||
@ -46,9 +43,7 @@ var dockerRunDir = flag.String("docker_run", "/var/run/docker", "Absolute path t
|
|||||||
|
|
||||||
// Regexp that identifies docker cgroups, containers started with
|
// Regexp that identifies docker cgroups, containers started with
|
||||||
// --cgroup-parent have another prefix than 'docker'
|
// --cgroup-parent have another prefix than 'docker'
|
||||||
var dockerCgroupRegexp = regexp.MustCompile(`.+-([a-z0-9]{64})\.scope$`)
|
var dockerCgroupRegexp = regexp.MustCompile(`([a-z0-9]{64})`)
|
||||||
|
|
||||||
var noSystemd = flag.Bool("nosystemd", false, "Explicitly disable systemd support for Docker containers")
|
|
||||||
|
|
||||||
var dockerEnvWhitelist = flag.String("docker_env_metadata_whitelist", "", "a comma-separated list of environment variable keys that needs to be collected for docker containers")
|
var dockerEnvWhitelist = flag.String("docker_env_metadata_whitelist", "", "a comma-separated list of environment variable keys that needs to be collected for docker containers")
|
||||||
|
|
||||||
@ -58,36 +53,10 @@ func DockerStateDir() string {
|
|||||||
return libcontainer.DockerStateDir(*dockerRootDir)
|
return libcontainer.DockerStateDir(*dockerRootDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Whether the system is using Systemd.
|
|
||||||
var useSystemd = false
|
|
||||||
var check = sync.Once{}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
dockerRootDirKey = "Root Dir"
|
dockerRootDirKey = "Root Dir"
|
||||||
)
|
)
|
||||||
|
|
||||||
func UseSystemd() bool {
|
|
||||||
check.Do(func() {
|
|
||||||
if *noSystemd {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Check for system.slice in systemd and cpu cgroup.
|
|
||||||
for _, cgroupType := range []string{"name=systemd", "cpu"} {
|
|
||||||
mnt, err := cgroups.FindCgroupMountpoint(cgroupType)
|
|
||||||
if err == nil {
|
|
||||||
// systemd presence does not mean systemd controls cgroups.
|
|
||||||
// If system.slice cgroup exists, then systemd is taking control.
|
|
||||||
// This breaks if user creates system.slice manually :)
|
|
||||||
if utils.FileExists(path.Join(mnt, "system.slice")) {
|
|
||||||
useSystemd = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return useSystemd
|
|
||||||
}
|
|
||||||
|
|
||||||
func RootDir() string {
|
func RootDir() string {
|
||||||
return *dockerRootDir
|
return *dockerRootDir
|
||||||
}
|
}
|
||||||
@ -117,6 +86,8 @@ type dockerFactory struct {
|
|||||||
fsInfo fs.FsInfo
|
fsInfo fs.FsInfo
|
||||||
|
|
||||||
dockerVersion []int
|
dockerVersion []int
|
||||||
|
|
||||||
|
ignoreMetrics container.MetricSet
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *dockerFactory) String() string {
|
func (self *dockerFactory) String() string {
|
||||||
@ -142,6 +113,7 @@ func (self *dockerFactory) NewContainerHandler(name string, inHostNamespace bool
|
|||||||
inHostNamespace,
|
inHostNamespace,
|
||||||
metadataEnvs,
|
metadataEnvs,
|
||||||
self.dockerVersion,
|
self.dockerVersion,
|
||||||
|
self.ignoreMetrics,
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -150,22 +122,16 @@ func (self *dockerFactory) NewContainerHandler(name string, inHostNamespace bool
|
|||||||
func ContainerNameToDockerId(name string) string {
|
func ContainerNameToDockerId(name string) string {
|
||||||
id := path.Base(name)
|
id := path.Base(name)
|
||||||
|
|
||||||
// Turn systemd cgroup name into Docker ID.
|
|
||||||
if UseSystemd() {
|
|
||||||
if matches := dockerCgroupRegexp.FindStringSubmatch(id); matches != nil {
|
if matches := dockerCgroupRegexp.FindStringSubmatch(id); matches != nil {
|
||||||
id = matches[1]
|
return matches[1]
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
func isContainerName(name string) bool {
|
func isContainerName(name string) bool {
|
||||||
if UseSystemd() {
|
|
||||||
return dockerCgroupRegexp.MatchString(path.Base(name))
|
return dockerCgroupRegexp.MatchString(path.Base(name))
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Docker handles all containers under /docker
|
// Docker handles all containers under /docker
|
||||||
func (self *dockerFactory) CanHandleAndAccept(name string) (bool, bool, error) {
|
func (self *dockerFactory) CanHandleAndAccept(name string) (bool, bool, error) {
|
||||||
@ -215,11 +181,7 @@ func parseDockerVersion(full_version_string string) ([]int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Register root container before running this function!
|
// Register root container before running this function!
|
||||||
func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo) error {
|
func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, ignoreMetrics container.MetricSet) error {
|
||||||
if UseSystemd() {
|
|
||||||
glog.Infof("System is using systemd")
|
|
||||||
}
|
|
||||||
|
|
||||||
client, err := Client()
|
client, err := Client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to communicate with docker daemon: %v", err)
|
return fmt.Errorf("unable to communicate with docker daemon: %v", err)
|
||||||
@ -277,7 +239,9 @@ func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo) error {
|
|||||||
machineInfoFactory: factory,
|
machineInfoFactory: factory,
|
||||||
storageDriver: storageDriver(sd),
|
storageDriver: storageDriver(sd),
|
||||||
storageDir: storageDir,
|
storageDir: storageDir,
|
||||||
|
ignoreMetrics: ignoreMetrics,
|
||||||
}
|
}
|
||||||
|
|
||||||
container.RegisterContainerHandlerFactory(f)
|
container.RegisterContainerHandlerFactory(f)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
34
Godeps/_workspace/src/github.com/google/cadvisor/container/docker/fsHandler.go
generated
vendored
34
Godeps/_workspace/src/github.com/google/cadvisor/container/docker/fsHandler.go
generated
vendored
@ -36,6 +36,7 @@ type realFsHandler struct {
|
|||||||
usageBytes uint64
|
usageBytes uint64
|
||||||
baseUsageBytes uint64
|
baseUsageBytes uint64
|
||||||
period time.Duration
|
period time.Duration
|
||||||
|
minPeriod time.Duration
|
||||||
rootfs string
|
rootfs string
|
||||||
extraDir string
|
extraDir string
|
||||||
fsInfo fs.FsInfo
|
fsInfo fs.FsInfo
|
||||||
@ -43,7 +44,11 @@ type realFsHandler struct {
|
|||||||
stopChan chan struct{}
|
stopChan chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
const longDu = time.Second
|
const (
|
||||||
|
longDu = time.Second
|
||||||
|
duTimeout = time.Minute
|
||||||
|
maxDuBackoffFactor = 20
|
||||||
|
)
|
||||||
|
|
||||||
var _ fsHandler = &realFsHandler{}
|
var _ fsHandler = &realFsHandler{}
|
||||||
|
|
||||||
@ -53,6 +58,7 @@ func newFsHandler(period time.Duration, rootfs, extraDir string, fsInfo fs.FsInf
|
|||||||
usageBytes: 0,
|
usageBytes: 0,
|
||||||
baseUsageBytes: 0,
|
baseUsageBytes: 0,
|
||||||
period: period,
|
period: period,
|
||||||
|
minPeriod: period,
|
||||||
rootfs: rootfs,
|
rootfs: rootfs,
|
||||||
extraDir: extraDir,
|
extraDir: extraDir,
|
||||||
fsInfo: fsInfo,
|
fsInfo: fsInfo,
|
||||||
@ -60,21 +66,25 @@ func newFsHandler(period time.Duration, rootfs, extraDir string, fsInfo fs.FsInf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fh *realFsHandler) needsUpdate() bool {
|
|
||||||
return time.Now().After(fh.lastUpdate.Add(fh.period))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fh *realFsHandler) update() error {
|
func (fh *realFsHandler) update() error {
|
||||||
|
var (
|
||||||
|
baseUsage, extraDirUsage uint64
|
||||||
|
err error
|
||||||
|
)
|
||||||
// TODO(vishh): Add support for external mounts.
|
// TODO(vishh): Add support for external mounts.
|
||||||
baseUsage, err := fh.fsInfo.GetDirUsage(fh.rootfs)
|
if fh.rootfs != "" {
|
||||||
|
baseUsage, err = fh.fsInfo.GetDirUsage(fh.rootfs, duTimeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extraDirUsage, err := fh.fsInfo.GetDirUsage(fh.extraDir)
|
if fh.extraDir != "" {
|
||||||
|
extraDirUsage, err = fh.fsInfo.GetDirUsage(fh.extraDir, duTimeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fh.Lock()
|
fh.Lock()
|
||||||
defer fh.Unlock()
|
defer fh.Unlock()
|
||||||
@ -93,11 +103,17 @@ func (fh *realFsHandler) trackUsage() {
|
|||||||
case <-time.After(fh.period):
|
case <-time.After(fh.period):
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
if err := fh.update(); err != nil {
|
if err := fh.update(); err != nil {
|
||||||
glog.V(2).Infof("failed to collect filesystem stats - %v", err)
|
glog.Errorf("failed to collect filesystem stats - %v", err)
|
||||||
|
fh.period = fh.period * 2
|
||||||
|
if fh.period > maxDuBackoffFactor*fh.minPeriod {
|
||||||
|
fh.period = maxDuBackoffFactor * fh.minPeriod
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fh.period = fh.minPeriod
|
||||||
}
|
}
|
||||||
duration := time.Since(start)
|
duration := time.Since(start)
|
||||||
if duration > longDu {
|
if duration > longDu {
|
||||||
glog.V(3).Infof("`du` on following dirs took %v: %v", duration, []string{fh.rootfs, fh.extraDir})
|
glog.V(2).Infof("`du` on following dirs took %v: %v", duration, []string{fh.rootfs, fh.extraDir})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
44
Godeps/_workspace/src/github.com/google/cadvisor/container/docker/handler.go
generated
vendored
44
Godeps/_workspace/src/github.com/google/cadvisor/container/docker/handler.go
generated
vendored
@ -81,6 +81,8 @@ type dockerContainerHandler struct {
|
|||||||
|
|
||||||
// Filesystem handler.
|
// Filesystem handler.
|
||||||
fsHandler fsHandler
|
fsHandler fsHandler
|
||||||
|
|
||||||
|
ignoreMetrics container.MetricSet
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRwLayerID(containerID, storageDir string, sd storageDriver, dockerVersion []int) (string, error) {
|
func getRwLayerID(containerID, storageDir string, sd storageDriver, dockerVersion []int) (string, error) {
|
||||||
@ -111,6 +113,7 @@ func newDockerContainerHandler(
|
|||||||
inHostNamespace bool,
|
inHostNamespace bool,
|
||||||
metadataEnvs []string,
|
metadataEnvs []string,
|
||||||
dockerVersion []int,
|
dockerVersion []int,
|
||||||
|
ignoreMetrics container.MetricSet,
|
||||||
) (container.ContainerHandler, error) {
|
) (container.ContainerHandler, error) {
|
||||||
// Create the cgroup paths.
|
// Create the cgroup paths.
|
||||||
cgroupPaths := make(map[string]string, len(cgroupSubsystems.MountPoints))
|
cgroupPaths := make(map[string]string, len(cgroupSubsystems.MountPoints))
|
||||||
@ -129,11 +132,13 @@ func newDockerContainerHandler(
|
|||||||
rootFs := "/"
|
rootFs := "/"
|
||||||
if !inHostNamespace {
|
if !inHostNamespace {
|
||||||
rootFs = "/rootfs"
|
rootFs = "/rootfs"
|
||||||
|
storageDir = path.Join(rootFs, storageDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
id := ContainerNameToDockerId(name)
|
id := ContainerNameToDockerId(name)
|
||||||
|
|
||||||
// Add the Containers dir where the log files are stored.
|
// Add the Containers dir where the log files are stored.
|
||||||
|
// FIXME: Give `otherStorageDir` a more descriptive name.
|
||||||
otherStorageDir := path.Join(storageDir, pathToContainersDir, id)
|
otherStorageDir := path.Join(storageDir, pathToContainersDir, id)
|
||||||
|
|
||||||
rwLayerID, err := getRwLayerID(id, storageDir, storageDriver, dockerVersion)
|
rwLayerID, err := getRwLayerID(id, storageDir, storageDriver, dockerVersion)
|
||||||
@ -159,8 +164,12 @@ func newDockerContainerHandler(
|
|||||||
fsInfo: fsInfo,
|
fsInfo: fsInfo,
|
||||||
rootFs: rootFs,
|
rootFs: rootFs,
|
||||||
rootfsStorageDir: rootfsStorageDir,
|
rootfsStorageDir: rootfsStorageDir,
|
||||||
fsHandler: newFsHandler(time.Minute, rootfsStorageDir, otherStorageDir, fsInfo),
|
|
||||||
envs: make(map[string]string),
|
envs: make(map[string]string),
|
||||||
|
ignoreMetrics: ignoreMetrics,
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ignoreMetrics.Has(container.DiskUsageMetrics) {
|
||||||
|
handler.fsHandler = newFsHandler(time.Minute, rootfsStorageDir, otherStorageDir, fsInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We assume that if Inspect fails then the container is not known to docker.
|
// We assume that if Inspect fails then the container is not known to docker.
|
||||||
@ -192,12 +201,16 @@ func newDockerContainerHandler(
|
|||||||
|
|
||||||
func (self *dockerContainerHandler) Start() {
|
func (self *dockerContainerHandler) Start() {
|
||||||
// Start the filesystem handler.
|
// Start the filesystem handler.
|
||||||
|
if self.fsHandler != nil {
|
||||||
self.fsHandler.start()
|
self.fsHandler.start()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (self *dockerContainerHandler) Cleanup() {
|
func (self *dockerContainerHandler) Cleanup() {
|
||||||
|
if self.fsHandler != nil {
|
||||||
self.fsHandler.stop()
|
self.fsHandler.stop()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (self *dockerContainerHandler) ContainerReference() (info.ContainerReference, error) {
|
func (self *dockerContainerHandler) ContainerReference() (info.ContainerReference, error) {
|
||||||
return info.ContainerReference{
|
return info.ContainerReference{
|
||||||
@ -253,8 +266,11 @@ func libcontainerConfigToContainerSpec(config *libcontainerconfigs.Config, mi *i
|
|||||||
return spec
|
return spec
|
||||||
}
|
}
|
||||||
|
|
||||||
func hasNet(networkMode string) bool {
|
func (self *dockerContainerHandler) needNet() bool {
|
||||||
return !strings.HasPrefix(networkMode, "container:")
|
if !self.ignoreMetrics.Has(container.NetworkUsageMetrics) {
|
||||||
|
return !strings.HasPrefix(self.networkMode, "container:")
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *dockerContainerHandler) GetSpec() (info.ContainerSpec, error) {
|
func (self *dockerContainerHandler) GetSpec() (info.ContainerSpec, error) {
|
||||||
@ -270,22 +286,25 @@ func (self *dockerContainerHandler) GetSpec() (info.ContainerSpec, error) {
|
|||||||
spec := libcontainerConfigToContainerSpec(libcontainerConfig, mi)
|
spec := libcontainerConfigToContainerSpec(libcontainerConfig, mi)
|
||||||
spec.CreationTime = self.creationTime
|
spec.CreationTime = self.creationTime
|
||||||
|
|
||||||
|
if !self.ignoreMetrics.Has(container.DiskUsageMetrics) {
|
||||||
switch self.storageDriver {
|
switch self.storageDriver {
|
||||||
case aufsStorageDriver, overlayStorageDriver, zfsStorageDriver:
|
case aufsStorageDriver, overlayStorageDriver, zfsStorageDriver:
|
||||||
spec.HasFilesystem = true
|
spec.HasFilesystem = true
|
||||||
default:
|
}
|
||||||
spec.HasFilesystem = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
spec.Labels = self.labels
|
spec.Labels = self.labels
|
||||||
spec.Envs = self.envs
|
spec.Envs = self.envs
|
||||||
spec.Image = self.image
|
spec.Image = self.image
|
||||||
spec.HasNetwork = hasNet(self.networkMode)
|
spec.HasNetwork = self.needNet()
|
||||||
|
|
||||||
return spec, err
|
return spec, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *dockerContainerHandler) getFsStats(stats *info.ContainerStats) error {
|
func (self *dockerContainerHandler) getFsStats(stats *info.ContainerStats) error {
|
||||||
|
if self.ignoreMetrics.Has(container.DiskUsageMetrics) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
switch self.storageDriver {
|
switch self.storageDriver {
|
||||||
case aufsStorageDriver, overlayStorageDriver, zfsStorageDriver:
|
case aufsStorageDriver, overlayStorageDriver, zfsStorageDriver:
|
||||||
default:
|
default:
|
||||||
@ -301,16 +320,21 @@ func (self *dockerContainerHandler) getFsStats(stats *info.ContainerStats) error
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var limit uint64 = 0
|
var (
|
||||||
|
limit uint64
|
||||||
|
fsType string
|
||||||
|
)
|
||||||
|
|
||||||
// Docker does not impose any filesystem limits for containers. So use capacity as limit.
|
// Docker does not impose any filesystem limits for containers. So use capacity as limit.
|
||||||
for _, fs := range mi.Filesystems {
|
for _, fs := range mi.Filesystems {
|
||||||
if fs.Device == deviceInfo.Device {
|
if fs.Device == deviceInfo.Device {
|
||||||
limit = fs.Capacity
|
limit = fs.Capacity
|
||||||
|
fsType = fs.Type
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fsStat := info.FsStats{Device: deviceInfo.Device, Limit: limit}
|
fsStat := info.FsStats{Device: deviceInfo.Device, Type: fsType, Limit: limit}
|
||||||
|
|
||||||
fsStat.BaseUsage, fsStat.Usage = self.fsHandler.usage()
|
fsStat.BaseUsage, fsStat.Usage = self.fsHandler.usage()
|
||||||
stats.Filesystem = append(stats.Filesystem, fsStat)
|
stats.Filesystem = append(stats.Filesystem, fsStat)
|
||||||
@ -320,7 +344,7 @@ func (self *dockerContainerHandler) getFsStats(stats *info.ContainerStats) error
|
|||||||
|
|
||||||
// TODO(vmarmol): Get from libcontainer API instead of cgroup manager when we don't have to support older Dockers.
|
// TODO(vmarmol): Get from libcontainer API instead of cgroup manager when we don't have to support older Dockers.
|
||||||
func (self *dockerContainerHandler) GetStats() (*info.ContainerStats, error) {
|
func (self *dockerContainerHandler) GetStats() (*info.ContainerStats, error) {
|
||||||
stats, err := containerlibcontainer.GetStats(self.cgroupManager, self.rootFs, self.pid)
|
stats, err := containerlibcontainer.GetStats(self.cgroupManager, self.rootFs, self.pid, self.ignoreMetrics)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stats, err
|
return stats, err
|
||||||
}
|
}
|
||||||
@ -328,7 +352,7 @@ func (self *dockerContainerHandler) GetStats() (*info.ContainerStats, error) {
|
|||||||
// includes containers running in Kubernetes pods that use the network of the
|
// includes containers running in Kubernetes pods that use the network of the
|
||||||
// infrastructure container. This stops metrics being reported multiple times
|
// infrastructure container. This stops metrics being reported multiple times
|
||||||
// for each container in a pod.
|
// for each container in a pod.
|
||||||
if !hasNet(self.networkMode) {
|
if !self.needNet() {
|
||||||
stats.Network = info.NetworkStats{}
|
stats.Network = info.NetworkStats{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
29
Godeps/_workspace/src/github.com/google/cadvisor/container/factory.go
generated
vendored
29
Godeps/_workspace/src/github.com/google/cadvisor/container/factory.go
generated
vendored
@ -35,6 +35,35 @@ type ContainerHandlerFactory interface {
|
|||||||
DebugInfo() map[string][]string
|
DebugInfo() map[string][]string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MetricKind represents the kind of metrics that cAdvisor exposes.
|
||||||
|
type MetricKind string
|
||||||
|
|
||||||
|
const (
|
||||||
|
CpuUsageMetrics MetricKind = "cpu"
|
||||||
|
MemoryUsageMetrics MetricKind = "memory"
|
||||||
|
CpuLoadMetrics MetricKind = "cpuLoad"
|
||||||
|
DiskIOMetrics MetricKind = "diskIO"
|
||||||
|
DiskUsageMetrics MetricKind = "disk"
|
||||||
|
NetworkUsageMetrics MetricKind = "network"
|
||||||
|
NetworkTcpUsageMetrics MetricKind = "tcp"
|
||||||
|
AppMetrics MetricKind = "app"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (mk MetricKind) String() string {
|
||||||
|
return string(mk)
|
||||||
|
}
|
||||||
|
|
||||||
|
type MetricSet map[MetricKind]struct{}
|
||||||
|
|
||||||
|
func (ms MetricSet) Has(mk MetricKind) bool {
|
||||||
|
_, exists := ms[mk]
|
||||||
|
return exists
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ms MetricSet) Add(mk MetricKind) {
|
||||||
|
ms[mk] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(vmarmol): Consider not making this global.
|
// TODO(vmarmol): Consider not making this global.
|
||||||
// Global list of factories.
|
// Global list of factories.
|
||||||
var (
|
var (
|
||||||
|
16
Godeps/_workspace/src/github.com/google/cadvisor/container/libcontainer/helpers.go
generated
vendored
16
Godeps/_workspace/src/github.com/google/cadvisor/container/libcontainer/helpers.go
generated
vendored
@ -17,12 +17,14 @@ package libcontainer
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/cadvisor/container"
|
||||||
info "github.com/google/cadvisor/info/v1"
|
info "github.com/google/cadvisor/info/v1"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
@ -79,7 +81,7 @@ var supportedSubsystems map[string]struct{} = map[string]struct{}{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get cgroup and networking stats of the specified container
|
// Get cgroup and networking stats of the specified container
|
||||||
func GetStats(cgroupManager cgroups.Manager, rootFs string, pid int) (*info.ContainerStats, error) {
|
func GetStats(cgroupManager cgroups.Manager, rootFs string, pid int, ignoreMetrics container.MetricSet) (*info.ContainerStats, error) {
|
||||||
cgroupStats, err := cgroupManager.GetStats()
|
cgroupStats, err := cgroupManager.GetStats()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -91,15 +93,16 @@ func GetStats(cgroupManager cgroups.Manager, rootFs string, pid int) (*info.Cont
|
|||||||
|
|
||||||
// If we know the pid then get network stats from /proc/<pid>/net/dev
|
// If we know the pid then get network stats from /proc/<pid>/net/dev
|
||||||
if pid > 0 {
|
if pid > 0 {
|
||||||
|
if !ignoreMetrics.Has(container.NetworkUsageMetrics) {
|
||||||
netStats, err := networkStatsFromProc(rootFs, pid)
|
netStats, err := networkStatsFromProc(rootFs, pid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.V(2).Infof("Unable to get network stats from pid %d: %v", pid, err)
|
glog.V(2).Infof("Unable to get network stats from pid %d: %v", pid, err)
|
||||||
} else {
|
} else {
|
||||||
stats.Network.Interfaces = append(stats.Network.Interfaces, netStats...)
|
stats.Network.Interfaces = append(stats.Network.Interfaces, netStats...)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Commenting out to disable: too CPU intensive
|
if !ignoreMetrics.Has(container.NetworkTcpUsageMetrics) {
|
||||||
/*t, err := tcpStatsFromProc(rootFs, pid, "net/tcp")
|
t, err := tcpStatsFromProc(rootFs, pid, "net/tcp")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.V(2).Infof("Unable to get tcp stats from pid %d: %v", pid, err)
|
glog.V(2).Infof("Unable to get tcp stats from pid %d: %v", pid, err)
|
||||||
} else {
|
} else {
|
||||||
@ -111,7 +114,8 @@ func GetStats(cgroupManager cgroups.Manager, rootFs string, pid int) (*info.Cont
|
|||||||
glog.V(2).Infof("Unable to get tcp6 stats from pid %d: %v", pid, err)
|
glog.V(2).Infof("Unable to get tcp6 stats from pid %d: %v", pid, err)
|
||||||
} else {
|
} else {
|
||||||
stats.Network.Tcp6 = t6
|
stats.Network.Tcp6 = t6
|
||||||
}*/
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// For backwards compatibility.
|
// For backwards compatibility.
|
||||||
@ -211,7 +215,6 @@ func setInterfaceStatValues(fields []string, pointers []*uint64) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
func tcpStatsFromProc(rootFs string, pid int, file string) (info.TcpStat, error) {
|
func tcpStatsFromProc(rootFs string, pid int, file string) (info.TcpStat, error) {
|
||||||
tcpStatsFile := path.Join(rootFs, "proc", strconv.Itoa(pid), file)
|
tcpStatsFile := path.Join(rootFs, "proc", strconv.Itoa(pid), file)
|
||||||
|
|
||||||
@ -286,7 +289,6 @@ func scanTcpStats(tcpStatsFile string) (info.TcpStat, error) {
|
|||||||
|
|
||||||
return stats, nil
|
return stats, nil
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
func GetProcesses(cgroupManager cgroups.Manager) ([]int, error) {
|
func GetProcesses(cgroupManager cgroups.Manager) ([]int, error) {
|
||||||
pids, err := cgroupManager.GetPids()
|
pids, err := cgroupManager.GetPids()
|
||||||
|
2
Godeps/_workspace/src/github.com/google/cadvisor/container/mock.go
generated
vendored
2
Godeps/_workspace/src/github.com/google/cadvisor/container/mock.go
generated
vendored
@ -12,6 +12,8 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
// +build test
|
||||||
|
|
||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
8
Godeps/_workspace/src/github.com/google/cadvisor/container/raw/factory.go
generated
vendored
8
Godeps/_workspace/src/github.com/google/cadvisor/container/raw/factory.go
generated
vendored
@ -40,6 +40,9 @@ type rawFactory struct {
|
|||||||
|
|
||||||
// Watcher for inotify events.
|
// Watcher for inotify events.
|
||||||
watcher *InotifyWatcher
|
watcher *InotifyWatcher
|
||||||
|
|
||||||
|
// List of metrics to be ignored.
|
||||||
|
ignoreMetrics map[container.MetricKind]struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *rawFactory) String() string {
|
func (self *rawFactory) String() string {
|
||||||
@ -51,7 +54,7 @@ func (self *rawFactory) NewContainerHandler(name string, inHostNamespace bool) (
|
|||||||
if !inHostNamespace {
|
if !inHostNamespace {
|
||||||
rootFs = "/rootfs"
|
rootFs = "/rootfs"
|
||||||
}
|
}
|
||||||
return newRawContainerHandler(name, self.cgroupSubsystems, self.machineInfoFactory, self.fsInfo, self.watcher, rootFs)
|
return newRawContainerHandler(name, self.cgroupSubsystems, self.machineInfoFactory, self.fsInfo, self.watcher, rootFs, self.ignoreMetrics)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The raw factory can handle any container. If --docker_only is set to false, non-docker containers are ignored.
|
// The raw factory can handle any container. If --docker_only is set to false, non-docker containers are ignored.
|
||||||
@ -77,7 +80,7 @@ func (self *rawFactory) DebugInfo() map[string][]string {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
func Register(machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo) error {
|
func Register(machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, ignoreMetrics map[container.MetricKind]struct{}) error {
|
||||||
cgroupSubsystems, err := libcontainer.GetCgroupSubsystems()
|
cgroupSubsystems, err := libcontainer.GetCgroupSubsystems()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get cgroup subsystems: %v", err)
|
return fmt.Errorf("failed to get cgroup subsystems: %v", err)
|
||||||
@ -97,6 +100,7 @@ func Register(machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo) erro
|
|||||||
fsInfo: fsInfo,
|
fsInfo: fsInfo,
|
||||||
cgroupSubsystems: &cgroupSubsystems,
|
cgroupSubsystems: &cgroupSubsystems,
|
||||||
watcher: watcher,
|
watcher: watcher,
|
||||||
|
ignoreMetrics: ignoreMetrics,
|
||||||
}
|
}
|
||||||
container.RegisterContainerHandlerFactory(factory)
|
container.RegisterContainerHandlerFactory(factory)
|
||||||
return nil
|
return nil
|
||||||
|
35
Godeps/_workspace/src/github.com/google/cadvisor/container/raw/handler.go
generated
vendored
35
Godeps/_workspace/src/github.com/google/cadvisor/container/raw/handler.go
generated
vendored
@ -57,16 +57,16 @@ type rawContainerHandler struct {
|
|||||||
// Manager of this container's cgroups.
|
// Manager of this container's cgroups.
|
||||||
cgroupManager cgroups.Manager
|
cgroupManager cgroups.Manager
|
||||||
|
|
||||||
// Whether this container has network isolation enabled.
|
|
||||||
hasNetwork bool
|
|
||||||
|
|
||||||
fsInfo fs.FsInfo
|
fsInfo fs.FsInfo
|
||||||
externalMounts []mount
|
externalMounts []mount
|
||||||
|
|
||||||
rootFs string
|
rootFs string
|
||||||
|
|
||||||
|
// Metrics to be ignored.
|
||||||
|
ignoreMetrics container.MetricSet
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRawContainerHandler(name string, cgroupSubsystems *libcontainer.CgroupSubsystems, machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, watcher *InotifyWatcher, rootFs string) (container.ContainerHandler, error) {
|
func newRawContainerHandler(name string, cgroupSubsystems *libcontainer.CgroupSubsystems, machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, watcher *InotifyWatcher, rootFs string, ignoreMetrics container.MetricSet) (container.ContainerHandler, error) {
|
||||||
// Create the cgroup paths.
|
// Create the cgroup paths.
|
||||||
cgroupPaths := make(map[string]string, len(cgroupSubsystems.MountPoints))
|
cgroupPaths := make(map[string]string, len(cgroupSubsystems.MountPoints))
|
||||||
for key, val := range cgroupSubsystems.MountPoints {
|
for key, val := range cgroupSubsystems.MountPoints {
|
||||||
@ -86,15 +86,9 @@ func newRawContainerHandler(name string, cgroupSubsystems *libcontainer.CgroupSu
|
|||||||
Paths: cgroupPaths,
|
Paths: cgroupPaths,
|
||||||
}
|
}
|
||||||
|
|
||||||
hasNetwork := false
|
|
||||||
var externalMounts []mount
|
var externalMounts []mount
|
||||||
for _, container := range cHints.AllHosts {
|
for _, container := range cHints.AllHosts {
|
||||||
if name == container.FullName {
|
if name == container.FullName {
|
||||||
/*libcontainerState.NetworkState = network.NetworkState{
|
|
||||||
VethHost: container.NetworkInterface.VethHost,
|
|
||||||
VethChild: container.NetworkInterface.VethChild,
|
|
||||||
}
|
|
||||||
hasNetwork = true*/
|
|
||||||
externalMounts = container.Mounts
|
externalMounts = container.Mounts
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -108,10 +102,10 @@ func newRawContainerHandler(name string, cgroupSubsystems *libcontainer.CgroupSu
|
|||||||
cgroupPaths: cgroupPaths,
|
cgroupPaths: cgroupPaths,
|
||||||
cgroupManager: cgroupManager,
|
cgroupManager: cgroupManager,
|
||||||
fsInfo: fsInfo,
|
fsInfo: fsInfo,
|
||||||
hasNetwork: hasNetwork,
|
|
||||||
externalMounts: externalMounts,
|
externalMounts: externalMounts,
|
||||||
watcher: watcher,
|
watcher: watcher,
|
||||||
rootFs: rootFs,
|
rootFs: rootFs,
|
||||||
|
ignoreMetrics: ignoreMetrics,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,6 +201,16 @@ func (self *rawContainerHandler) GetSpec() (info.ContainerSpec, error) {
|
|||||||
if utils.FileExists(cpuRoot) {
|
if utils.FileExists(cpuRoot) {
|
||||||
spec.HasCpu = true
|
spec.HasCpu = true
|
||||||
spec.Cpu.Limit = readUInt64(cpuRoot, "cpu.shares")
|
spec.Cpu.Limit = readUInt64(cpuRoot, "cpu.shares")
|
||||||
|
spec.Cpu.Period = readUInt64(cpuRoot, "cpu.cfs_period_us")
|
||||||
|
quota := readString(cpuRoot, "cpu.cfs_quota_us")
|
||||||
|
|
||||||
|
if quota != "" && quota != "-1" {
|
||||||
|
val, err := strconv.ParseUint(quota, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("raw driver: Failed to parse CPUQuota from %q: %s", path.Join(cpuRoot, "cpu.cfs_quota_us"), err)
|
||||||
|
}
|
||||||
|
spec.Cpu.Quota = val
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,9 +260,6 @@ func (self *rawContainerHandler) GetSpec() (info.ContainerSpec, error) {
|
|||||||
spec.HasFilesystem = true
|
spec.HasFilesystem = true
|
||||||
}
|
}
|
||||||
|
|
||||||
//Network
|
|
||||||
spec.HasNetwork = self.hasNetwork
|
|
||||||
|
|
||||||
// DiskIo.
|
// DiskIo.
|
||||||
if blkioRoot, ok := self.cgroupPaths["blkio"]; ok && utils.FileExists(blkioRoot) {
|
if blkioRoot, ok := self.cgroupPaths["blkio"]; ok && utils.FileExists(blkioRoot) {
|
||||||
spec.HasDiskIo = true
|
spec.HasDiskIo = true
|
||||||
@ -286,9 +287,11 @@ func (self *rawContainerHandler) getFsStats(stats *info.ContainerStats) error {
|
|||||||
stats.Filesystem = append(stats.Filesystem,
|
stats.Filesystem = append(stats.Filesystem,
|
||||||
info.FsStats{
|
info.FsStats{
|
||||||
Device: fs.Device,
|
Device: fs.Device,
|
||||||
|
Type: fs.Type.String(),
|
||||||
Limit: fs.Capacity,
|
Limit: fs.Capacity,
|
||||||
Usage: fs.Capacity - fs.Free,
|
Usage: fs.Capacity - fs.Free,
|
||||||
Available: fs.Available,
|
Available: fs.Available,
|
||||||
|
InodesFree: fs.InodesFree,
|
||||||
ReadsCompleted: fs.DiskStats.ReadsCompleted,
|
ReadsCompleted: fs.DiskStats.ReadsCompleted,
|
||||||
ReadsMerged: fs.DiskStats.ReadsMerged,
|
ReadsMerged: fs.DiskStats.ReadsMerged,
|
||||||
SectorsRead: fs.DiskStats.SectorsRead,
|
SectorsRead: fs.DiskStats.SectorsRead,
|
||||||
@ -316,8 +319,10 @@ func (self *rawContainerHandler) getFsStats(stats *info.ContainerStats) error {
|
|||||||
stats.Filesystem = append(stats.Filesystem,
|
stats.Filesystem = append(stats.Filesystem,
|
||||||
info.FsStats{
|
info.FsStats{
|
||||||
Device: fs.Device,
|
Device: fs.Device,
|
||||||
|
Type: fs.Type.String(),
|
||||||
Limit: fs.Capacity,
|
Limit: fs.Capacity,
|
||||||
Usage: fs.Capacity - fs.Free,
|
Usage: fs.Capacity - fs.Free,
|
||||||
|
InodesFree: fs.InodesFree,
|
||||||
ReadsCompleted: fs.DiskStats.ReadsCompleted,
|
ReadsCompleted: fs.DiskStats.ReadsCompleted,
|
||||||
ReadsMerged: fs.DiskStats.ReadsMerged,
|
ReadsMerged: fs.DiskStats.ReadsMerged,
|
||||||
SectorsRead: fs.DiskStats.SectorsRead,
|
SectorsRead: fs.DiskStats.SectorsRead,
|
||||||
@ -336,7 +341,7 @@ func (self *rawContainerHandler) getFsStats(stats *info.ContainerStats) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *rawContainerHandler) GetStats() (*info.ContainerStats, error) {
|
func (self *rawContainerHandler) GetStats() (*info.ContainerStats, error) {
|
||||||
stats, err := libcontainer.GetStats(self.cgroupManager, self.rootFs, os.Getpid())
|
stats, err := libcontainer.GetStats(self.cgroupManager, self.rootFs, os.Getpid(), self.ignoreMetrics)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stats, err
|
return stats, err
|
||||||
}
|
}
|
||||||
|
80
Godeps/_workspace/src/github.com/google/cadvisor/fs/fs.go
generated
vendored
80
Godeps/_workspace/src/github.com/google/cadvisor/fs/fs.go
generated
vendored
@ -21,6 +21,7 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
@ -29,6 +30,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/mount"
|
"github.com/docker/docker/pkg/mount"
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
@ -114,7 +116,7 @@ func NewFsInfo(context Context) (FsInfo, error) {
|
|||||||
// return any information or error, as we want to report based on the actual partition where the
|
// return any information or error, as we want to report based on the actual partition where the
|
||||||
// loopback file resides, inside of the loopback file itself.
|
// loopback file resides, inside of the loopback file itself.
|
||||||
func (self *RealFsInfo) getDockerDeviceMapperInfo(dockerInfo map[string]string) (string, *partition, error) {
|
func (self *RealFsInfo) getDockerDeviceMapperInfo(dockerInfo map[string]string) (string, *partition, error) {
|
||||||
if storageDriver, ok := dockerInfo["Driver"]; ok && storageDriver != "devicemapper" {
|
if storageDriver, ok := dockerInfo["Driver"]; ok && storageDriver != DeviceMapper.String() {
|
||||||
return "", nil, nil
|
return "", nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +136,7 @@ func (self *RealFsInfo) getDockerDeviceMapperInfo(dockerInfo map[string]string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return dev, &partition{
|
return dev, &partition{
|
||||||
fsType: "devicemapper",
|
fsType: DeviceMapper.String(),
|
||||||
major: major,
|
major: major,
|
||||||
minor: minor,
|
minor: minor,
|
||||||
blockSize: blockSize,
|
blockSize: blockSize,
|
||||||
@ -244,27 +246,30 @@ func (self *RealFsInfo) GetFsInfoForPath(mountSet map[string]struct{}) ([]Fs, er
|
|||||||
_, hasDevice := deviceSet[device]
|
_, hasDevice := deviceSet[device]
|
||||||
if mountSet == nil || (hasMount && !hasDevice) {
|
if mountSet == nil || (hasMount && !hasDevice) {
|
||||||
var (
|
var (
|
||||||
total, free, avail uint64
|
|
||||||
err error
|
err error
|
||||||
|
fs Fs
|
||||||
)
|
)
|
||||||
switch partition.fsType {
|
switch partition.fsType {
|
||||||
case "devicemapper":
|
case DeviceMapper.String():
|
||||||
total, free, avail, err = getDMStats(device, partition.blockSize)
|
fs.Capacity, fs.Free, fs.Available, err = getDMStats(device, partition.blockSize)
|
||||||
case "zfs":
|
fs.Type = DeviceMapper
|
||||||
total, free, avail, err = getZfstats(device)
|
case ZFS.String():
|
||||||
|
fs.Capacity, fs.Free, fs.Available, err = getZfstats(device)
|
||||||
|
fs.Type = ZFS
|
||||||
default:
|
default:
|
||||||
total, free, avail, err = getVfsStats(partition.mountpoint)
|
fs.Capacity, fs.Free, fs.Available, fs.Inodes, fs.InodesFree, err = getVfsStats(partition.mountpoint)
|
||||||
|
fs.Type = VFS
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("Stat fs failed. Error: %v", err)
|
glog.Errorf("Stat fs failed. Error: %v", err)
|
||||||
} else {
|
} else {
|
||||||
deviceSet[device] = struct{}{}
|
deviceSet[device] = struct{}{}
|
||||||
deviceInfo := DeviceInfo{
|
fs.DeviceInfo = DeviceInfo{
|
||||||
Device: device,
|
Device: device,
|
||||||
Major: uint(partition.major),
|
Major: uint(partition.major),
|
||||||
Minor: uint(partition.minor),
|
Minor: uint(partition.minor),
|
||||||
}
|
}
|
||||||
fs := Fs{deviceInfo, total, free, avail, diskStatsMap[device]}
|
fs.DiskStats = diskStatsMap[device]
|
||||||
filesystems = append(filesystems, fs)
|
filesystems = append(filesystems, fs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -355,27 +360,56 @@ func (self *RealFsInfo) GetDirFsDevice(dir string) (*DeviceInfo, error) {
|
|||||||
return nil, fmt.Errorf("could not find device with major: %d, minor: %d in cached partitions map", major, minor)
|
return nil, fmt.Errorf("could not find device with major: %d, minor: %d in cached partitions map", major, minor)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *RealFsInfo) GetDirUsage(dir string) (uint64, error) {
|
func (self *RealFsInfo) GetDirUsage(dir string, timeout time.Duration) (uint64, error) {
|
||||||
out, err := exec.Command("nice", "-n", "19", "du", "-s", dir).CombinedOutput()
|
if dir == "" {
|
||||||
if err != nil {
|
return 0, fmt.Errorf("invalid directory")
|
||||||
return 0, fmt.Errorf("du command failed on %s with output %s - %s", dir, out, err)
|
|
||||||
}
|
}
|
||||||
usageInKb, err := strconv.ParseUint(strings.Fields(string(out))[0], 10, 64)
|
cmd := exec.Command("nice", "-n", "19", "du", "-s", dir)
|
||||||
|
stdoutp, err := cmd.StdoutPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("cannot parse 'du' output %s - %s", out, err)
|
return 0, fmt.Errorf("failed to setup stdout for cmd %v - %v", cmd.Args, err)
|
||||||
|
}
|
||||||
|
stderrp, err := cmd.StderrPipe()
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("failed to setup stderr for cmd %v - %v", cmd.Args, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cmd.Start(); err != nil {
|
||||||
|
return 0, fmt.Errorf("failed to exec du - %v", err)
|
||||||
|
}
|
||||||
|
stdoutb, souterr := ioutil.ReadAll(stdoutp)
|
||||||
|
stderrb, _ := ioutil.ReadAll(stderrp)
|
||||||
|
timer := time.AfterFunc(timeout, func() {
|
||||||
|
glog.Infof("killing cmd %v due to timeout(%s)", cmd.Args, timeout.String())
|
||||||
|
cmd.Process.Kill()
|
||||||
|
})
|
||||||
|
err = cmd.Wait()
|
||||||
|
timer.Stop()
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("du command failed on %s with output stdout: %s, stderr: %s - %v", dir, string(stdoutb), string(stderrb), err)
|
||||||
|
}
|
||||||
|
stdout := string(stdoutb)
|
||||||
|
if souterr != nil {
|
||||||
|
glog.Errorf("failed to read from stdout for cmd %v - %v", cmd.Args, souterr)
|
||||||
|
}
|
||||||
|
usageInKb, err := strconv.ParseUint(strings.Fields(stdout)[0], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("cannot parse 'du' output %s - %s", stdout, err)
|
||||||
}
|
}
|
||||||
return usageInKb * 1024, nil
|
return usageInKb * 1024, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getVfsStats(path string) (uint64, uint64, uint64, error) {
|
func getVfsStats(path string) (total uint64, free uint64, avail uint64, inodes uint64, inodesFree uint64, err error) {
|
||||||
var s syscall.Statfs_t
|
var s syscall.Statfs_t
|
||||||
if err := syscall.Statfs(path, &s); err != nil {
|
if err = syscall.Statfs(path, &s); err != nil {
|
||||||
return 0, 0, 0, err
|
return 0, 0, 0, 0, 0, err
|
||||||
}
|
}
|
||||||
total := uint64(s.Frsize) * s.Blocks
|
total = uint64(s.Frsize) * s.Blocks
|
||||||
free := uint64(s.Frsize) * s.Bfree
|
free = uint64(s.Frsize) * s.Bfree
|
||||||
avail := uint64(s.Frsize) * s.Bavail
|
avail = uint64(s.Frsize) * s.Bavail
|
||||||
return total, free, avail, nil
|
inodes = uint64(s.Files)
|
||||||
|
inodesFree = uint64(s.Ffree)
|
||||||
|
return total, free, avail, inodes, inodesFree, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func dockerStatusValue(status [][]string, target string) string {
|
func dockerStatusValue(status [][]string, target string) string {
|
||||||
|
19
Godeps/_workspace/src/github.com/google/cadvisor/fs/types.go
generated
vendored
19
Godeps/_workspace/src/github.com/google/cadvisor/fs/types.go
generated
vendored
@ -14,17 +14,34 @@
|
|||||||
|
|
||||||
package fs
|
package fs
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
type DeviceInfo struct {
|
type DeviceInfo struct {
|
||||||
Device string
|
Device string
|
||||||
Major uint
|
Major uint
|
||||||
Minor uint
|
Minor uint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FsType string
|
||||||
|
|
||||||
|
func (ft FsType) String() string {
|
||||||
|
return string(ft)
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
ZFS FsType = "zfs"
|
||||||
|
DeviceMapper FsType = "devicemapper"
|
||||||
|
VFS FsType = "vfs"
|
||||||
|
)
|
||||||
|
|
||||||
type Fs struct {
|
type Fs struct {
|
||||||
DeviceInfo
|
DeviceInfo
|
||||||
|
Type FsType
|
||||||
Capacity uint64
|
Capacity uint64
|
||||||
Free uint64
|
Free uint64
|
||||||
Available uint64
|
Available uint64
|
||||||
|
Inodes uint64
|
||||||
|
InodesFree uint64
|
||||||
DiskStats DiskStats
|
DiskStats DiskStats
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +67,7 @@ type FsInfo interface {
|
|||||||
GetFsInfoForPath(mountSet map[string]struct{}) ([]Fs, error)
|
GetFsInfoForPath(mountSet map[string]struct{}) ([]Fs, error)
|
||||||
|
|
||||||
// Returns number of bytes occupied by 'dir'.
|
// Returns number of bytes occupied by 'dir'.
|
||||||
GetDirUsage(dir string) (uint64, error)
|
GetDirUsage(dir string, timeout time.Duration) (uint64, error)
|
||||||
|
|
||||||
// Returns the block device info of the filesystem on which 'dir' resides.
|
// Returns the block device info of the filesystem on which 'dir' resides.
|
||||||
GetDirFsDevice(dir string) (*DeviceInfo, error)
|
GetDirFsDevice(dir string) (*DeviceInfo, error)
|
||||||
|
8
Godeps/_workspace/src/github.com/google/cadvisor/info/v1/container.go
generated
vendored
8
Godeps/_workspace/src/github.com/google/cadvisor/info/v1/container.go
generated
vendored
@ -23,6 +23,8 @@ type CpuSpec struct {
|
|||||||
Limit uint64 `json:"limit"`
|
Limit uint64 `json:"limit"`
|
||||||
MaxLimit uint64 `json:"max_limit"`
|
MaxLimit uint64 `json:"max_limit"`
|
||||||
Mask string `json:"mask,omitempty"`
|
Mask string `json:"mask,omitempty"`
|
||||||
|
Quota uint64 `json:"quota,omitempty"`
|
||||||
|
Period uint64 `json:"period,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type MemorySpec struct {
|
type MemorySpec struct {
|
||||||
@ -397,6 +399,9 @@ type FsStats struct {
|
|||||||
// The block device name associated with the filesystem.
|
// The block device name associated with the filesystem.
|
||||||
Device string `json:"device,omitempty"`
|
Device string `json:"device,omitempty"`
|
||||||
|
|
||||||
|
// Type of the filesytem.
|
||||||
|
Type string `json:"type"`
|
||||||
|
|
||||||
// Number of bytes that can be consumed by the container on this filesystem.
|
// Number of bytes that can be consumed by the container on this filesystem.
|
||||||
Limit uint64 `json:"capacity"`
|
Limit uint64 `json:"capacity"`
|
||||||
|
|
||||||
@ -410,6 +415,9 @@ type FsStats struct {
|
|||||||
// Number of bytes available for non-root user.
|
// Number of bytes available for non-root user.
|
||||||
Available uint64 `json:"available"`
|
Available uint64 `json:"available"`
|
||||||
|
|
||||||
|
// Number of available Inodes
|
||||||
|
InodesFree uint64 `json:"inodes_free"`
|
||||||
|
|
||||||
// Number of reads completed
|
// Number of reads completed
|
||||||
// This is the total number of reads completed successfully.
|
// This is the total number of reads completed successfully.
|
||||||
ReadsCompleted uint64 `json:"reads_completed"`
|
ReadsCompleted uint64 `json:"reads_completed"`
|
||||||
|
16
Godeps/_workspace/src/github.com/google/cadvisor/info/v1/machine.go
generated
vendored
16
Godeps/_workspace/src/github.com/google/cadvisor/info/v1/machine.go
generated
vendored
@ -20,6 +20,12 @@ type FsInfo struct {
|
|||||||
|
|
||||||
// Total number of bytes available on the filesystem.
|
// Total number of bytes available on the filesystem.
|
||||||
Capacity uint64 `json:"capacity"`
|
Capacity uint64 `json:"capacity"`
|
||||||
|
|
||||||
|
// Type of device.
|
||||||
|
Type string `json:"type"`
|
||||||
|
|
||||||
|
// Total number of inodes available on the filesystem.
|
||||||
|
Inodes uint64 `json:"inodes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Node struct {
|
type Node struct {
|
||||||
@ -117,6 +123,7 @@ type CloudProvider string
|
|||||||
const (
|
const (
|
||||||
GCE CloudProvider = "GCE"
|
GCE CloudProvider = "GCE"
|
||||||
AWS = "AWS"
|
AWS = "AWS"
|
||||||
|
Azure = "Azure"
|
||||||
Baremetal = "Baremetal"
|
Baremetal = "Baremetal"
|
||||||
UnkownProvider = "Unknown"
|
UnkownProvider = "Unknown"
|
||||||
)
|
)
|
||||||
@ -128,6 +135,12 @@ const (
|
|||||||
UnknownInstance = "Unknown"
|
UnknownInstance = "Unknown"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type InstanceID string
|
||||||
|
|
||||||
|
const (
|
||||||
|
UnNamedInstance InstanceID = "None"
|
||||||
|
)
|
||||||
|
|
||||||
type MachineInfo struct {
|
type MachineInfo struct {
|
||||||
// The number of cores in this machine.
|
// The number of cores in this machine.
|
||||||
NumCores int `json:"num_cores"`
|
NumCores int `json:"num_cores"`
|
||||||
@ -165,6 +178,9 @@ type MachineInfo struct {
|
|||||||
|
|
||||||
// Type of cloud instance (e.g. GCE standard) the machine is.
|
// Type of cloud instance (e.g. GCE standard) the machine is.
|
||||||
InstanceType InstanceType `json:"instance_type"`
|
InstanceType InstanceType `json:"instance_type"`
|
||||||
|
|
||||||
|
// ID of cloud instance (e.g. instance-1) given to it by the cloud provider.
|
||||||
|
InstanceID InstanceID `json:"instance_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type VersionInfo struct {
|
type VersionInfo struct {
|
||||||
|
4
Godeps/_workspace/src/github.com/google/cadvisor/info/v2/container.go
generated
vendored
4
Godeps/_workspace/src/github.com/google/cadvisor/info/v2/container.go
generated
vendored
@ -36,6 +36,10 @@ type CpuSpec struct {
|
|||||||
// Cpu affinity mask.
|
// Cpu affinity mask.
|
||||||
// TODO(rjnagal): Add a library to convert mask string to set of cpu bitmask.
|
// TODO(rjnagal): Add a library to convert mask string to set of cpu bitmask.
|
||||||
Mask string `json:"mask,omitempty"`
|
Mask string `json:"mask,omitempty"`
|
||||||
|
// CPUQuota Default is disabled
|
||||||
|
Quota uint64 `json:"quota,omitempty"`
|
||||||
|
// Period is the CPU reference time in ns e.g the quota is compared aginst this.
|
||||||
|
Period uint64 `json:"period,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type MemorySpec struct {
|
type MemorySpec struct {
|
||||||
|
2
Godeps/_workspace/src/github.com/google/cadvisor/info/v2/conversion.go
generated
vendored
2
Godeps/_workspace/src/github.com/google/cadvisor/info/v2/conversion.go
generated
vendored
@ -31,9 +31,11 @@ func machineFsStatsFromV1(fsStats []v1.FsStats) []MachineFsStats {
|
|||||||
weightedDuration := time.Millisecond * time.Duration(stat.WeightedIoTime)
|
weightedDuration := time.Millisecond * time.Duration(stat.WeightedIoTime)
|
||||||
result = append(result, MachineFsStats{
|
result = append(result, MachineFsStats{
|
||||||
Device: stat.Device,
|
Device: stat.Device,
|
||||||
|
Type: stat.Type,
|
||||||
Capacity: &stat.Limit,
|
Capacity: &stat.Limit,
|
||||||
Usage: &stat.Usage,
|
Usage: &stat.Usage,
|
||||||
Available: &stat.Available,
|
Available: &stat.Available,
|
||||||
|
InodesFree: &stat.InodesFree,
|
||||||
DiskStats: DiskStats{
|
DiskStats: DiskStats{
|
||||||
ReadsCompleted: &stat.ReadsCompleted,
|
ReadsCompleted: &stat.ReadsCompleted,
|
||||||
ReadsMerged: &stat.ReadsMerged,
|
ReadsMerged: &stat.ReadsMerged,
|
||||||
|
6
Godeps/_workspace/src/github.com/google/cadvisor/info/v2/machine.go
generated
vendored
6
Godeps/_workspace/src/github.com/google/cadvisor/info/v2/machine.go
generated
vendored
@ -112,6 +112,9 @@ type MachineFsStats struct {
|
|||||||
// The block device name associated with the filesystem.
|
// The block device name associated with the filesystem.
|
||||||
Device string `json:"device"`
|
Device string `json:"device"`
|
||||||
|
|
||||||
|
// Type of filesystem.
|
||||||
|
Type string `json:"type"`
|
||||||
|
|
||||||
// Number of bytes that can be consumed on this filesystem.
|
// Number of bytes that can be consumed on this filesystem.
|
||||||
Capacity *uint64 `json:"capacity,omitempty"`
|
Capacity *uint64 `json:"capacity,omitempty"`
|
||||||
|
|
||||||
@ -121,6 +124,9 @@ type MachineFsStats struct {
|
|||||||
// Number of bytes available for non-root user on this filesystem.
|
// Number of bytes available for non-root user on this filesystem.
|
||||||
Available *uint64 `json:"available,omitempty"`
|
Available *uint64 `json:"available,omitempty"`
|
||||||
|
|
||||||
|
// Number of inodes that are available on this filesystem.
|
||||||
|
InodesFree *uint64 `json:"inodes_free,omitempty"`
|
||||||
|
|
||||||
// DiskStats for this device.
|
// DiskStats for this device.
|
||||||
DiskStats `json:"inline"`
|
DiskStats `json:"inline"`
|
||||||
}
|
}
|
||||||
|
4
Godeps/_workspace/src/github.com/google/cadvisor/manager/machine.go
generated
vendored
4
Godeps/_workspace/src/github.com/google/cadvisor/manager/machine.go
generated
vendored
@ -96,6 +96,7 @@ func getMachineInfo(sysFs sysfs.SysFs, fsInfo fs.FsInfo, inHostNamespace bool) (
|
|||||||
realCloudInfo := cloudinfo.NewRealCloudInfo()
|
realCloudInfo := cloudinfo.NewRealCloudInfo()
|
||||||
cloudProvider := realCloudInfo.GetCloudProvider()
|
cloudProvider := realCloudInfo.GetCloudProvider()
|
||||||
instanceType := realCloudInfo.GetInstanceType()
|
instanceType := realCloudInfo.GetInstanceType()
|
||||||
|
instanceID := realCloudInfo.GetInstanceID()
|
||||||
|
|
||||||
machineInfo := &info.MachineInfo{
|
machineInfo := &info.MachineInfo{
|
||||||
NumCores: numCores,
|
NumCores: numCores,
|
||||||
@ -109,10 +110,11 @@ func getMachineInfo(sysFs sysfs.SysFs, fsInfo fs.FsInfo, inHostNamespace bool) (
|
|||||||
BootID: getInfoFromFiles(filepath.Join(rootFs, *bootIdFilePath)),
|
BootID: getInfoFromFiles(filepath.Join(rootFs, *bootIdFilePath)),
|
||||||
CloudProvider: cloudProvider,
|
CloudProvider: cloudProvider,
|
||||||
InstanceType: instanceType,
|
InstanceType: instanceType,
|
||||||
|
InstanceID: instanceID,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, fs := range filesystems {
|
for _, fs := range filesystems {
|
||||||
machineInfo.Filesystems = append(machineInfo.Filesystems, info.FsInfo{Device: fs.Device, Capacity: fs.Capacity})
|
machineInfo.Filesystems = append(machineInfo.Filesystems, info.FsInfo{Device: fs.Device, Type: fs.Type.String(), Capacity: fs.Capacity, Inodes: fs.Inodes})
|
||||||
}
|
}
|
||||||
|
|
||||||
return machineInfo, nil
|
return machineInfo, nil
|
||||||
|
49
Godeps/_workspace/src/github.com/google/cadvisor/manager/manager.go
generated
vendored
49
Godeps/_workspace/src/github.com/google/cadvisor/manager/manager.go
generated
vendored
@ -48,6 +48,43 @@ var logCadvisorUsage = flag.Bool("log_cadvisor_usage", false, "Whether to log th
|
|||||||
var enableLoadReader = flag.Bool("enable_load_reader", false, "Whether to enable cpu load reader")
|
var enableLoadReader = flag.Bool("enable_load_reader", false, "Whether to enable cpu load reader")
|
||||||
var eventStorageAgeLimit = flag.String("event_storage_age_limit", "default=24h", "Max length of time for which to store events (per type). Value is a comma separated list of key values, where the keys are event types (e.g.: creation, oom) or \"default\" and the value is a duration. Default is applied to all non-specified event types")
|
var eventStorageAgeLimit = flag.String("event_storage_age_limit", "default=24h", "Max length of time for which to store events (per type). Value is a comma separated list of key values, where the keys are event types (e.g.: creation, oom) or \"default\" and the value is a duration. Default is applied to all non-specified event types")
|
||||||
var eventStorageEventLimit = flag.String("event_storage_event_limit", "default=100000", "Max number of events to store (per type). Value is a comma separated list of key values, where the keys are event types (e.g.: creation, oom) or \"default\" and the value is an integer. Default is applied to all non-specified event types")
|
var eventStorageEventLimit = flag.String("event_storage_event_limit", "default=100000", "Max number of events to store (per type). Value is a comma separated list of key values, where the keys are event types (e.g.: creation, oom) or \"default\" and the value is an integer. Default is applied to all non-specified event types")
|
||||||
|
var applicationMetricsCountLimit = flag.Int("application_metrics_count_limit", 100, "Max number of application metrics to store (per container)")
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Metrics to be ignored.
|
||||||
|
ignoreMetrics metricSetValue = metricSetValue{container.MetricSet{}}
|
||||||
|
// List of metrics that can be ignored.
|
||||||
|
ignoreWhitelist = container.MetricSet{
|
||||||
|
container.DiskUsageMetrics: struct{}{},
|
||||||
|
container.NetworkUsageMetrics: struct{}{},
|
||||||
|
container.NetworkTcpUsageMetrics: struct{}{},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
flag.Var(&ignoreMetrics, "disable_metrics", "comma-separated list of metrics to be disabled. Options are `disk`, `network`, `tcp`. Note: tcp is disabled by default due to high CPU usage.")
|
||||||
|
// Tcp metrics are ignored by default.
|
||||||
|
flag.Set("disable_metrics", "tcp")
|
||||||
|
}
|
||||||
|
|
||||||
|
type metricSetValue struct {
|
||||||
|
container.MetricSet
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ml *metricSetValue) String() string {
|
||||||
|
return fmt.Sprint(*ml)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ml *metricSetValue) Set(value string) error {
|
||||||
|
for _, metric := range strings.Split(value, ",") {
|
||||||
|
if ignoreWhitelist.Has(container.MetricKind(metric)) {
|
||||||
|
(*ml).Add(container.MetricKind(metric))
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("unsupported metric %q specified in disable_metrics", metric)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// The Manager interface defines operations for starting a manager and getting
|
// The Manager interface defines operations for starting a manager and getting
|
||||||
// container and machine information.
|
// container and machine information.
|
||||||
@ -146,6 +183,7 @@ func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, maxHousekeepingIn
|
|||||||
if _, err := os.Stat("/rootfs/proc"); os.IsNotExist(err) {
|
if _, err := os.Stat("/rootfs/proc"); os.IsNotExist(err) {
|
||||||
inHostNamespace = true
|
inHostNamespace = true
|
||||||
}
|
}
|
||||||
|
|
||||||
newManager := &manager{
|
newManager := &manager{
|
||||||
containers: make(map[namespacedContainerName]*containerData),
|
containers: make(map[namespacedContainerName]*containerData),
|
||||||
quitChannels: make([]chan error, 0, 2),
|
quitChannels: make([]chan error, 0, 2),
|
||||||
@ -156,6 +194,7 @@ func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, maxHousekeepingIn
|
|||||||
startupTime: time.Now(),
|
startupTime: time.Now(),
|
||||||
maxHousekeepingInterval: maxHousekeepingInterval,
|
maxHousekeepingInterval: maxHousekeepingInterval,
|
||||||
allowDynamicHousekeeping: allowDynamicHousekeeping,
|
allowDynamicHousekeeping: allowDynamicHousekeeping,
|
||||||
|
ignoreMetrics: ignoreMetrics.MetricSet,
|
||||||
}
|
}
|
||||||
|
|
||||||
machineInfo, err := getMachineInfo(sysfs, fsInfo, inHostNamespace)
|
machineInfo, err := getMachineInfo(sysfs, fsInfo, inHostNamespace)
|
||||||
@ -198,18 +237,19 @@ type manager struct {
|
|||||||
startupTime time.Time
|
startupTime time.Time
|
||||||
maxHousekeepingInterval time.Duration
|
maxHousekeepingInterval time.Duration
|
||||||
allowDynamicHousekeeping bool
|
allowDynamicHousekeeping bool
|
||||||
|
ignoreMetrics container.MetricSet
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the container manager.
|
// Start the container manager.
|
||||||
func (self *manager) Start() error {
|
func (self *manager) Start() error {
|
||||||
// Register Docker container factory.
|
// Register Docker container factory.
|
||||||
err := docker.Register(self, self.fsInfo)
|
err := docker.Register(self, self.fsInfo, self.ignoreMetrics)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("Docker container factory registration failed: %v.", err)
|
glog.Errorf("Docker container factory registration failed: %v.", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register the raw driver.
|
// Register the raw driver.
|
||||||
err = raw.Register(self, self.fsInfo)
|
err = raw.Register(self, self.fsInfo, self.ignoreMetrics)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("Registration of the raw container factory failed: %v", err)
|
glog.Errorf("Registration of the raw container factory failed: %v", err)
|
||||||
}
|
}
|
||||||
@ -718,7 +758,7 @@ func (m *manager) registerCollectors(collectorConfigs map[string]string, cont *c
|
|||||||
glog.V(3).Infof("Got config from %q: %q", v, configFile)
|
glog.V(3).Infof("Got config from %q: %q", v, configFile)
|
||||||
|
|
||||||
if strings.HasPrefix(k, "prometheus") || strings.HasPrefix(k, "Prometheus") {
|
if strings.HasPrefix(k, "prometheus") || strings.HasPrefix(k, "Prometheus") {
|
||||||
newCollector, err := collector.NewPrometheusCollector(k, configFile)
|
newCollector, err := collector.NewPrometheusCollector(k, configFile, *applicationMetricsCountLimit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Infof("failed to create collector for container %q, config %q: %v", cont.info.Name, k, err)
|
glog.Infof("failed to create collector for container %q, config %q: %v", cont.info.Name, k, err)
|
||||||
return err
|
return err
|
||||||
@ -729,7 +769,7 @@ func (m *manager) registerCollectors(collectorConfigs map[string]string, cont *c
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
newCollector, err := collector.NewCollector(k, configFile)
|
newCollector, err := collector.NewCollector(k, configFile, *applicationMetricsCountLimit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Infof("failed to create collector for container %q, config %q: %v", cont.info.Name, k, err)
|
glog.Infof("failed to create collector for container %q, config %q: %v", cont.info.Name, k, err)
|
||||||
return err
|
return err
|
||||||
@ -784,7 +824,6 @@ func (m *manager) createContainer(containerName string) error {
|
|||||||
err = m.registerCollectors(collectorConfigs, cont)
|
err = m.registerCollectors(collectorConfigs, cont)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Infof("failed to register collectors for %q: %v", containerName, err)
|
glog.Infof("failed to register collectors for %q: %v", containerName, err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the container name and all its aliases. The aliases must be within the namespace of the factory.
|
// Add the container name and all its aliases. The aliases must be within the namespace of the factory.
|
||||||
|
2
Godeps/_workspace/src/github.com/google/cadvisor/manager/manager_mock.go
generated
vendored
2
Godeps/_workspace/src/github.com/google/cadvisor/manager/manager_mock.go
generated
vendored
@ -12,6 +12,8 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
// +build test
|
||||||
|
|
||||||
package manager
|
package manager
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
8
Godeps/_workspace/src/github.com/google/cadvisor/metrics/prometheus.go
generated
vendored
8
Godeps/_workspace/src/github.com/google/cadvisor/metrics/prometheus.go
generated
vendored
@ -542,10 +542,16 @@ func (c *PrometheusCollector) collectContainersInfo(ch chan<- prometheus.Metric)
|
|||||||
ch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, float64(container.Spec.CreationTime.Unix()), baseLabelValues...)
|
ch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, float64(container.Spec.CreationTime.Unix()), baseLabelValues...)
|
||||||
|
|
||||||
if container.Spec.HasCpu {
|
if container.Spec.HasCpu {
|
||||||
|
desc = prometheus.NewDesc("container_spec_cpu_period", "CPU period of the container.", baseLabels, nil)
|
||||||
|
ch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, float64(container.Spec.Cpu.Period), baseLabelValues...)
|
||||||
|
if container.Spec.Cpu.Quota != 0 {
|
||||||
|
desc = prometheus.NewDesc("container_spec_cpu_quota", "CPU quota of the container.", baseLabels, nil)
|
||||||
|
ch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, float64(container.Spec.Cpu.Quota), baseLabelValues...)
|
||||||
|
}
|
||||||
desc := prometheus.NewDesc("container_spec_cpu_shares", "CPU share of the container.", baseLabels, nil)
|
desc := prometheus.NewDesc("container_spec_cpu_shares", "CPU share of the container.", baseLabels, nil)
|
||||||
ch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, float64(container.Spec.Cpu.Limit), baseLabelValues...)
|
ch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, float64(container.Spec.Cpu.Limit), baseLabelValues...)
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
if container.Spec.HasMemory {
|
if container.Spec.HasMemory {
|
||||||
desc := prometheus.NewDesc("container_spec_memory_limit_bytes", "Memory limit for the container.", baseLabels, nil)
|
desc := prometheus.NewDesc("container_spec_memory_limit_bytes", "Memory limit for the container.", baseLabels, nil)
|
||||||
ch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, specMemoryValue(container.Spec.Memory.Limit), baseLabelValues...)
|
ch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, specMemoryValue(container.Spec.Memory.Limit), baseLabelValues...)
|
||||||
|
45
Godeps/_workspace/src/github.com/google/cadvisor/utils/cloudinfo/aws.go
generated
vendored
Normal file
45
Godeps/_workspace/src/github.com/google/cadvisor/utils/cloudinfo/aws.go
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
// Copyright 2015 Google Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package cloudinfo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/ec2metadata"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
|
|
||||||
|
info "github.com/google/cadvisor/info/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
func onAWS() bool {
|
||||||
|
client := ec2metadata.New(session.New(&aws.Config{}))
|
||||||
|
return client.Available()
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAwsMetadata(name string) string {
|
||||||
|
client := ec2metadata.New(session.New(&aws.Config{}))
|
||||||
|
data, err := client.GetMetadata(name)
|
||||||
|
if err != nil {
|
||||||
|
return info.UnknownInstance
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAwsInstanceType() info.InstanceType {
|
||||||
|
return info.InstanceType(getAwsMetadata("instance-type"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAwsInstanceID() info.InstanceID {
|
||||||
|
return info.InstanceID(getAwsMetadata("instance-id"))
|
||||||
|
}
|
48
Godeps/_workspace/src/github.com/google/cadvisor/utils/cloudinfo/azure.go
generated
vendored
Normal file
48
Godeps/_workspace/src/github.com/google/cadvisor/utils/cloudinfo/azure.go
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// Copyright 2015 Google Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package cloudinfo
|
||||||
|
|
||||||
|
import (
|
||||||
|
info "github.com/google/cadvisor/info/v1"
|
||||||
|
"io/ioutil"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
SysVendorFileName = "/sys/class/dmi/id/sys_vendor"
|
||||||
|
BiosUUIDFileName = "/sys/class/dmi/id/product_uuid"
|
||||||
|
MicrosoftCorporation = "Microsoft Corporation"
|
||||||
|
)
|
||||||
|
|
||||||
|
func onAzure() bool {
|
||||||
|
data, err := ioutil.ReadFile(SysVendorFileName)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return strings.Contains(string(data), MicrosoftCorporation)
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Implement method.
|
||||||
|
func getAzureInstanceType() info.InstanceType {
|
||||||
|
return info.UnknownInstance
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAzureInstanceID() info.InstanceID {
|
||||||
|
data, err := ioutil.ReadFile(BiosUUIDFileName)
|
||||||
|
if err != nil {
|
||||||
|
return info.UnNamedInstance
|
||||||
|
}
|
||||||
|
return info.InstanceID(strings.TrimSuffix(string(data), "\n"))
|
||||||
|
}
|
30
Godeps/_workspace/src/github.com/google/cadvisor/utils/cloudinfo/cloudinfo.go
generated
vendored
30
Godeps/_workspace/src/github.com/google/cadvisor/utils/cloudinfo/cloudinfo.go
generated
vendored
@ -23,19 +23,23 @@ import (
|
|||||||
type CloudInfo interface {
|
type CloudInfo interface {
|
||||||
GetCloudProvider() info.CloudProvider
|
GetCloudProvider() info.CloudProvider
|
||||||
GetInstanceType() info.InstanceType
|
GetInstanceType() info.InstanceType
|
||||||
|
GetInstanceID() info.InstanceID
|
||||||
}
|
}
|
||||||
|
|
||||||
type realCloudInfo struct {
|
type realCloudInfo struct {
|
||||||
cloudProvider info.CloudProvider
|
cloudProvider info.CloudProvider
|
||||||
instanceType info.InstanceType
|
instanceType info.InstanceType
|
||||||
|
instanceID info.InstanceID
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRealCloudInfo() CloudInfo {
|
func NewRealCloudInfo() CloudInfo {
|
||||||
cloudProvider := detectCloudProvider()
|
cloudProvider := detectCloudProvider()
|
||||||
instanceType := detectInstanceType(cloudProvider)
|
instanceType := detectInstanceType(cloudProvider)
|
||||||
|
instanceID := detectInstanceID(cloudProvider)
|
||||||
return &realCloudInfo{
|
return &realCloudInfo{
|
||||||
cloudProvider: cloudProvider,
|
cloudProvider: cloudProvider,
|
||||||
instanceType: instanceType,
|
instanceType: instanceType,
|
||||||
|
instanceID: instanceID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,12 +51,18 @@ func (self *realCloudInfo) GetInstanceType() info.InstanceType {
|
|||||||
return self.instanceType
|
return self.instanceType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *realCloudInfo) GetInstanceID() info.InstanceID {
|
||||||
|
return self.instanceID
|
||||||
|
}
|
||||||
|
|
||||||
func detectCloudProvider() info.CloudProvider {
|
func detectCloudProvider() info.CloudProvider {
|
||||||
switch {
|
switch {
|
||||||
case onGCE():
|
case onGCE():
|
||||||
return info.GCE
|
return info.GCE
|
||||||
case onAWS():
|
case onAWS():
|
||||||
return info.AWS
|
return info.AWS
|
||||||
|
case onAzure():
|
||||||
|
return info.Azure
|
||||||
case onBaremetal():
|
case onBaremetal():
|
||||||
return info.Baremetal
|
return info.Baremetal
|
||||||
}
|
}
|
||||||
@ -65,20 +75,26 @@ func detectInstanceType(cloudProvider info.CloudProvider) info.InstanceType {
|
|||||||
return getGceInstanceType()
|
return getGceInstanceType()
|
||||||
case info.AWS:
|
case info.AWS:
|
||||||
return getAwsInstanceType()
|
return getAwsInstanceType()
|
||||||
|
case info.Azure:
|
||||||
|
return getAzureInstanceType()
|
||||||
case info.Baremetal:
|
case info.Baremetal:
|
||||||
return info.NoInstance
|
return info.NoInstance
|
||||||
}
|
}
|
||||||
return info.UnknownInstance
|
return info.UnknownInstance
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Implement method.
|
func detectInstanceID(cloudProvider info.CloudProvider) info.InstanceID {
|
||||||
func onAWS() bool {
|
switch cloudProvider {
|
||||||
return false
|
case info.GCE:
|
||||||
|
return getGceInstanceID()
|
||||||
|
case info.AWS:
|
||||||
|
return getAwsInstanceID()
|
||||||
|
case info.Azure:
|
||||||
|
return getAzureInstanceID()
|
||||||
|
case info.Baremetal:
|
||||||
|
return info.UnNamedInstance
|
||||||
}
|
}
|
||||||
|
return info.UnNamedInstance
|
||||||
//TODO: Implement method.
|
|
||||||
func getAwsInstanceType() info.InstanceType {
|
|
||||||
return info.UnknownInstance
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Implement method.
|
//TODO: Implement method.
|
||||||
|
8
Godeps/_workspace/src/github.com/google/cadvisor/utils/cloudinfo/gce.go
generated
vendored
8
Godeps/_workspace/src/github.com/google/cadvisor/utils/cloudinfo/gce.go
generated
vendored
@ -35,3 +35,11 @@ func getGceInstanceType() info.InstanceType {
|
|||||||
responseParts := strings.Split(machineType, "/") // Extract the instance name from the machine type.
|
responseParts := strings.Split(machineType, "/") // Extract the instance name from the machine type.
|
||||||
return info.InstanceType(responseParts[len(responseParts)-1])
|
return info.InstanceType(responseParts[len(responseParts)-1])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getGceInstanceID() info.InstanceID {
|
||||||
|
instanceID, err := metadata.Get("instance/id")
|
||||||
|
if err != nil {
|
||||||
|
return info.UnknownInstance
|
||||||
|
}
|
||||||
|
return info.InstanceID(info.InstanceType(instanceID))
|
||||||
|
}
|
||||||
|
5
Godeps/_workspace/src/github.com/google/cadvisor/validate/validate.go
generated
vendored
5
Godeps/_workspace/src/github.com/google/cadvisor/validate/validate.go
generated
vendored
@ -192,11 +192,6 @@ func validateDockerInfo() (string, string) {
|
|||||||
execDriver := info.Get("ExecutionDriver")
|
execDriver := info.Get("ExecutionDriver")
|
||||||
storageDriver := info.Get("Driver")
|
storageDriver := info.Get("Driver")
|
||||||
desc := fmt.Sprintf("Docker exec driver is %s. Storage driver is %s.\n", execDriver, storageDriver)
|
desc := fmt.Sprintf("Docker exec driver is %s. Storage driver is %s.\n", execDriver, storageDriver)
|
||||||
if docker.UseSystemd() {
|
|
||||||
desc += "\tsystemd is being used to create cgroups.\n"
|
|
||||||
} else {
|
|
||||||
desc += "\tCgroups are being created through cgroup filesystem.\n"
|
|
||||||
}
|
|
||||||
if strings.Contains(execDriver, "native") {
|
if strings.Contains(execDriver, "native") {
|
||||||
stateFile := docker.DockerStateDir()
|
stateFile := docker.DockerStateDir()
|
||||||
if !utils.FileExists(stateFile) {
|
if !utils.FileExists(stateFile) {
|
||||||
|
2
Godeps/_workspace/src/github.com/google/cadvisor/version/VERSION
generated
vendored
2
Godeps/_workspace/src/github.com/google/cadvisor/version/VERSION
generated
vendored
@ -1 +1 @@
|
|||||||
0.21.1
|
0.22.0
|
Loading…
Reference in New Issue
Block a user