diff --git a/collector/collector_manager.go b/collector/collector_manager.go index 0641d199..a3df12cc 100644 --- a/collector/collector_manager.go +++ b/collector/collector_manager.go @@ -18,6 +18,8 @@ import ( "fmt" "strings" "time" + + "github.com/google/cadvisor/info/v2" ) type collectorManager struct { @@ -46,17 +48,19 @@ func (cm *collectorManager) RegisterCollector(collector Collector) error { return nil } -func (cm *collectorManager) Collect() (time.Time, error) { +func (cm *collectorManager) Collect() (time.Time, []v2.Metric, error) { var errors []error // Collect from all collectors that are ready. var next time.Time + var metrics []v2.Metric for _, c := range cm.collectors { if c.nextCollectionTime.Before(time.Now()) { - nextCollection, err := c.collector.Collect() + nextCollection, newMetrics, err := c.collector.Collect() if err != nil { errors = append(errors, err) } + metrics = append(metrics, newMetrics...) c.nextCollectionTime = nextCollection } @@ -66,7 +70,7 @@ func (cm *collectorManager) Collect() (time.Time, error) { } } - return next, compileErrors(errors) + return next, metrics, compileErrors(errors) } // Make an error slice into a single error. diff --git a/collector/collector_manager_test.go b/collector/collector_manager_test.go index 85d6bbc0..49877032 100644 --- a/collector/collector_manager_test.go +++ b/collector/collector_manager_test.go @@ -18,6 +18,7 @@ import ( "testing" "time" + "github.com/google/cadvisor/info/v2" "github.com/stretchr/testify/assert" ) @@ -27,9 +28,9 @@ type fakeCollector struct { collectedFrom int } -func (fc *fakeCollector) Collect() (time.Time, error) { +func (fc *fakeCollector) Collect() (time.Time, []v2.Metric, error) { fc.collectedFrom++ - return fc.nextCollectionTime, fc.err + return fc.nextCollectionTime, []v2.Metric{}, fc.err } func (fc *fakeCollector) Name() string { @@ -53,7 +54,7 @@ func TestCollect(t *testing.T) { assert.NoError(cm.RegisterCollector(f2)) // First collection, everyone gets collected from. - nextTime, err := cm.Collect() + nextTime, _, err := cm.Collect() assert.Equal(firstTime, nextTime) assert.NoError(err) assert.Equal(1, f1.collectedFrom) @@ -62,7 +63,7 @@ func TestCollect(t *testing.T) { f1.nextCollectionTime = time.Now().Add(2 * time.Hour) // Second collection, only the one that is ready gets collected from. - nextTime, err = cm.Collect() + nextTime, _, err = cm.Collect() assert.Equal(secondTime, nextTime) assert.NoError(err) assert.Equal(2, f1.collectedFrom) diff --git a/collector/fakes.go b/collector/fakes.go index d36f1136..388f3fc0 100644 --- a/collector/fakes.go +++ b/collector/fakes.go @@ -16,6 +16,8 @@ package collector import ( "time" + + "github.com/google/cadvisor/info/v2" ) type FakeCollectorManager struct { @@ -25,7 +27,7 @@ func (fkm *FakeCollectorManager) RegisterCollector(collector Collector) error { return nil } -func (fkm *FakeCollectorManager) Collect() (time.Time, error) { +func (fkm *FakeCollectorManager) Collect() (time.Time, []v2.Metric, error) { var zero time.Time - return zero, nil + return zero, []v2.Metric{}, nil } diff --git a/collector/types.go b/collector/types.go index 4967a6ce..8bd29d06 100644 --- a/collector/types.go +++ b/collector/types.go @@ -15,6 +15,7 @@ package collector import ( + "github.com/google/cadvisor/info/v2" "time" ) @@ -26,7 +27,7 @@ type Collector interface { // Returns the next time this collector should be collected from. // Next collection time is always returned, even when an error occurs. // A collection time of zero means no more collection. - Collect() (time.Time, error) + Collect() (time.Time, []v2.Metric, error) // Name of this collector. Name() string @@ -41,5 +42,5 @@ type CollectorManager interface { // at which a collector will be ready to collect from. // Next collection time is always returned, even when an error occurs. // A collection time of zero means no more collection. - Collect() (time.Time, error) + Collect() (time.Time, []v2.Metric, error) } diff --git a/info/v2/metric.go b/info/v2/metric.go new file mode 100644 index 00000000..1057980c --- /dev/null +++ b/info/v2/metric.go @@ -0,0 +1,69 @@ +// 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 v2 + +import ( + "time" +) + +// Type of metric being exported. +type MetricType string + +const ( + // Instantaneous value. May increase or decrease. + MetricGauge MetricType = "gauge" + + // A counter-like value that is only expected to increase. + MetricCumulative = "cumulative" + + // Rate over a time period. + MetricDelta = "delta" +) + +// An exported metric. +type Metric struct { + // The name of the metric. + Name string `json:"name"` + + // Type of the metric. + Type MetricType `json:"type"` + + // Metadata associated with this metric. + Labels map[string]string + + // Value of the metric. Only one of these values will be + // available according to the output type of the metric. + // If no values are available, there are no data points. + IntPoints []IntPoint `json:"int_points,omitempty"` + FloatPoints []FloatPoint `json:"float_points,omitempty"` +} + +// An integer metric data point. +type IntPoint struct { + // Time at which the metric was queried + Timestamp time.Time `json:"timestamp"` + + // The value of the metric at this point. + Value int64 `json:"value"` +} + +// A float metric data point. +type FloatPoint struct { + // Time at which the metric was queried + Timestamp time.Time `json:"timestamp"` + + // The value of the metric at this point. + Value float64 `json:"value"` +} diff --git a/manager/container.go b/manager/container.go index f59a95ce..b4bd88be 100644 --- a/manager/container.go +++ b/manager/container.go @@ -232,8 +232,9 @@ func (c *containerData) housekeeping() { } } + // TODO(vmarmol): Export metrics. // Run custom collectors. - nextCollectionTime, err := c.collectorManager.Collect() + nextCollectionTime, _, err := c.collectorManager.Collect() if err != nil && c.allowErrorLogging() { glog.Warningf("[%s] Collection failed: %v", c.info.Name, err) }