// freeContainerMetrics returns a metric timeseries for a metric of the Container entity. // freeContainerMetrics addresses only free containers, by using the node-name/container-name path. func (a *Api) freeContainerMetrics(request *restful.Request, response *restful.Response) { a.processMetricRequest( core.NodeContainerKey(request.PathParameter("node-name"), request.PathParameter("container-name"), ), request, response) }
func TestDecodeSummaryMetrics(t *testing.T) { ms := testingSummaryMetricsSource() summary := stats.Summary{ Node: stats.NodeStats{ NodeName: nodeInfo.NodeName, StartTime: unversioned.NewTime(startTime), CPU: genTestSummaryCPU(seedNode), Memory: genTestSummaryMemory(seedNode), Network: genTestSummaryNetwork(seedNode), SystemContainers: []stats.ContainerStats{ genTestSummaryContainer(stats.SystemContainerKubelet, seedKubelet), genTestSummaryContainer(stats.SystemContainerRuntime, seedRuntime), genTestSummaryContainer(stats.SystemContainerMisc, seedMisc), }, Fs: genTestSummaryFsStats(seedNode), }, Pods: []stats.PodStats{{ PodRef: stats.PodReference{ Name: pName0, Namespace: namespace0, }, StartTime: unversioned.NewTime(startTime), Network: genTestSummaryNetwork(seedPod0), Containers: []stats.ContainerStats{ genTestSummaryContainer(cName00, seedPod0Container0), genTestSummaryContainer(cName01, seedPod0Container1), }, }, { PodRef: stats.PodReference{ Name: pName1, Namespace: namespace0, }, StartTime: unversioned.NewTime(startTime), Network: genTestSummaryNetwork(seedPod1), Containers: []stats.ContainerStats{ genTestSummaryContainer(cName10, seedPod1Container), }, VolumeStats: []stats.VolumeStats{{ Name: "A", FsStats: *genTestSummaryFsStats(seedPod1), }, { Name: "B", FsStats: *genTestSummaryFsStats(seedPod1), }}, }, { PodRef: stats.PodReference{ Name: pName2, Namespace: namespace1, }, StartTime: unversioned.NewTime(startTime), Network: genTestSummaryNetwork(seedPod2), Containers: []stats.ContainerStats{ genTestSummaryContainer(cName20, seedPod2Container), }, }}, } containerFs := []string{"/", "logs"} expectations := []struct { key string setType string seed int64 cpu bool memory bool network bool fs []string }{{ key: core.NodeKey(nodeInfo.NodeName), setType: core.MetricSetTypeNode, seed: seedNode, cpu: true, memory: true, network: true, fs: []string{"/"}, }, { key: core.NodeContainerKey(nodeInfo.NodeName, "kubelet"), setType: core.MetricSetTypeSystemContainer, seed: seedKubelet, cpu: true, memory: true, }, { key: core.NodeContainerKey(nodeInfo.NodeName, "docker-daemon"), setType: core.MetricSetTypeSystemContainer, seed: seedRuntime, cpu: true, memory: true, }, { key: core.NodeContainerKey(nodeInfo.NodeName, "system"), setType: core.MetricSetTypeSystemContainer, seed: seedMisc, cpu: true, memory: true, }, { key: core.PodKey(namespace0, pName0), setType: core.MetricSetTypePod, seed: seedPod0, network: true, }, { key: core.PodKey(namespace0, pName1), setType: core.MetricSetTypePod, seed: seedPod1, network: true, fs: []string{"Volume:A", "Volume:B"}, }, { key: core.PodKey(namespace1, pName2), setType: core.MetricSetTypePod, seed: seedPod2, network: true, }, { key: core.PodContainerKey(namespace0, pName0, cName00), setType: core.MetricSetTypePodContainer, seed: seedPod0Container0, cpu: true, memory: true, fs: containerFs, }, { key: core.PodContainerKey(namespace0, pName0, cName01), setType: core.MetricSetTypePodContainer, seed: seedPod0Container1, cpu: true, memory: true, fs: containerFs, }, { key: core.PodContainerKey(namespace0, pName1, cName10), setType: core.MetricSetTypePodContainer, seed: seedPod1Container, cpu: true, memory: true, fs: containerFs, }, { key: core.PodContainerKey(namespace1, pName2, cName20), setType: core.MetricSetTypePodContainer, seed: seedPod2Container, cpu: true, memory: true, fs: containerFs, }} metrics := ms.decodeSummary(&summary) for _, e := range expectations { m, ok := metrics[e.key] if !assert.True(t, ok, "missing metric %q", e.key) { continue } assert.Equal(t, m.Labels[core.LabelMetricSetType.Key], e.setType, e.key) assert.Equal(t, m.CreateTime, startTime, e.key) assert.Equal(t, m.ScrapeTime, scrapeTime, e.key) if e.cpu { checkIntMetric(t, m, e.key, core.MetricCpuUsage, e.seed+offsetCPUUsageCoreSeconds) } if e.memory { checkIntMetric(t, m, e.key, core.MetricMemoryUsage, e.seed+offsetMemUsageBytes) checkIntMetric(t, m, e.key, core.MetricMemoryWorkingSet, e.seed+offsetMemWorkingSetBytes) checkIntMetric(t, m, e.key, core.MetricMemoryPageFaults, e.seed+offsetMemPageFaults) checkIntMetric(t, m, e.key, core.MetricMemoryMajorPageFaults, e.seed+offsetMemMajorPageFaults) } if e.network { checkIntMetric(t, m, e.key, core.MetricNetworkRx, e.seed+offsetNetRxBytes) checkIntMetric(t, m, e.key, core.MetricNetworkRxErrors, e.seed+offsetNetRxErrors) checkIntMetric(t, m, e.key, core.MetricNetworkTx, e.seed+offsetNetTxBytes) checkIntMetric(t, m, e.key, core.MetricNetworkTxErrors, e.seed+offsetNetTxErrors) } for _, label := range e.fs { checkFsMetric(t, m, e.key, label, core.MetricFilesystemAvailable, e.seed+offsetFsAvailable) checkFsMetric(t, m, e.key, label, core.MetricFilesystemLimit, e.seed+offsetFsCapacity) checkFsMetric(t, m, e.key, label, core.MetricFilesystemUsage, e.seed+offsetFsUsed) } delete(metrics, e.key) } for k, v := range metrics { assert.Fail(t, "unexpected metric", "%q: %+v", k, v) } }