mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 20:53:33 +00:00
Update Kubernetes cadvisor to pull in @b7bbefd9b1d4c1032c6afece425a99ba17e43cdb so that the VersionInfo is not cached.
This commit is contained in:
parent
3c0a05de4a
commit
dae4142d5c
76
Godeps/Godeps.json
generated
76
Godeps/Godeps.json
generated
@ -18,10 +18,6 @@
|
|||||||
"ImportPath": "code.google.com/p/gcfg",
|
"ImportPath": "code.google.com/p/gcfg",
|
||||||
"Rev": "c2d3050044d05357eaf6c3547249ba57c5e235cb"
|
"Rev": "c2d3050044d05357eaf6c3547249ba57c5e235cb"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"ImportPath": "github.com/GoogleCloudPlatform/gcloud-golang/compute/metadata",
|
|
||||||
"Rev": "e34a32f9b0ecbc0784865fb2d47f3818c09521d4"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/Sirupsen/logrus",
|
"ImportPath": "github.com/Sirupsen/logrus",
|
||||||
"Comment": "v0.6.2-10-g51fe59a",
|
"Comment": "v0.6.2-10-g51fe59a",
|
||||||
@ -269,93 +265,93 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/api",
|
"ImportPath": "github.com/google/cadvisor/api",
|
||||||
"Comment": "0.16.0-51-g78419de",
|
"Comment": "0.16.0-81-g27fb6d5",
|
||||||
"Rev": "78419de3ea9c2d23cb04ec9d63f8899de34ebd43"
|
"Rev": "27fb6d593c6bffe274718119659815771e79e198"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/cache/memory",
|
"ImportPath": "github.com/google/cadvisor/cache/memory",
|
||||||
"Comment": "0.16.0-51-g78419de",
|
"Comment": "0.16.0-81-g27fb6d5",
|
||||||
"Rev": "78419de3ea9c2d23cb04ec9d63f8899de34ebd43"
|
"Rev": "27fb6d593c6bffe274718119659815771e79e198"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/collector",
|
"ImportPath": "github.com/google/cadvisor/collector",
|
||||||
"Comment": "0.16.0-51-g78419de",
|
"Comment": "0.16.0-81-g27fb6d5",
|
||||||
"Rev": "78419de3ea9c2d23cb04ec9d63f8899de34ebd43"
|
"Rev": "27fb6d593c6bffe274718119659815771e79e198"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/container",
|
"ImportPath": "github.com/google/cadvisor/container",
|
||||||
"Comment": "0.16.0-51-g78419de",
|
"Comment": "0.16.0-81-g27fb6d5",
|
||||||
"Rev": "78419de3ea9c2d23cb04ec9d63f8899de34ebd43"
|
"Rev": "27fb6d593c6bffe274718119659815771e79e198"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/events",
|
"ImportPath": "github.com/google/cadvisor/events",
|
||||||
"Comment": "0.16.0-51-g78419de",
|
"Comment": "0.16.0-81-g27fb6d5",
|
||||||
"Rev": "78419de3ea9c2d23cb04ec9d63f8899de34ebd43"
|
"Rev": "27fb6d593c6bffe274718119659815771e79e198"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/fs",
|
"ImportPath": "github.com/google/cadvisor/fs",
|
||||||
"Comment": "0.16.0-51-g78419de",
|
"Comment": "0.16.0-81-g27fb6d5",
|
||||||
"Rev": "78419de3ea9c2d23cb04ec9d63f8899de34ebd43"
|
"Rev": "27fb6d593c6bffe274718119659815771e79e198"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/healthz",
|
"ImportPath": "github.com/google/cadvisor/healthz",
|
||||||
"Comment": "0.16.0-51-g78419de",
|
"Comment": "0.16.0-81-g27fb6d5",
|
||||||
"Rev": "78419de3ea9c2d23cb04ec9d63f8899de34ebd43"
|
"Rev": "27fb6d593c6bffe274718119659815771e79e198"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/http",
|
"ImportPath": "github.com/google/cadvisor/http",
|
||||||
"Comment": "0.16.0-51-g78419de",
|
"Comment": "0.16.0-81-g27fb6d5",
|
||||||
"Rev": "78419de3ea9c2d23cb04ec9d63f8899de34ebd43"
|
"Rev": "27fb6d593c6bffe274718119659815771e79e198"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/info/v1",
|
"ImportPath": "github.com/google/cadvisor/info/v1",
|
||||||
"Comment": "0.16.0-51-g78419de",
|
"Comment": "0.16.0-81-g27fb6d5",
|
||||||
"Rev": "78419de3ea9c2d23cb04ec9d63f8899de34ebd43"
|
"Rev": "27fb6d593c6bffe274718119659815771e79e198"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/info/v2",
|
"ImportPath": "github.com/google/cadvisor/info/v2",
|
||||||
"Comment": "0.16.0-51-g78419de",
|
"Comment": "0.16.0-81-g27fb6d5",
|
||||||
"Rev": "78419de3ea9c2d23cb04ec9d63f8899de34ebd43"
|
"Rev": "27fb6d593c6bffe274718119659815771e79e198"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/manager",
|
"ImportPath": "github.com/google/cadvisor/manager",
|
||||||
"Comment": "0.16.0-51-g78419de",
|
"Comment": "0.16.0-81-g27fb6d5",
|
||||||
"Rev": "78419de3ea9c2d23cb04ec9d63f8899de34ebd43"
|
"Rev": "27fb6d593c6bffe274718119659815771e79e198"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/metrics",
|
"ImportPath": "github.com/google/cadvisor/metrics",
|
||||||
"Comment": "0.16.0-51-g78419de",
|
"Comment": "0.16.0-81-g27fb6d5",
|
||||||
"Rev": "78419de3ea9c2d23cb04ec9d63f8899de34ebd43"
|
"Rev": "27fb6d593c6bffe274718119659815771e79e198"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/pages",
|
"ImportPath": "github.com/google/cadvisor/pages",
|
||||||
"Comment": "0.16.0-51-g78419de",
|
"Comment": "0.16.0-81-g27fb6d5",
|
||||||
"Rev": "78419de3ea9c2d23cb04ec9d63f8899de34ebd43"
|
"Rev": "27fb6d593c6bffe274718119659815771e79e198"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/storage",
|
"ImportPath": "github.com/google/cadvisor/storage",
|
||||||
"Comment": "0.16.0-51-g78419de",
|
"Comment": "0.16.0-81-g27fb6d5",
|
||||||
"Rev": "78419de3ea9c2d23cb04ec9d63f8899de34ebd43"
|
"Rev": "27fb6d593c6bffe274718119659815771e79e198"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/summary",
|
"ImportPath": "github.com/google/cadvisor/summary",
|
||||||
"Comment": "0.16.0-51-g78419de",
|
"Comment": "0.16.0-81-g27fb6d5",
|
||||||
"Rev": "78419de3ea9c2d23cb04ec9d63f8899de34ebd43"
|
"Rev": "27fb6d593c6bffe274718119659815771e79e198"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/utils",
|
"ImportPath": "github.com/google/cadvisor/utils",
|
||||||
"Comment": "0.16.0-51-g78419de",
|
"Comment": "0.16.0-81-g27fb6d5",
|
||||||
"Rev": "78419de3ea9c2d23cb04ec9d63f8899de34ebd43"
|
"Rev": "27fb6d593c6bffe274718119659815771e79e198"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/validate",
|
"ImportPath": "github.com/google/cadvisor/validate",
|
||||||
"Comment": "0.16.0-51-g78419de",
|
"Comment": "0.16.0-81-g27fb6d5",
|
||||||
"Rev": "78419de3ea9c2d23cb04ec9d63f8899de34ebd43"
|
"Rev": "27fb6d593c6bffe274718119659815771e79e198"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/version",
|
"ImportPath": "github.com/google/cadvisor/version",
|
||||||
"Comment": "0.16.0-51-g78419de",
|
"Comment": "0.16.0-81-g27fb6d5",
|
||||||
"Rev": "78419de3ea9c2d23cb04ec9d63f8899de34ebd43"
|
"Rev": "27fb6d593c6bffe274718119659815771e79e198"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/gofuzz",
|
"ImportPath": "github.com/google/gofuzz",
|
||||||
|
34
Godeps/_workspace/src/github.com/google/cadvisor/api/versions.go
generated
vendored
34
Godeps/_workspace/src/github.com/google/cadvisor/api/versions.go
generated
vendored
@ -372,19 +372,33 @@ func (self *version2_0) HandleRequest(requestType string, request []string, m ma
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
specs, err := m.GetContainerSpec(containerName, opt)
|
contMetrics := make(map[string]map[string]map[string][]info.MetricValBasic, 0)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
contMetrics := make(map[string]map[string][]info.MetricVal, 0)
|
|
||||||
for _, cont := range conts {
|
for _, cont := range conts {
|
||||||
metrics := map[string][]info.MetricVal{}
|
metrics := make(map[string]map[string][]info.MetricValBasic, 0)
|
||||||
contStats := convertStats(cont)
|
contStats := convertStats(cont)
|
||||||
spec := specs[cont.Name]
|
|
||||||
for _, contStat := range contStats {
|
for _, contStat := range contStats {
|
||||||
for _, ms := range spec.CustomMetrics {
|
if contStat.HasCustomMetrics {
|
||||||
if contStat.HasCustomMetrics && !contStat.CustomMetrics[ms.Name].Timestamp.IsZero() {
|
for name, allLabels := range contStat.CustomMetrics {
|
||||||
metrics[ms.Name] = append(metrics[ms.Name], contStat.CustomMetrics[ms.Name])
|
metricLabels := make(map[string][]info.MetricValBasic, 0)
|
||||||
|
for _, metric := range allLabels {
|
||||||
|
if !metric.Timestamp.IsZero() {
|
||||||
|
metVal := info.MetricValBasic{
|
||||||
|
Timestamp: metric.Timestamp,
|
||||||
|
IntValue: metric.IntValue,
|
||||||
|
FloatValue: metric.FloatValue,
|
||||||
|
}
|
||||||
|
labels := metrics[name]
|
||||||
|
if labels != nil {
|
||||||
|
values := labels[metric.Label]
|
||||||
|
values = append(values, metVal)
|
||||||
|
labels[metric.Label] = values
|
||||||
|
metrics[name] = labels
|
||||||
|
} else {
|
||||||
|
metricLabels[metric.Label] = []info.MetricValBasic{metVal}
|
||||||
|
metrics[name] = metricLabels
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
4
Godeps/_workspace/src/github.com/google/cadvisor/collector/collector_manager.go
generated
vendored
4
Godeps/_workspace/src/github.com/google/cadvisor/collector/collector_manager.go
generated
vendored
@ -71,12 +71,12 @@ func (cm *GenericCollectorManager) GetSpec() ([]v1.MetricSpec, error) {
|
|||||||
return metricSpec, nil
|
return metricSpec, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cm *GenericCollectorManager) Collect() (time.Time, map[string]v1.MetricVal, error) {
|
func (cm *GenericCollectorManager) Collect() (time.Time, map[string][]v1.MetricVal, error) {
|
||||||
var errors []error
|
var errors []error
|
||||||
|
|
||||||
// Collect from all collectors that are ready.
|
// Collect from all collectors that are ready.
|
||||||
var next time.Time
|
var next time.Time
|
||||||
metrics := map[string]v1.MetricVal{}
|
metrics := map[string][]v1.MetricVal{}
|
||||||
for _, c := range cm.Collectors {
|
for _, c := range cm.Collectors {
|
||||||
if c.nextCollectionTime.Before(time.Now()) {
|
if c.nextCollectionTime.Before(time.Now()) {
|
||||||
var err error
|
var err error
|
||||||
|
2
Godeps/_workspace/src/github.com/google/cadvisor/collector/collector_manager_test.go
generated
vendored
2
Godeps/_workspace/src/github.com/google/cadvisor/collector/collector_manager_test.go
generated
vendored
@ -28,7 +28,7 @@ type fakeCollector struct {
|
|||||||
collectedFrom int
|
collectedFrom int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fc *fakeCollector) Collect(metric map[string]v1.MetricVal) (time.Time, map[string]v1.MetricVal, error) {
|
func (fc *fakeCollector) Collect(metric map[string][]v1.MetricVal) (time.Time, map[string][]v1.MetricVal, error) {
|
||||||
fc.collectedFrom++
|
fc.collectedFrom++
|
||||||
return fc.nextCollectionTime, metric, fc.err
|
return fc.nextCollectionTime, metric, fc.err
|
||||||
}
|
}
|
||||||
|
11
Godeps/_workspace/src/github.com/google/cadvisor/collector/config.go
generated
vendored
11
Godeps/_workspace/src/github.com/google/cadvisor/collector/config.go
generated
vendored
@ -48,3 +48,14 @@ type MetricConfig struct {
|
|||||||
//the regular expression that can be used to extract the metric
|
//the regular expression that can be used to extract the metric
|
||||||
Regex string `json:"regex"`
|
Regex string `json:"regex"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Prometheus struct {
|
||||||
|
//the endpoint to hit to scrape metrics
|
||||||
|
Endpoint string `json:"endpoint"`
|
||||||
|
|
||||||
|
//the frequency at which metrics should be collected
|
||||||
|
PollingFrequency time.Duration `json:"polling_frequency"`
|
||||||
|
|
||||||
|
//holds names of different metrics that can be collected
|
||||||
|
MetricsConfig []string `json:"metrics_config"`
|
||||||
|
}
|
||||||
|
6
Godeps/_workspace/src/github.com/google/cadvisor/collector/config/sample_config_prometheus.json
generated
vendored
Normal file
6
Godeps/_workspace/src/github.com/google/cadvisor/collector/config/sample_config_prometheus.json
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"endpoint" : "http://localhost:8080/metrics",
|
||||||
|
"polling_frequency" : 10,
|
||||||
|
"metrics_config" : [
|
||||||
|
]
|
||||||
|
}
|
2
Godeps/_workspace/src/github.com/google/cadvisor/collector/fakes.go
generated
vendored
2
Godeps/_workspace/src/github.com/google/cadvisor/collector/fakes.go
generated
vendored
@ -31,7 +31,7 @@ func (fkm *FakeCollectorManager) GetSpec() ([]v1.MetricSpec, error) {
|
|||||||
return []v1.MetricSpec{}, nil
|
return []v1.MetricSpec{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fkm *FakeCollectorManager) Collect(metric map[string]v1.MetricVal) (time.Time, map[string]v1.MetricVal, error) {
|
func (fkm *FakeCollectorManager) Collect(metric map[string][]v1.MetricVal) (time.Time, map[string][]v1.MetricVal, error) {
|
||||||
var zero time.Time
|
var zero time.Time
|
||||||
return zero, metric, nil
|
return zero, metric, nil
|
||||||
}
|
}
|
||||||
|
10
Godeps/_workspace/src/github.com/google/cadvisor/collector/generic_collector.go
generated
vendored
10
Godeps/_workspace/src/github.com/google/cadvisor/collector/generic_collector.go
generated
vendored
@ -116,7 +116,7 @@ func (collector *GenericCollector) GetSpec() []v1.MetricSpec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Returns collected metrics and the next collection time of the collector
|
//Returns collected metrics and the next collection time of the collector
|
||||||
func (collector *GenericCollector) Collect(metrics map[string]v1.MetricVal) (time.Time, map[string]v1.MetricVal, error) {
|
func (collector *GenericCollector) Collect(metrics map[string][]v1.MetricVal) (time.Time, map[string][]v1.MetricVal, error) {
|
||||||
currentTime := time.Now()
|
currentTime := time.Now()
|
||||||
nextCollectionTime := currentTime.Add(time.Duration(collector.info.minPollingFrequency))
|
nextCollectionTime := currentTime.Add(time.Duration(collector.info.minPollingFrequency))
|
||||||
|
|
||||||
@ -142,16 +142,16 @@ func (collector *GenericCollector) Collect(metrics map[string]v1.MetricVal) (tim
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
errorSlice = append(errorSlice, err)
|
errorSlice = append(errorSlice, err)
|
||||||
}
|
}
|
||||||
metrics[metricConfig.Name] = v1.MetricVal{
|
metrics[metricConfig.Name] = []v1.MetricVal{
|
||||||
FloatValue: regVal, Timestamp: currentTime,
|
{FloatValue: regVal, Timestamp: currentTime},
|
||||||
}
|
}
|
||||||
} else if metricConfig.DataType == v1.IntType {
|
} else if metricConfig.DataType == v1.IntType {
|
||||||
regVal, err := strconv.ParseInt(strings.TrimSpace(matchString[1]), 10, 64)
|
regVal, err := strconv.ParseInt(strings.TrimSpace(matchString[1]), 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorSlice = append(errorSlice, err)
|
errorSlice = append(errorSlice, err)
|
||||||
}
|
}
|
||||||
metrics[metricConfig.Name] = v1.MetricVal{
|
metrics[metricConfig.Name] = []v1.MetricVal{
|
||||||
IntValue: regVal, Timestamp: currentTime,
|
{IntValue: regVal, Timestamp: currentTime},
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
18
Godeps/_workspace/src/github.com/google/cadvisor/collector/generic_collector_test.go
generated
vendored
18
Godeps/_workspace/src/github.com/google/cadvisor/collector/generic_collector_test.go
generated
vendored
@ -148,20 +148,20 @@ func TestMetricCollection(t *testing.T) {
|
|||||||
defer tempServer.Close()
|
defer tempServer.Close()
|
||||||
fakeCollector.configFile.Endpoint = tempServer.URL
|
fakeCollector.configFile.Endpoint = tempServer.URL
|
||||||
|
|
||||||
metrics := map[string]v1.MetricVal{}
|
metrics := map[string][]v1.MetricVal{}
|
||||||
_, metrics, errMetric := fakeCollector.Collect(metrics)
|
_, metrics, errMetric := fakeCollector.Collect(metrics)
|
||||||
assert.NoError(errMetric)
|
assert.NoError(errMetric)
|
||||||
metricNames := []string{"activeConnections", "reading", "writing", "waiting"}
|
metricNames := []string{"activeConnections", "reading", "writing", "waiting"}
|
||||||
// activeConnections = 3
|
// activeConnections = 3
|
||||||
assert.Equal(metrics[metricNames[0]].IntValue, 3)
|
assert.Equal(metrics[metricNames[0]][0].IntValue, 3)
|
||||||
assert.Equal(metrics[metricNames[0]].FloatValue, 0)
|
assert.Equal(metrics[metricNames[0]][0].FloatValue, 0)
|
||||||
// reading = 0
|
// reading = 0
|
||||||
assert.Equal(metrics[metricNames[1]].IntValue, 0)
|
assert.Equal(metrics[metricNames[1]][0].IntValue, 0)
|
||||||
assert.Equal(metrics[metricNames[1]].FloatValue, 0)
|
assert.Equal(metrics[metricNames[1]][0].FloatValue, 0)
|
||||||
// writing = 1
|
// writing = 1
|
||||||
assert.Equal(metrics[metricNames[2]].IntValue, 1)
|
assert.Equal(metrics[metricNames[2]][0].IntValue, 1)
|
||||||
assert.Equal(metrics[metricNames[2]].FloatValue, 0)
|
assert.Equal(metrics[metricNames[2]][0].FloatValue, 0)
|
||||||
// waiting = 2
|
// waiting = 2
|
||||||
assert.Equal(metrics[metricNames[3]].IntValue, 2)
|
assert.Equal(metrics[metricNames[3]][0].IntValue, 2)
|
||||||
assert.Equal(metrics[metricNames[3]].FloatValue, 0)
|
assert.Equal(metrics[metricNames[3]][0].FloatValue, 0)
|
||||||
}
|
}
|
||||||
|
170
Godeps/_workspace/src/github.com/google/cadvisor/collector/prometheus_collector.go
generated
vendored
Normal file
170
Godeps/_workspace/src/github.com/google/cadvisor/collector/prometheus_collector.go
generated
vendored
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
// 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 collector
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io/ioutil"
|
||||||
|
"math"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/cadvisor/info/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PrometheusCollector struct {
|
||||||
|
//name of the collector
|
||||||
|
name string
|
||||||
|
|
||||||
|
//rate at which metrics are collected
|
||||||
|
pollingFrequency time.Duration
|
||||||
|
|
||||||
|
//holds information extracted from the config file for a collector
|
||||||
|
configFile Prometheus
|
||||||
|
}
|
||||||
|
|
||||||
|
//Returns a new collector using the information extracted from the configfile
|
||||||
|
func NewPrometheusCollector(collectorName string, configFile []byte) (*PrometheusCollector, error) {
|
||||||
|
var configInJSON Prometheus
|
||||||
|
err := json.Unmarshal(configFile, &configInJSON)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
minPollingFrequency := configInJSON.PollingFrequency
|
||||||
|
|
||||||
|
// Minimum supported frequency is 1s
|
||||||
|
minSupportedFrequency := 1 * time.Second
|
||||||
|
|
||||||
|
if minPollingFrequency < minSupportedFrequency {
|
||||||
|
minPollingFrequency = minSupportedFrequency
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO : Add checks for validity of config file (eg : Accurate JSON fields)
|
||||||
|
return &PrometheusCollector{
|
||||||
|
name: collectorName,
|
||||||
|
pollingFrequency: minPollingFrequency,
|
||||||
|
configFile: configInJSON,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//Returns name of the collector
|
||||||
|
func (collector *PrometheusCollector) Name() string {
|
||||||
|
return collector.name
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMetricData(line string) string {
|
||||||
|
fields := strings.Fields(line)
|
||||||
|
data := fields[3]
|
||||||
|
if len(fields) > 4 {
|
||||||
|
for i := range fields {
|
||||||
|
if i > 3 {
|
||||||
|
data = data + "_" + fields[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (collector *PrometheusCollector) GetSpec() []v1.MetricSpec {
|
||||||
|
specs := []v1.MetricSpec{}
|
||||||
|
response, err := http.Get(collector.configFile.Endpoint)
|
||||||
|
if err != nil {
|
||||||
|
return specs
|
||||||
|
}
|
||||||
|
defer response.Body.Close()
|
||||||
|
|
||||||
|
pageContent, err := ioutil.ReadAll(response.Body)
|
||||||
|
if err != nil {
|
||||||
|
return specs
|
||||||
|
}
|
||||||
|
|
||||||
|
lines := strings.Split(string(pageContent), "\n")
|
||||||
|
for i, line := range lines {
|
||||||
|
if strings.HasPrefix(line, "# HELP") {
|
||||||
|
stopIndex := strings.Index(lines[i+2], "{")
|
||||||
|
if stopIndex == -1 {
|
||||||
|
stopIndex = strings.Index(lines[i+2], " ")
|
||||||
|
}
|
||||||
|
spec := v1.MetricSpec{
|
||||||
|
Name: strings.TrimSpace(lines[i+2][0:stopIndex]),
|
||||||
|
Type: v1.MetricType(getMetricData(lines[i+1])),
|
||||||
|
Format: "float",
|
||||||
|
Units: getMetricData(lines[i]),
|
||||||
|
}
|
||||||
|
specs = append(specs, spec)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return specs
|
||||||
|
}
|
||||||
|
|
||||||
|
//Returns collected metrics and the next collection time of the collector
|
||||||
|
func (collector *PrometheusCollector) Collect(metrics map[string][]v1.MetricVal) (time.Time, map[string][]v1.MetricVal, error) {
|
||||||
|
currentTime := time.Now()
|
||||||
|
nextCollectionTime := currentTime.Add(time.Duration(collector.pollingFrequency))
|
||||||
|
|
||||||
|
uri := collector.configFile.Endpoint
|
||||||
|
response, err := http.Get(uri)
|
||||||
|
if err != nil {
|
||||||
|
return nextCollectionTime, nil, err
|
||||||
|
}
|
||||||
|
defer response.Body.Close()
|
||||||
|
|
||||||
|
pageContent, err := ioutil.ReadAll(response.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nextCollectionTime, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var errorSlice []error
|
||||||
|
lines := strings.Split(string(pageContent), "\n")
|
||||||
|
|
||||||
|
for _, line := range lines {
|
||||||
|
if line == "" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if !strings.HasPrefix(line, "# HELP") && !strings.HasPrefix(line, "# TYPE") {
|
||||||
|
var metLabel string
|
||||||
|
startLabelIndex := strings.Index(line, "{")
|
||||||
|
spaceIndex := strings.Index(line, " ")
|
||||||
|
if startLabelIndex == -1 {
|
||||||
|
startLabelIndex = spaceIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
metName := strings.TrimSpace(line[0:startLabelIndex])
|
||||||
|
|
||||||
|
if startLabelIndex+1 <= spaceIndex-1 {
|
||||||
|
metLabel = strings.TrimSpace(line[(startLabelIndex + 1):(spaceIndex - 1)])
|
||||||
|
}
|
||||||
|
|
||||||
|
metVal, err := strconv.ParseFloat(line[spaceIndex+1:], 64)
|
||||||
|
if err != nil {
|
||||||
|
errorSlice = append(errorSlice, err)
|
||||||
|
}
|
||||||
|
if math.IsNaN(metVal) {
|
||||||
|
metVal = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
metric := v1.MetricVal{
|
||||||
|
Label: metLabel,
|
||||||
|
FloatValue: metVal,
|
||||||
|
Timestamp: currentTime,
|
||||||
|
}
|
||||||
|
metrics[metName] = append(metrics[metName], metric)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nextCollectionTime, metrics, compileErrors(errorSlice)
|
||||||
|
}
|
64
Godeps/_workspace/src/github.com/google/cadvisor/collector/prometheus_collector_test.go
generated
vendored
Normal file
64
Godeps/_workspace/src/github.com/google/cadvisor/collector/prometheus_collector_test.go
generated
vendored
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// 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 collector
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/cadvisor/info/v1"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPrometheus(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
//Create a prometheus collector using the config file 'sample_config_prometheus.json'
|
||||||
|
configFile, err := ioutil.ReadFile("config/sample_config_prometheus.json")
|
||||||
|
collector, err := NewPrometheusCollector("Prometheus", configFile)
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.Equal(collector.name, "Prometheus")
|
||||||
|
assert.Equal(collector.configFile.Endpoint, "http://localhost:8080/metrics")
|
||||||
|
|
||||||
|
tempServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
text := "# HELP go_gc_duration_seconds A summary of the GC invocation durations.\n"
|
||||||
|
text += "# TYPE go_gc_duration_seconds summary\n"
|
||||||
|
text += "go_gc_duration_seconds{quantile=\"0\"} 5.8348000000000004e-05\n"
|
||||||
|
text += "go_gc_duration_seconds{quantile=\"1\"} 0.000499764\n"
|
||||||
|
text += "# HELP go_goroutines Number of goroutines that currently exist.\n"
|
||||||
|
text += "# TYPE go_goroutines gauge\n"
|
||||||
|
text += "go_goroutines 16"
|
||||||
|
fmt.Fprintln(w, text)
|
||||||
|
}))
|
||||||
|
|
||||||
|
defer tempServer.Close()
|
||||||
|
|
||||||
|
collector.configFile.Endpoint = tempServer.URL
|
||||||
|
metrics := map[string][]v1.MetricVal{}
|
||||||
|
_, metrics, errMetric := collector.Collect(metrics)
|
||||||
|
|
||||||
|
assert.NoError(errMetric)
|
||||||
|
|
||||||
|
go_gc_duration := metrics["go_gc_duration_seconds"]
|
||||||
|
assert.Equal(go_gc_duration[0].FloatValue, 5.8348000000000004e-05)
|
||||||
|
assert.Equal(go_gc_duration[1].FloatValue, 0.000499764)
|
||||||
|
|
||||||
|
goRoutines := metrics["go_goroutines"]
|
||||||
|
assert.Equal(goRoutines[0].FloatValue, 16)
|
||||||
|
}
|
4
Godeps/_workspace/src/github.com/google/cadvisor/collector/types.go
generated
vendored
4
Godeps/_workspace/src/github.com/google/cadvisor/collector/types.go
generated
vendored
@ -27,7 +27,7 @@ type Collector interface {
|
|||||||
// Returns the next time this collector should be collected from.
|
// Returns the next time this collector should be collected from.
|
||||||
// Next collection time is always returned, even when an error occurs.
|
// Next collection time is always returned, even when an error occurs.
|
||||||
// A collection time of zero means no more collection.
|
// A collection time of zero means no more collection.
|
||||||
Collect(map[string]v1.MetricVal) (time.Time, map[string]v1.MetricVal, error)
|
Collect(map[string][]v1.MetricVal) (time.Time, map[string][]v1.MetricVal, error)
|
||||||
|
|
||||||
// Return spec for all metrics associated with this collector
|
// Return spec for all metrics associated with this collector
|
||||||
GetSpec() []v1.MetricSpec
|
GetSpec() []v1.MetricSpec
|
||||||
@ -45,7 +45,7 @@ type CollectorManager interface {
|
|||||||
// at which a collector will be ready to collect from.
|
// at which a collector will be ready to collect from.
|
||||||
// Next collection time is always returned, even when an error occurs.
|
// Next collection time is always returned, even when an error occurs.
|
||||||
// A collection time of zero means no more collection.
|
// A collection time of zero means no more collection.
|
||||||
Collect() (time.Time, map[string]v1.MetricVal, error)
|
Collect() (time.Time, map[string][]v1.MetricVal, error)
|
||||||
|
|
||||||
// Get metric spec from all registered collectors.
|
// Get metric spec from all registered collectors.
|
||||||
GetSpec() ([]v1.MetricSpec, error)
|
GetSpec() ([]v1.MetricSpec, error)
|
||||||
|
11
Godeps/_workspace/src/github.com/google/cadvisor/container/docker/handler.go
generated
vendored
11
Godeps/_workspace/src/github.com/google/cadvisor/container/docker/handler.go
generated
vendored
@ -167,7 +167,16 @@ func libcontainerConfigToContainerSpec(config *libcontainerConfigs.Config, mi *i
|
|||||||
}
|
}
|
||||||
spec.Cpu.Mask = utils.FixCpuMask(config.Cgroups.CpusetCpus, mi.NumCores)
|
spec.Cpu.Mask = utils.FixCpuMask(config.Cgroups.CpusetCpus, mi.NumCores)
|
||||||
|
|
||||||
spec.HasNetwork = len(config.Networks) > 0
|
// Docker reports a loop device for containers with --net=host. Ignore
|
||||||
|
// those too.
|
||||||
|
networkCount := 0
|
||||||
|
for _, n := range config.Networks {
|
||||||
|
if n.Type != "loopback" {
|
||||||
|
networkCount += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spec.HasNetwork = networkCount > 0
|
||||||
spec.HasDiskIo = true
|
spec.HasDiskIo = true
|
||||||
|
|
||||||
return spec
|
return spec
|
||||||
|
2
Godeps/_workspace/src/github.com/google/cadvisor/info/v1/container.go
generated
vendored
2
Godeps/_workspace/src/github.com/google/cadvisor/info/v1/container.go
generated
vendored
@ -427,7 +427,7 @@ type ContainerStats struct {
|
|||||||
TaskStats LoadStats `json:"task_stats,omitempty"`
|
TaskStats LoadStats `json:"task_stats,omitempty"`
|
||||||
|
|
||||||
//Custom metrics from all collectors
|
//Custom metrics from all collectors
|
||||||
CustomMetrics map[string]MetricVal `json:"custom_metrics,omitempty"`
|
CustomMetrics map[string][]MetricVal `json:"custom_metrics,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func timeEq(t1, t2 time.Time, tolerance time.Duration) bool {
|
func timeEq(t1, t2 time.Time, tolerance time.Duration) bool {
|
||||||
|
15
Godeps/_workspace/src/github.com/google/cadvisor/info/v1/metric.go
generated
vendored
15
Godeps/_workspace/src/github.com/google/cadvisor/info/v1/metric.go
generated
vendored
@ -56,7 +56,20 @@ type MetricSpec struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// An exported metric.
|
// An exported metric.
|
||||||
type MetricVal struct {
|
type MetricValBasic struct {
|
||||||
|
// Time at which the metric was queried
|
||||||
|
Timestamp time.Time `json:"timestamp"`
|
||||||
|
|
||||||
|
// The value of the metric at this point.
|
||||||
|
IntValue int64 `json:"int_value,omitempty"`
|
||||||
|
FloatValue float64 `json:"float_value,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// An exported metric.
|
||||||
|
type MetricVal struct {
|
||||||
|
// Label associated with a metric
|
||||||
|
Label string `json:"label,omitempty"`
|
||||||
|
|
||||||
// Time at which the metric was queried
|
// Time at which the metric was queried
|
||||||
Timestamp time.Time `json:"timestamp"`
|
Timestamp time.Time `json:"timestamp"`
|
||||||
|
|
||||||
|
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
@ -104,8 +104,8 @@ type ContainerStats struct {
|
|||||||
HasLoad bool `json:"has_load"`
|
HasLoad bool `json:"has_load"`
|
||||||
Load v1.LoadStats `json:"load_stats,omitempty"`
|
Load v1.LoadStats `json:"load_stats,omitempty"`
|
||||||
// Custom Metrics
|
// Custom Metrics
|
||||||
HasCustomMetrics bool `json:"has_custom_metrics"`
|
HasCustomMetrics bool `json:"has_custom_metrics"`
|
||||||
CustomMetrics map[string]v1.MetricVal `json:"custom_metrics,omitempty"`
|
CustomMetrics map[string][]v1.MetricVal `json:"custom_metrics,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Percentiles struct {
|
type Percentiles struct {
|
||||||
|
6
Godeps/_workspace/src/github.com/google/cadvisor/manager/container.go
generated
vendored
6
Godeps/_workspace/src/github.com/google/cadvisor/manager/container.go
generated
vendored
@ -42,7 +42,7 @@ import (
|
|||||||
// Housekeeping interval.
|
// Housekeeping interval.
|
||||||
var HousekeepingInterval = flag.Duration("housekeeping_interval", 1*time.Second, "Interval between container housekeepings")
|
var HousekeepingInterval = flag.Duration("housekeeping_interval", 1*time.Second, "Interval between container housekeepings")
|
||||||
|
|
||||||
var cgroupPathRegExp = regexp.MustCompile(".*:devices:(.*?),.*")
|
var cgroupPathRegExp = regexp.MustCompile(".*devices:(.*?)[,;$].*")
|
||||||
|
|
||||||
// Decay value used for load average smoothing. Interval length of 10 seconds is used.
|
// Decay value used for load average smoothing. Interval length of 10 seconds is used.
|
||||||
var loadDecay = math.Exp(float64(-1 * (*HousekeepingInterval).Seconds() / 10))
|
var loadDecay = math.Exp(float64(-1 * (*HousekeepingInterval).Seconds() / 10))
|
||||||
@ -416,6 +416,8 @@ func (c *containerData) housekeeping() {
|
|||||||
// Schedule the next housekeeping. Sleep until that time.
|
// Schedule the next housekeeping. Sleep until that time.
|
||||||
if time.Now().Before(next) {
|
if time.Now().Before(next) {
|
||||||
time.Sleep(next.Sub(time.Now()))
|
time.Sleep(next.Sub(time.Now()))
|
||||||
|
} else {
|
||||||
|
next = time.Now()
|
||||||
}
|
}
|
||||||
lastHousekeeping = next
|
lastHousekeeping = next
|
||||||
}
|
}
|
||||||
@ -529,7 +531,7 @@ func (c *containerData) updateStats() error {
|
|||||||
return customStatsErr
|
return customStatsErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *containerData) updateCustomStats() (map[string]info.MetricVal, error) {
|
func (c *containerData) updateCustomStats() (map[string][]info.MetricVal, error) {
|
||||||
_, customStats, customStatsErr := c.collectorManager.Collect()
|
_, customStats, customStatsErr := c.collectorManager.Collect()
|
||||||
if customStatsErr != nil {
|
if customStatsErr != nil {
|
||||||
if !c.handler.Exists() {
|
if !c.handler.Exists() {
|
||||||
|
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
@ -161,8 +161,7 @@ func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, maxHousekeepingIn
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
newManager.versionInfo = *versionInfo
|
glog.Infof("Version: %+v", *versionInfo)
|
||||||
glog.Infof("Version: %+v", newManager.versionInfo)
|
|
||||||
|
|
||||||
newManager.eventHandler = events.NewEventManager(parseEventsStoragePolicy())
|
newManager.eventHandler = events.NewEventManager(parseEventsStoragePolicy())
|
||||||
return newManager, nil
|
return newManager, nil
|
||||||
@ -183,7 +182,6 @@ type manager struct {
|
|||||||
memoryCache *memory.InMemoryCache
|
memoryCache *memory.InMemoryCache
|
||||||
fsInfo fs.FsInfo
|
fsInfo fs.FsInfo
|
||||||
machineInfo info.MachineInfo
|
machineInfo info.MachineInfo
|
||||||
versionInfo info.VersionInfo
|
|
||||||
quitChannels []chan error
|
quitChannels []chan error
|
||||||
cadvisorContainer string
|
cadvisorContainer string
|
||||||
inHostNamespace bool
|
inHostNamespace bool
|
||||||
@ -221,7 +219,7 @@ func (self *manager) Start() error {
|
|||||||
} else {
|
} else {
|
||||||
err = cpuLoadReader.Start()
|
err = cpuLoadReader.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Warning("Could not start cpu load stat collector: %s", err)
|
glog.Warningf("Could not start cpu load stat collector: %s", err)
|
||||||
} else {
|
} else {
|
||||||
self.loadReader = cpuLoadReader
|
self.loadReader = cpuLoadReader
|
||||||
}
|
}
|
||||||
@ -658,7 +656,11 @@ func (m *manager) GetMachineInfo() (*info.MachineInfo, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *manager) GetVersionInfo() (*info.VersionInfo, error) {
|
func (m *manager) GetVersionInfo() (*info.VersionInfo, error) {
|
||||||
return &m.versionInfo, nil
|
// TODO: Consider caching this and periodically updating. The VersionInfo may change if
|
||||||
|
// the docker daemon is started after the cAdvisor client is created. Caching the value
|
||||||
|
// would be helpful so we would be able to return the last known docker version if
|
||||||
|
// docker was down at the time of a query.
|
||||||
|
return getVersionInfo()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *manager) Exists(containerName string) bool {
|
func (m *manager) Exists(containerName string) bool {
|
||||||
@ -705,15 +707,28 @@ 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)
|
||||||
|
|
||||||
newCollector, err := collector.NewCollector(k, configFile)
|
if strings.HasPrefix(k, "prometheus") || strings.HasPrefix(k, "Prometheus") {
|
||||||
if err != nil {
|
newCollector, err := collector.NewPrometheusCollector(k, configFile)
|
||||||
glog.Infof("failed to create collector for container %q, config %q: %v", cont.info.Name, k, err)
|
if err != nil {
|
||||||
return err
|
glog.Infof("failed to create collector for container %q, config %q: %v", cont.info.Name, k, err)
|
||||||
}
|
return err
|
||||||
err = cont.collectorManager.RegisterCollector(newCollector)
|
}
|
||||||
if err != nil {
|
err = cont.collectorManager.RegisterCollector(newCollector)
|
||||||
glog.Infof("failed to register collector for container %q, config %q: %v", cont.info.Name, k, err)
|
if err != nil {
|
||||||
return err
|
glog.Infof("failed to register collector for container %q, config %q: %v", cont.info.Name, k, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
newCollector, err := collector.NewCollector(k, configFile)
|
||||||
|
if err != nil {
|
||||||
|
glog.Infof("failed to create collector for container %q, config %q: %v", cont.info.Name, k, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = cont.collectorManager.RegisterCollector(newCollector)
|
||||||
|
if err != nil {
|
||||||
|
glog.Infof("failed to register collector for container %q, config %q: %v", cont.info.Name, k, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -1136,8 +1151,12 @@ func (m *manager) DockerInfo() (DockerStatus, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return DockerStatus{}, err
|
return DockerStatus{}, err
|
||||||
}
|
}
|
||||||
|
versionInfo, err := m.GetVersionInfo()
|
||||||
|
if err != nil {
|
||||||
|
return DockerStatus{}, err
|
||||||
|
}
|
||||||
out := DockerStatus{}
|
out := DockerStatus{}
|
||||||
out.Version = m.versionInfo.DockerVersion
|
out.Version = versionInfo.DockerVersion
|
||||||
if val, ok := info["KernelVersion"]; ok {
|
if val, ok := info["KernelVersion"]; ok {
|
||||||
out.KernelVersion = val
|
out.KernelVersion = val
|
||||||
}
|
}
|
||||||
|
2
Godeps/_workspace/src/github.com/google/cadvisor/metrics/prometheus.go
generated
vendored
2
Godeps/_workspace/src/github.com/google/cadvisor/metrics/prometheus.go
generated
vendored
@ -392,7 +392,7 @@ func (c *PrometheusCollector) Collect(ch chan<- prometheus.Metric) {
|
|||||||
containers, err := c.infoProvider.SubcontainersInfo("/", &info.ContainerInfoRequest{NumStats: 1})
|
containers, err := c.infoProvider.SubcontainersInfo("/", &info.ContainerInfoRequest{NumStats: 1})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.errors.Set(1)
|
c.errors.Set(1)
|
||||||
glog.Warning("Couldn't get containers: %s", err)
|
glog.Warningf("Couldn't get containers: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, container := range containers {
|
for _, container := range containers {
|
||||||
|
29
Godeps/_workspace/src/github.com/google/cadvisor/pages/containers.go
generated
vendored
29
Godeps/_workspace/src/github.com/google/cadvisor/pages/containers.go
generated
vendored
@ -231,20 +231,21 @@ func serveContainersPage(m manager.Manager, w http.ResponseWriter, u *url.URL) e
|
|||||||
}
|
}
|
||||||
|
|
||||||
data := &pageData{
|
data := &pageData{
|
||||||
DisplayName: displayName,
|
DisplayName: displayName,
|
||||||
ContainerName: escapeContainerName(cont.Name),
|
ContainerName: escapeContainerName(cont.Name),
|
||||||
ParentContainers: parentContainers,
|
ParentContainers: parentContainers,
|
||||||
Subcontainers: subcontainerLinks,
|
Subcontainers: subcontainerLinks,
|
||||||
Spec: cont.Spec,
|
Spec: cont.Spec,
|
||||||
Stats: cont.Stats,
|
Stats: cont.Stats,
|
||||||
MachineInfo: machineInfo,
|
MachineInfo: machineInfo,
|
||||||
IsRoot: cont.Name == "/",
|
IsRoot: cont.Name == "/",
|
||||||
ResourcesAvailable: cont.Spec.HasCpu || cont.Spec.HasMemory || cont.Spec.HasNetwork || cont.Spec.HasFilesystem,
|
ResourcesAvailable: cont.Spec.HasCpu || cont.Spec.HasMemory || cont.Spec.HasNetwork || cont.Spec.HasFilesystem,
|
||||||
CpuAvailable: cont.Spec.HasCpu,
|
CpuAvailable: cont.Spec.HasCpu,
|
||||||
MemoryAvailable: cont.Spec.HasMemory,
|
MemoryAvailable: cont.Spec.HasMemory,
|
||||||
NetworkAvailable: cont.Spec.HasNetwork,
|
NetworkAvailable: cont.Spec.HasNetwork,
|
||||||
FsAvailable: cont.Spec.HasFilesystem,
|
FsAvailable: cont.Spec.HasFilesystem,
|
||||||
Root: rootDir,
|
CustomMetricsAvailable: cont.Spec.HasCustomMetrics,
|
||||||
|
Root: rootDir,
|
||||||
}
|
}
|
||||||
err = pageTemplate.Execute(w, data)
|
err = pageTemplate.Execute(w, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
10
Godeps/_workspace/src/github.com/google/cadvisor/pages/containers_html.go
generated
vendored
10
Godeps/_workspace/src/github.com/google/cadvisor/pages/containers_html.go
generated
vendored
@ -221,6 +221,16 @@ const containersHtmlTemplate = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
{{if .CustomMetricsAvailable}}
|
||||||
|
<div class="panel panel-primary">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title">Application Metrics</h3>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div id="custom-metrics-chart"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
25
Godeps/_workspace/src/github.com/google/cadvisor/pages/docker.go
generated
vendored
25
Godeps/_workspace/src/github.com/google/cadvisor/pages/docker.go
generated
vendored
@ -129,18 +129,19 @@ func serveDockerPage(m manager.Manager, w http.ResponseWriter, u *url.URL) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
data = &pageData{
|
data = &pageData{
|
||||||
DisplayName: displayName,
|
DisplayName: displayName,
|
||||||
ContainerName: escapeContainerName(cont.Name),
|
ContainerName: escapeContainerName(cont.Name),
|
||||||
ParentContainers: parentContainers,
|
ParentContainers: parentContainers,
|
||||||
Spec: cont.Spec,
|
Spec: cont.Spec,
|
||||||
Stats: cont.Stats,
|
Stats: cont.Stats,
|
||||||
MachineInfo: machineInfo,
|
MachineInfo: machineInfo,
|
||||||
ResourcesAvailable: cont.Spec.HasCpu || cont.Spec.HasMemory || cont.Spec.HasNetwork,
|
ResourcesAvailable: cont.Spec.HasCpu || cont.Spec.HasMemory || cont.Spec.HasNetwork,
|
||||||
CpuAvailable: cont.Spec.HasCpu,
|
CpuAvailable: cont.Spec.HasCpu,
|
||||||
MemoryAvailable: cont.Spec.HasMemory,
|
MemoryAvailable: cont.Spec.HasMemory,
|
||||||
NetworkAvailable: cont.Spec.HasNetwork,
|
NetworkAvailable: cont.Spec.HasNetwork,
|
||||||
FsAvailable: cont.Spec.HasFilesystem,
|
FsAvailable: cont.Spec.HasFilesystem,
|
||||||
Root: rootDir,
|
CustomMetricsAvailable: cont.Spec.HasCustomMetrics,
|
||||||
|
Root: rootDir,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
35
Godeps/_workspace/src/github.com/google/cadvisor/pages/pages.go
generated
vendored
35
Godeps/_workspace/src/github.com/google/cadvisor/pages/pages.go
generated
vendored
@ -44,23 +44,24 @@ type keyVal struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type pageData struct {
|
type pageData struct {
|
||||||
DisplayName string
|
DisplayName string
|
||||||
ContainerName string
|
ContainerName string
|
||||||
ParentContainers []link
|
ParentContainers []link
|
||||||
Subcontainers []link
|
Subcontainers []link
|
||||||
Spec info.ContainerSpec
|
Spec info.ContainerSpec
|
||||||
Stats []*info.ContainerStats
|
Stats []*info.ContainerStats
|
||||||
MachineInfo *info.MachineInfo
|
MachineInfo *info.MachineInfo
|
||||||
IsRoot bool
|
IsRoot bool
|
||||||
ResourcesAvailable bool
|
ResourcesAvailable bool
|
||||||
CpuAvailable bool
|
CpuAvailable bool
|
||||||
MemoryAvailable bool
|
MemoryAvailable bool
|
||||||
NetworkAvailable bool
|
NetworkAvailable bool
|
||||||
FsAvailable bool
|
FsAvailable bool
|
||||||
Root string
|
CustomMetricsAvailable bool
|
||||||
DockerStatus []keyVal
|
Root string
|
||||||
DockerDriverStatus []keyVal
|
DockerStatus []keyVal
|
||||||
DockerImages []manager.DockerImage
|
DockerDriverStatus []keyVal
|
||||||
|
DockerImages []manager.DockerImage
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
145
Godeps/_workspace/src/github.com/google/cadvisor/pages/static/containers_js.go
generated
vendored
145
Godeps/_workspace/src/github.com/google/cadvisor/pages/static/containers_js.go
generated
vendored
@ -645,6 +645,15 @@ function drawCharts(machineInfo, containerInfo) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Custom Metrics
|
||||||
|
if (containerInfo.spec.has_custom_metrics) {
|
||||||
|
steps.push(function() {
|
||||||
|
getCustomMetrics(window.cadvisor.rootDir, window.cadvisor.containerName, function(metricsInfo) {
|
||||||
|
drawCustomMetrics("custom-metrics-chart", containerInfo, metricsInfo)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
stepExecute(steps);
|
stepExecute(steps);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -696,12 +705,144 @@ function refreshStats() {
|
|||||||
}
|
}
|
||||||
if (containerInfo.spec.has_network) {
|
if (containerInfo.spec.has_network) {
|
||||||
startNetwork("network-selection", containerInfo);
|
startNetwork("network-selection", containerInfo);
|
||||||
|
}
|
||||||
|
if (containerInfo.spec.has_custom_metrics) {
|
||||||
|
startCustomMetrics("custom-metrics-chart", containerInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
drawCharts(machineInfo, containerInfo);
|
drawCharts(machineInfo, containerInfo);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addAllLabels(containerInfo, metricsInfo) {
|
||||||
|
if (metricsInfo.length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var metricSpec = containerInfo.spec.custom_metrics;
|
||||||
|
for (var containerName in metricsInfo) {
|
||||||
|
var container = metricsInfo[containerName];
|
||||||
|
for (i=0; i<metricSpec.length; i++) {
|
||||||
|
metricName = metricSpec[i].name;
|
||||||
|
metricLabelVal = container[metricName];
|
||||||
|
firstLabel = true;
|
||||||
|
for (var label in metricLabelVal) {
|
||||||
|
if (label == "") {
|
||||||
|
$('#button-'+metricName).hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#"+metricName+"_labels").append($("<li>")
|
||||||
|
.attr("role", "presentation")
|
||||||
|
.append($("<a>")
|
||||||
|
.attr("role", "menuitem")
|
||||||
|
.click(setLabel.bind(null, metricName, label))
|
||||||
|
.text(label)));
|
||||||
|
if (firstLabel) {
|
||||||
|
firstLabel = false;
|
||||||
|
setLabel(metricName, label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMetricIndex(metricName) {
|
||||||
|
for (i = 0; i<window.cadvisor.metricLabelPair.length; ++i) {
|
||||||
|
if (window.cadvisor.metricLabelPair[i][0] == metricName)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setLabel(metric, label) {
|
||||||
|
$("#"+metric+"-selection-text")
|
||||||
|
.empty()
|
||||||
|
.append($("<span>").text("Label: "))
|
||||||
|
.append($("<b>").text(label))
|
||||||
|
|
||||||
|
index = getMetricIndex(metric);
|
||||||
|
if (index == -1) {
|
||||||
|
window.cadvisor.metricLabelPair.push([metric, label]);
|
||||||
|
} else {
|
||||||
|
window.cadvisor.metricLabelPair[index][1] = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshStats();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSelectedLabel(metricName) {
|
||||||
|
index = getMetricIndex(metricName);
|
||||||
|
if (index == -1)
|
||||||
|
return "";
|
||||||
|
return window.cadvisor.metricLabelPair[index][1];
|
||||||
|
}
|
||||||
|
|
||||||
|
function startCustomMetrics(elementId, containerInfo) {
|
||||||
|
var metricSpec = containerInfo.spec.custom_metrics;
|
||||||
|
var metricStats = containerInfo.stats.custom_metrics;
|
||||||
|
var el=$("<div>");
|
||||||
|
|
||||||
|
if (metricSpec.length < window.cadvisor.maxCustomMetrics)
|
||||||
|
window.cadvisor.maxCustomMetrics = metricSpec.length
|
||||||
|
for (i = 0; i<window.cadvisor.maxCustomMetrics; i++) {
|
||||||
|
metricName = metricSpec[i].name;
|
||||||
|
var divText = "<div class='dropdown'> <button class='btn btn-default dropdown-toggle' type='button' id='button-"+metricName;
|
||||||
|
divText += "' data-toggle='dropdown' aria-haspopup='true' aria-expanded='false'>";
|
||||||
|
divText += "<span id='"+metricName+"-selection-text'></span> <span class='caret'></span> </button>";
|
||||||
|
divText += "<ul id='"+metricName+"_labels' class='dropdown-menu' role='menu' aria-labelledby='button-"+metricName+ "'> </ul> </div>";
|
||||||
|
divText += "<div id='"+elementId+"-"+metricName+"'> </div>";
|
||||||
|
el.append($(divText));
|
||||||
|
}
|
||||||
|
el.append($("</div>"));
|
||||||
|
|
||||||
|
$("#"+elementId).append(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCustomMetrics(rootDir, containerName, callback) {
|
||||||
|
$.getJSON(rootDir + "api/v2.0/appmetrics/" + containerName)
|
||||||
|
.done(function(data) {
|
||||||
|
callback(data);
|
||||||
|
})
|
||||||
|
.fail(function(jqhxr, textStatus, error) {
|
||||||
|
callback([]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawCustomMetrics(elementId, containerInfo, metricsInfo) {
|
||||||
|
if(metricsInfo.length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var metricSpec = containerInfo.spec.custom_metrics;
|
||||||
|
for (var containerName in metricsInfo) {
|
||||||
|
var container = metricsInfo[containerName];
|
||||||
|
for (i=0; i<window.cadvisor.maxCustomMetrics; i++) {
|
||||||
|
metricName = metricSpec[i].name;
|
||||||
|
metricUnits = metricSpec[i].units;
|
||||||
|
var titles = ["Time", metricName];
|
||||||
|
metricLabelVal = container[metricName];
|
||||||
|
if (window.cadvisor.firstCustomCollection) {
|
||||||
|
window.cadvisor.firstCustomCollection = false;
|
||||||
|
addAllLabels(containerInfo, metricsInfo);
|
||||||
|
}
|
||||||
|
var data = [];
|
||||||
|
selectedLabel = getSelectedLabel(metricName);
|
||||||
|
metricVal = metricLabelVal[selectedLabel];
|
||||||
|
for (var index in metricVal) {
|
||||||
|
metric = metricVal[index];
|
||||||
|
var elements = [];
|
||||||
|
for (var attribute in metric) {
|
||||||
|
value = metric[attribute];
|
||||||
|
elements.push(value);
|
||||||
|
}
|
||||||
|
if (elements.length<2) {
|
||||||
|
elements.push(0);
|
||||||
|
}
|
||||||
|
data.push(elements);
|
||||||
|
}
|
||||||
|
drawLineChart(titles, data, elementId+"-"+metricName, metricUnits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Executed when the page finishes loading.
|
// Executed when the page finishes loading.
|
||||||
function startPage(containerName, hasCpu, hasMemory, rootDir, isRoot) {
|
function startPage(containerName, hasCpu, hasMemory, rootDir, isRoot) {
|
||||||
// Don't fetch data if we don't have any resource.
|
// Don't fetch data if we don't have any resource.
|
||||||
@ -715,6 +856,10 @@ function startPage(containerName, hasCpu, hasMemory, rootDir, isRoot) {
|
|||||||
window.cadvisor.rootDir = rootDir;
|
window.cadvisor.rootDir = rootDir;
|
||||||
window.cadvisor.containerName = containerName;
|
window.cadvisor.containerName = containerName;
|
||||||
|
|
||||||
|
window.cadvisor.firstCustomCollection = true;
|
||||||
|
window.cadvisor.metricLabelPair = [];
|
||||||
|
window.cadvisor.maxCustomMetrics = 10;
|
||||||
|
|
||||||
// Draw process information at start and refresh every 60s.
|
// Draw process information at start and refresh every 60s.
|
||||||
getProcessInfo(rootDir, containerName, function(processInfo) {
|
getProcessInfo(rootDir, containerName, function(processInfo) {
|
||||||
drawProcesses(isRoot, rootDir, processInfo)
|
drawProcesses(isRoot, rootDir, processInfo)
|
||||||
|
116
Godeps/_workspace/src/github.com/google/cadvisor/storage/stdout/stdout.go
generated
vendored
Normal file
116
Godeps/_workspace/src/github.com/google/cadvisor/storage/stdout/stdout.go
generated
vendored
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
// 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 stdout
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
info "github.com/google/cadvisor/info/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
type stdoutStorage struct {
|
||||||
|
Namespace string
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
colCpuCumulativeUsage = "cpu_cumulative_usage"
|
||||||
|
// Memory Usage
|
||||||
|
colMemoryUsage = "memory_usage"
|
||||||
|
// Working set size
|
||||||
|
colMemoryWorkingSet = "memory_working_set"
|
||||||
|
// Cumulative count of bytes received.
|
||||||
|
colRxBytes = "rx_bytes"
|
||||||
|
// Cumulative count of receive errors encountered.
|
||||||
|
colRxErrors = "rx_errors"
|
||||||
|
// Cumulative count of bytes transmitted.
|
||||||
|
colTxBytes = "tx_bytes"
|
||||||
|
// Cumulative count of transmit errors encountered.
|
||||||
|
colTxErrors = "tx_errors"
|
||||||
|
// Filesystem summary
|
||||||
|
colFsSummary = "fs_summary"
|
||||||
|
// Filesystem limit.
|
||||||
|
colFsLimit = "fs_limit"
|
||||||
|
// Filesystem usage.
|
||||||
|
colFsUsage = "fs_usage"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (driver *stdoutStorage) containerStatsToValues(stats *info.ContainerStats) (series map[string]uint64) {
|
||||||
|
series = make(map[string]uint64)
|
||||||
|
|
||||||
|
// Cumulative Cpu Usage
|
||||||
|
series[colCpuCumulativeUsage] = stats.Cpu.Usage.Total
|
||||||
|
|
||||||
|
// Memory Usage
|
||||||
|
series[colMemoryUsage] = stats.Memory.Usage
|
||||||
|
|
||||||
|
// Working set size
|
||||||
|
series[colMemoryWorkingSet] = stats.Memory.WorkingSet
|
||||||
|
|
||||||
|
// Network stats.
|
||||||
|
series[colRxBytes] = stats.Network.RxBytes
|
||||||
|
series[colRxErrors] = stats.Network.RxErrors
|
||||||
|
series[colTxBytes] = stats.Network.TxBytes
|
||||||
|
series[colTxErrors] = stats.Network.TxErrors
|
||||||
|
|
||||||
|
return series
|
||||||
|
}
|
||||||
|
|
||||||
|
func (driver *stdoutStorage) containerFsStatsToValues(series *map[string]uint64, stats *info.ContainerStats) {
|
||||||
|
for _, fsStat := range stats.Filesystem {
|
||||||
|
// Summary stats.
|
||||||
|
(*series)[colFsSummary+"."+colFsLimit] += fsStat.Limit
|
||||||
|
(*series)[colFsSummary+"."+colFsUsage] += fsStat.Usage
|
||||||
|
|
||||||
|
// Per device stats.
|
||||||
|
(*series)[fsStat.Device+"."+colFsLimit] = fsStat.Limit
|
||||||
|
(*series)[fsStat.Device+"."+colFsUsage] = fsStat.Usage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (driver *stdoutStorage) AddStats(ref info.ContainerReference, stats *info.ContainerStats) error {
|
||||||
|
if stats == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
containerName := ref.Name
|
||||||
|
if len(ref.Aliases) > 0 {
|
||||||
|
containerName = ref.Aliases[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
buffer.WriteString(fmt.Sprintf("cName=%s host=%s", containerName, driver.Namespace))
|
||||||
|
|
||||||
|
series := driver.containerStatsToValues(stats)
|
||||||
|
driver.containerFsStatsToValues(&series, stats)
|
||||||
|
for key, value := range series {
|
||||||
|
buffer.WriteString(fmt.Sprintf(" %s=%v", key, value))
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := fmt.Println(buffer.String())
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (driver *stdoutStorage) Close() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(namespace string) (*stdoutStorage, error) {
|
||||||
|
stdoutStorage := &stdoutStorage{
|
||||||
|
Namespace: namespace,
|
||||||
|
}
|
||||||
|
return stdoutStorage, nil
|
||||||
|
}
|
2
Godeps/_workspace/src/github.com/google/cadvisor/utils/cloudinfo/gce.go
generated
vendored
2
Godeps/_workspace/src/github.com/google/cadvisor/utils/cloudinfo/gce.go
generated
vendored
@ -17,8 +17,8 @@ package cloudinfo
|
|||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/gcloud-golang/compute/metadata"
|
|
||||||
info "github.com/google/cadvisor/info/v1"
|
info "github.com/google/cadvisor/info/v1"
|
||||||
|
"google.golang.org/cloud/compute/metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
func onGCE() bool {
|
func onGCE() bool {
|
||||||
|
Loading…
Reference in New Issue
Block a user