Skip to content
This repository was archived by the owner on Dec 1, 2018. It is now read-only.

Commit 6b59690

Browse files
committed
Add pod-level metrics into heapster
This commit adds pod-level cpu, memory and ephemeralstorage metrics from summary API to heaspter. Before, some pod-level metrics are aggregated from containers. After getting those metrics directly from pod summary API, it no longer needs to aggregate from containers.
1 parent ba4ca21 commit 6b59690

File tree

6 files changed

+114
-30
lines changed

6 files changed

+114
-30
lines changed

Godeps/Godeps.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

metrics/core/metrics.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const (
2929
var StandardMetrics = []Metric{
3030
MetricUptime,
3131
MetricCpuUsage,
32+
MetricEphemeralStorageUsage,
3233
MetricMemoryUsage,
3334
MetricMemoryRSS,
3435
MetricMemoryCache,
@@ -220,6 +221,15 @@ var MetricCpuUsage = Metric{
220221
},
221222
}
222223

224+
var MetricEphemeralStorageUsage = Metric{
225+
MetricDescriptor: MetricDescriptor{
226+
Name: "ephemeralstorage/usage",
227+
Description: "Ephemeral storage usage",
228+
Type: MetricGauge,
229+
ValueType: ValueInt64,
230+
Units: UnitsBytes,
231+
},
232+
}
223233
var MetricMemoryUsage = Metric{
224234
MetricDescriptor: MetricDescriptor{
225235
Name: "memory/usage",

metrics/processors/pod_aggregator.go

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ func (this *PodAggregator) Name() string {
4242
func (this *PodAggregator) Process(batch *core.DataBatch) (*core.DataBatch, error) {
4343
newPods := make(map[string]*core.MetricSet)
4444

45+
// If pod already has pod-level metrics, it no longer needs to aggregates its container's metrics.
46+
requireAggregate := make(map[string]bool)
4547
for key, metricSet := range batch.MetricSets {
4648
if metricSetType, found := metricSet.Labels[core.LabelMetricSetType.Key]; !found || metricSetType != core.MetricSetTypePodContainer {
4749
continue
@@ -72,23 +74,27 @@ func (this *PodAggregator) Process(batch *core.DataBatch) (*core.DataBatch, erro
7274
}
7375

7476
aggregatedValue, found := pod.MetricValues[metricName]
75-
if found {
76-
if aggregatedValue.ValueType != metricValue.ValueType {
77-
glog.Errorf("PodAggregator: inconsistent type in %s", metricName)
78-
continue
79-
}
80-
81-
switch aggregatedValue.ValueType {
82-
case core.ValueInt64:
83-
aggregatedValue.IntValue += metricValue.IntValue
84-
case core.ValueFloat:
85-
aggregatedValue.FloatValue += metricValue.FloatValue
86-
default:
87-
return nil, fmt.Errorf("PodAggregator: type not supported in %s", metricName)
88-
}
89-
} else {
77+
if !found {
78+
requireAggregate[podKey+metricName] = true
9079
aggregatedValue = metricValue
80+
} else {
81+
if requireAggregate[podKey+metricName] {
82+
if aggregatedValue.ValueType != metricValue.ValueType {
83+
glog.Errorf("PodAggregator: inconsistent type in %s", metricName)
84+
continue
85+
}
86+
87+
switch aggregatedValue.ValueType {
88+
case core.ValueInt64:
89+
aggregatedValue.IntValue += metricValue.IntValue
90+
case core.ValueFloat:
91+
aggregatedValue.FloatValue += metricValue.FloatValue
92+
default:
93+
return nil, fmt.Errorf("PodAggregator: type not supported in %s", metricName)
94+
}
95+
}
9196
}
97+
9298
pod.MetricValues[metricName] = aggregatedValue
9399
}
94100
}

metrics/processors/pod_aggregator_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,41 @@ func TestPodAggregator(t *testing.T) {
6666
},
6767
},
6868
},
69+
70+
core.PodKey("ns1", "pod2"): {
71+
Labels: map[string]string{
72+
core.LabelMetricSetType.Key: core.MetricSetTypePod,
73+
core.LabelPodName.Key: "pod2",
74+
core.LabelNamespaceName.Key: "ns1",
75+
},
76+
MetricValues: map[string]core.MetricValue{
77+
"m1": {
78+
ValueType: core.ValueInt64,
79+
MetricType: core.MetricGauge,
80+
IntValue: 100,
81+
},
82+
},
83+
},
84+
85+
core.PodContainerKey("ns1", "pod2", "c1"): {
86+
Labels: map[string]string{
87+
core.LabelMetricSetType.Key: core.MetricSetTypePodContainer,
88+
core.LabelPodName.Key: "pod2",
89+
core.LabelNamespaceName.Key: "ns1",
90+
},
91+
MetricValues: map[string]core.MetricValue{
92+
"m1": {
93+
ValueType: core.ValueInt64,
94+
MetricType: core.MetricGauge,
95+
IntValue: 10,
96+
},
97+
"m2": {
98+
ValueType: core.ValueInt64,
99+
MetricType: core.MetricGauge,
100+
IntValue: 20,
101+
},
102+
},
103+
},
69104
},
70105
}
71106
processor := PodAggregator{}
@@ -93,4 +128,16 @@ func TestPodAggregator(t *testing.T) {
93128
labelNsName, found := pod.Labels[core.LabelNamespaceName.Key]
94129
assert.True(t, found)
95130
assert.Equal(t, "ns1", labelNsName)
131+
132+
pod, found = result.MetricSets[core.PodKey("ns1", "pod2")]
133+
assert.True(t, found)
134+
135+
m1, found = pod.MetricValues["m1"]
136+
assert.True(t, found)
137+
assert.Equal(t, int64(100), m1.IntValue)
138+
139+
m2, found = pod.MetricValues["m2"]
140+
assert.True(t, found)
141+
assert.Equal(t, int64(20), m2.IntValue)
142+
96143
}

metrics/sources/summary/summary.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,9 @@ func (this *summaryMetricsSource) decodePodStats(metrics map[string]*MetricSet,
188188

189189
this.decodeUptime(podMetrics, pod.StartTime.Time)
190190
this.decodeNetworkStats(podMetrics, pod.Network)
191+
this.decodeCPUStats(podMetrics, pod.CPU)
192+
this.decodeMemoryStats(podMetrics, pod.Memory)
193+
this.decodeEphemeralStorageStats(podMetrics, pod.EphemeralStorage)
191194
for _, vol := range pod.VolumeStats {
192195
this.decodeFsStats(podMetrics, VolumeResourcePrefix+vol.Name, &vol.FsStats)
193196
}
@@ -255,6 +258,14 @@ func (this *summaryMetricsSource) decodeCPUStats(metrics *MetricSet, cpu *stats.
255258
this.addIntMetric(metrics, &MetricCpuUsage, cpu.UsageCoreNanoSeconds)
256259
}
257260

261+
func (this *summaryMetricsSource) decodeEphemeralStorageStats(metrics *MetricSet, storage *stats.FsStats) {
262+
if storage == nil {
263+
glog.V(9).Infof("missing storage usage metric!")
264+
return
265+
}
266+
this.addIntMetric(metrics, &MetricEphemeralStorageUsage, storage.UsedBytes)
267+
}
268+
258269
func (this *summaryMetricsSource) decodeMemoryStats(metrics *MetricSet, memory *stats.MemoryStats) {
259270
if memory == nil {
260271
glog.V(9).Infof("missing memory metrics!")

metrics/sources/summary/summary_test.go

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,11 @@ func TestDecodeSummaryMetrics(t *testing.T) {
153153
Name: pName0,
154154
Namespace: namespace0,
155155
},
156-
StartTime: metav1.NewTime(startTime),
157-
Network: genTestSummaryNetwork(seedPod0),
156+
StartTime: metav1.NewTime(startTime),
157+
Network: genTestSummaryNetwork(seedPod0),
158+
EphemeralStorage: genTestSummaryFsStats(seedPod0),
159+
CPU: genTestSummaryCPU(seedPod0),
160+
Memory: genTestSummaryMemory(seedPod0),
158161
Containers: []stats.ContainerStats{
159162
genTestSummaryContainer(cName00, seedPod0Container0),
160163
genTestSummaryContainer(cName01, seedPod0Container1),
@@ -235,14 +238,15 @@ func TestDecodeSummaryMetrics(t *testing.T) {
235238

236239
containerFs := []string{"/", "logs"}
237240
expectations := []struct {
238-
key string
239-
setType string
240-
seed int64
241-
cpu bool
242-
memory bool
243-
network bool
244-
accelerators bool
245-
fs []string
241+
key string
242+
setType string
243+
seed int64
244+
cpu bool
245+
memory bool
246+
network bool
247+
accelerators bool
248+
ephemeralstorage bool
249+
fs []string
246250
}{{
247251
key: core.NodeKey(nodeInfo.NodeName),
248252
setType: core.MetricSetTypeNode,
@@ -270,10 +274,13 @@ func TestDecodeSummaryMetrics(t *testing.T) {
270274
cpu: true,
271275
memory: true,
272276
}, {
273-
key: core.PodKey(namespace0, pName0),
274-
setType: core.MetricSetTypePod,
275-
seed: seedPod0,
276-
network: true,
277+
key: core.PodKey(namespace0, pName0),
278+
setType: core.MetricSetTypePod,
279+
seed: seedPod0,
280+
network: true,
281+
cpu: true,
282+
memory: true,
283+
ephemeralstorage: true,
277284
}, {
278285
key: core.PodKey(namespace0, pName1),
279286
setType: core.MetricSetTypePod,
@@ -382,6 +389,9 @@ func TestDecodeSummaryMetrics(t *testing.T) {
382389
checkAcceleratorMetric(t, m, e.key, core.MetricAcceleratorMemoryUsed, e.seed+offsetAcceleratorMemoryUsed)
383390
checkAcceleratorMetric(t, m, e.key, core.MetricAcceleratorDutyCycle, e.seed+offsetAcceleratorDutyCycle)
384391
}
392+
if e.ephemeralstorage {
393+
checkIntMetric(t, m, e.key, core.MetricEphemeralStorageUsage, e.seed+offsetFsUsed)
394+
}
385395
for _, label := range e.fs {
386396
checkFsMetric(t, m, e.key, label, core.MetricFilesystemAvailable, e.seed+offsetFsAvailable)
387397
checkFsMetric(t, m, e.key, label, core.MetricFilesystemLimit, e.seed+offsetFsCapacity)

0 commit comments

Comments
 (0)