If k8s objects only have one container, show that container's metrics on them (#1473)

This commit is contained in:
Paul Bellamy
2016-06-04 08:03:51 +01:00
committed by Tom Wilkie
parent 1bd8eb218d
commit 85aee27ef6
4 changed files with 235 additions and 20 deletions

View File

@@ -35,6 +35,8 @@ var (
Created: {ID: Created, Label: "Created", From: report.FromLatest, Priority: 6},
}
PodMetricTemplates = docker.ContainerMetricTemplates
ServiceMetadataTemplates = report.MetadataTemplates{
ID: {ID: ID, Label: "ID", From: report.FromLatest, Priority: 1},
Namespace: {ID: Namespace, Label: "Namespace", From: report.FromLatest, Priority: 2},
@@ -44,6 +46,8 @@ var (
report.Pod: {ID: report.Pod, Label: "# Pods", From: report.FromCounters, Datatype: "number", Priority: 6},
}
ServiceMetricTemplates = PodMetricTemplates
DeploymentMetadataTemplates = report.MetadataTemplates{
ID: {ID: ID, Label: "ID", From: report.FromLatest, Priority: 1},
Namespace: {ID: Namespace, Label: "Namespace", From: report.FromLatest, Priority: 2},
@@ -54,6 +58,8 @@ var (
Strategy: {ID: Strategy, Label: "Strategy", From: report.FromLatest, Priority: 7},
}
DeploymentMetricTemplates = ReplicaSetMetricTemplates
ReplicaSetMetadataTemplates = report.MetadataTemplates{
ID: {ID: ID, Label: "ID", From: report.FromLatest, Priority: 1},
Namespace: {ID: Namespace, Label: "Namespace", From: report.FromLatest, Priority: 2},
@@ -63,6 +69,8 @@ var (
report.Pod: {ID: report.Pod, Label: "# Pods", From: report.FromCounters, Datatype: "number", Priority: 6},
}
ReplicaSetMetricTemplates = PodMetricTemplates
TableTemplates = report.TableTemplates{
LabelPrefix: {ID: LabelPrefix, Label: "Kubernetes Labels", Prefix: LabelPrefix},
}
@@ -211,6 +219,7 @@ func (r *Reporter) serviceTopology() (report.Topology, []Service, error) {
var (
result = report.MakeTopology().
WithMetadataTemplates(ServiceMetadataTemplates).
WithMetricTemplates(ServiceMetricTemplates).
WithTableTemplates(TableTemplates)
services = []Service{}
)
@@ -245,6 +254,7 @@ func (r *Reporter) deploymentTopology(probeID string) (report.Topology, []Deploy
var (
result = report.MakeTopology().
WithMetadataTemplates(DeploymentMetadataTemplates).
WithMetricTemplates(DeploymentMetricTemplates).
WithTableTemplates(TableTemplates)
deployments = []Deployment{}
)
@@ -262,6 +272,7 @@ func (r *Reporter) replicaSetTopology(probeID string, deployments []Deployment)
var (
result = report.MakeTopology().
WithMetadataTemplates(ReplicaSetMetadataTemplates).
WithMetricTemplates(ReplicaSetMetricTemplates).
WithTableTemplates(TableTemplates)
replicaSets = []ReplicaSet{}
selectors = []func(labelledChild){}
@@ -338,6 +349,7 @@ func (r *Reporter) podTopology(services []Service, replicaSets []ReplicaSet) (re
var (
pods = report.MakeTopology().
WithMetadataTemplates(PodMetadataTemplates).
WithMetricTemplates(PodMetricTemplates).
WithTableTemplates(TableTemplates)
selectors = []func(labelledChild){}
)

24
render/metrics.go Normal file
View File

@@ -0,0 +1,24 @@
package render
import (
"github.com/weaveworks/scope/report"
)
// PropagateSingleMetrics puts metrics from one of the children onto the parent
// iff there is only one child of that type.
func PropagateSingleMetrics(topology string) MapFunc {
return func(n report.Node, _ report.Networks) report.Nodes {
var found []report.Node
n.Children.ForEach(func(child report.Node) {
if child.Topology == topology {
if _, ok := child.Latest.Lookup(report.DoesNotMakeConnections); !ok {
found = append(found, child)
}
}
})
if len(found) == 1 {
n = n.WithMetrics(found[0].Metrics)
}
return report.Nodes{n.ID: n}
}
}

167
render/metrics_test.go Normal file
View File

@@ -0,0 +1,167 @@
package render_test
import (
"testing"
"time"
"github.com/weaveworks/scope/render"
"github.com/weaveworks/scope/report"
"github.com/weaveworks/scope/test"
"github.com/weaveworks/scope/test/reflect"
)
func TestPropagateSingleMetrics(t *testing.T) {
now := time.Now()
for _, c := range []struct {
name string
input report.Node
topology string
output report.Nodes
}{
{
name: "empty",
input: report.MakeNode("empty"),
topology: "",
output: report.Nodes{"empty": report.MakeNode("empty")},
},
{
name: "one child",
input: report.MakeNode("a").WithChildren(
report.MakeNodeSet(
report.MakeNode("child1").
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric1": report.MakeMetric(),
}),
),
),
topology: report.Container,
output: report.Nodes{
"a": report.MakeNode("a").WithMetrics(report.Metrics{
"metric1": report.MakeMetric(),
}).WithChildren(
report.MakeNodeSet(
report.MakeNode("child1").
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric1": report.MakeMetric(),
}),
),
),
},
},
{
name: "ignores other topologies",
input: report.MakeNode("a").WithChildren(
report.MakeNodeSet(
report.MakeNode("child1").
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric1": report.MakeMetric(),
}),
report.MakeNode("child2").
WithTopology("otherTopology").
WithMetrics(report.Metrics{
"metric2": report.MakeMetric(),
}),
),
),
topology: report.Container,
output: report.Nodes{
"a": report.MakeNode("a").WithMetrics(report.Metrics{
"metric1": report.MakeMetric(),
}).WithChildren(
report.MakeNodeSet(
report.MakeNode("child1").
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric1": report.MakeMetric(),
}),
report.MakeNode("child2").
WithTopology("otherTopology").
WithMetrics(report.Metrics{
"metric2": report.MakeMetric(),
}),
),
),
},
},
{
name: "two children",
input: report.MakeNode("a").WithChildren(
report.MakeNodeSet(
report.MakeNode("child1").
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric1": report.MakeMetric(),
}),
report.MakeNode("child2").
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric2": report.MakeMetric(),
}),
),
),
topology: report.Container,
output: report.Nodes{
"a": report.MakeNode("a").WithChildren(
report.MakeNodeSet(
report.MakeNode("child1").
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric1": report.MakeMetric(),
}),
report.MakeNode("child2").
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric2": report.MakeMetric(),
}),
),
),
},
},
{
name: "ignores k8s pause container",
input: report.MakeNode("a").WithChildren(
report.MakeNodeSet(
report.MakeNode("child1").
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric1": report.MakeMetric(),
}),
report.MakeNode("child2").
WithLatest(report.DoesNotMakeConnections, now, "").
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric2": report.MakeMetric(),
}),
),
),
topology: report.Container,
output: report.Nodes{
"a": report.MakeNode("a").WithMetrics(report.Metrics{
"metric1": report.MakeMetric(),
}).WithChildren(
report.MakeNodeSet(
report.MakeNode("child1").
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric1": report.MakeMetric(),
}),
report.MakeNode("child2").
WithLatest(report.DoesNotMakeConnections, now, "").
WithTopology(report.Container).
WithMetrics(report.Metrics{
"metric2": report.MakeMetric(),
}),
),
),
},
},
} {
got := render.PropagateSingleMetrics(c.topology)(c.input, report.Networks{})
if !reflect.DeepEqual(got, c.output) {
t.Errorf("[%s] Diff: %s", c.name, test.Diff(c.output, got))
}
}
}

View File

@@ -26,12 +26,15 @@ var PodRenderer = ConditionalRenderer(renderKubernetesTopologies,
state, ok := n.Latest.Lookup(kubernetes.State)
return (!ok || state != kubernetes.StateDeleted)
},
MakeReduce(
MakeMap(
MapContainer2Pod,
ContainerWithImageNameRenderer,
MakeMap(
PropagateSingleMetrics(report.Container),
MakeReduce(
MakeMap(
MapContainer2Pod,
ContainerWithImageNameRenderer,
),
SelectPod,
),
SelectPod,
),
)),
)
@@ -40,12 +43,15 @@ var PodRenderer = ConditionalRenderer(renderKubernetesTopologies,
// graph by merging the pods graph and the services topology.
var PodServiceRenderer = ConditionalRenderer(renderKubernetesTopologies,
ApplyDecorators(
MakeReduce(
MakeMap(
Map2Service,
PodRenderer,
MakeMap(
PropagateSingleMetrics(report.Pod),
MakeReduce(
MakeMap(
Map2Service,
PodRenderer,
),
SelectService,
),
SelectService,
),
),
)
@@ -54,12 +60,15 @@ var PodServiceRenderer = ConditionalRenderer(renderKubernetesTopologies,
// graph by merging the pods graph and the deployments topology.
var DeploymentRenderer = ConditionalRenderer(renderKubernetesTopologies,
ApplyDecorators(
MakeReduce(
MakeMap(
Map2Deployment,
ReplicaSetRenderer,
MakeMap(
PropagateSingleMetrics(report.ReplicaSet),
MakeReduce(
MakeMap(
Map2Deployment,
ReplicaSetRenderer,
),
SelectDeployment,
),
SelectDeployment,
),
),
)
@@ -68,12 +77,15 @@ var DeploymentRenderer = ConditionalRenderer(renderKubernetesTopologies,
// graph by merging the pods graph and the replica sets topology.
var ReplicaSetRenderer = ConditionalRenderer(renderKubernetesTopologies,
ApplyDecorators(
MakeReduce(
MakeMap(
Map2ReplicaSet,
PodRenderer,
MakeMap(
PropagateSingleMetrics(report.Pod),
MakeReduce(
MakeMap(
Map2ReplicaSet,
PodRenderer,
),
SelectReplicaSet,
),
SelectReplicaSet,
),
),
)