Skip to content

Commit

Permalink
Merge pull request #3060 from weaveworks/service-cpu-mem-link-to-monitor
Browse files Browse the repository at this point in the history
Replace service cpu/mem link to 'Monitor'
  • Loading branch information
rbruggem authored Feb 9, 2018
2 parents 8ac4811 + 95a490d commit 14f77fc
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 21 deletions.
52 changes: 39 additions & 13 deletions render/detailed/links.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,8 @@ var (
report.StatefulSet: podIDHashQueries,
report.CronJob: podIDHashQueries,
report.Service: {
// These recording rules must be defined in the prometheus config.
// NB: Pods need to be labeled and selected by their respective Service name, meaning:
// - The Service's `spec.selector` needs to select on `name`
// - The Service's `metadata.name` needs to be the same value as `spec.selector.name`
docker.CPUTotalUsage: `namespace_label_name:container_cpu_usage_seconds_total:sum_rate{label_name="{{label}}",namespace="{{namespace}}"}`,
docker.MemoryUsage: `namespace_label_name:container_memory_usage_bytes:sum{label_name="{{label}}",namespace="{{namespace}}"}`,
docker.CPUTotalUsage: `sum(rate(container_cpu_usage_seconds_total{image!="",namespace="{{namespace}}",_weave_pod_name="{{label}}",job="cadvisor",container_name!="POD"}[5m]))`,
docker.MemoryUsage: `sum(rate(container_memory_usage_bytes{image!="",namespace="{{namespace}}",_weave_pod_name="{{label}}",job="cadvisor",container_name!="POD"}[5m]))`,
},
}
)
Expand Down Expand Up @@ -102,7 +98,7 @@ func formatMetricQueries(filter string, ids []string) map[string]string {

// RenderMetricURLs sets respective URLs for metrics in a node summary. Missing metrics
// where we have a query for will be appended as an empty metric (no values or samples).
func RenderMetricURLs(summary NodeSummary, n report.Node, metricsGraphURL string) NodeSummary {
func RenderMetricURLs(summary NodeSummary, n report.Node, r report.Report, metricsGraphURL string) NodeSummary {
if metricsGraphURL == "" {
return summary
}
Expand All @@ -117,7 +113,7 @@ func RenderMetricURLs(summary NodeSummary, n report.Node, metricsGraphURL string
maxprio = metric.Priority
}

query := metricQuery(summary, n, metric.ID)
query := metricQuery(summary, n, r, metric.ID)
ms = append(ms, metric)

if query != "" {
Expand All @@ -133,7 +129,7 @@ func RenderMetricURLs(summary NodeSummary, n report.Node, metricsGraphURL string
continue
}

query := metricQuery(summary, n, metadata.ID)
query := metricQuery(summary, n, r, metadata.ID)
if query == "" {
continue
}
Expand All @@ -155,20 +151,50 @@ func RenderMetricURLs(summary NodeSummary, n report.Node, metricsGraphURL string
}

// metricQuery returns the query for the given node and metric.
func metricQuery(summary NodeSummary, n report.Node, metricID string) string {
func metricQuery(summary NodeSummary, n report.Node, r report.Report, metricID string) string {
queries := topologyQueries[n.Topology]
if len(queries) == 0 {
return ""
}

namespace, _ := n.Latest.Lookup(kubernetes.Namespace)
name, _ := n.Latest.Lookup(docker.ContainerName)
r := strings.NewReplacer(
"{{label}}", summary.Label,
replacer := strings.NewReplacer(
"{{label}}", metricLabel(summary, n, r),
"{{namespace}}", namespace,
"{{containerName}}", name,
)
return r.Replace(queries[metricID])
return replacer.Replace(queries[metricID])
}

func metricLabel(summary NodeSummary, n report.Node, r report.Report) string {
label := summary.Label
if n.Topology == report.Service {
deploymentTopology, ok := r.Topology(report.Deployment)
if ok {
deploymentNames := []string{}
for _, pod := range r.Pod.Nodes {
serviceParents, serviceOk := pod.Parents.Lookup(report.Service)
deploymentParents, deploymentOk := pod.Parents.Lookup(report.Deployment)
if serviceOk && deploymentOk && serviceParents.Contains(n.ID) {
for _, id := range deploymentParents {
deploymentNode, ok := deploymentTopology.Nodes[id]
if !ok {
continue
}
if name, ok := deploymentNode.Latest.Lookup(report.KubernetesName); ok {
deploymentNames = append(deploymentNames, name)
}
}
break
}
}
if len(deploymentNames) == 1 {
label = deploymentNames[0]
}
}
}
return label
}

// metricURL builds the URL by embedding it into the configured `metricsGraphURL`.
Expand Down
14 changes: 7 additions & 7 deletions render/detailed/links_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,23 @@ func nodeSummaryWithMetrics(label string, metrics []report.MetricRow) detailed.N

func TestRenderMetricURLs_Disabled(t *testing.T) {
s := nodeSummaryWithMetrics("foo", sampleMetrics)
result := detailed.RenderMetricURLs(s, samplePodNode, "")
result := detailed.RenderMetricURLs(s, samplePodNode, report.MakeReport(), "")

assert.Empty(t, result.Metrics[0].URL)
assert.Empty(t, result.Metrics[1].URL)
}

func TestRenderMetricURLs_UnknownTopology(t *testing.T) {
s := nodeSummaryWithMetrics("foo", sampleMetrics)
result := detailed.RenderMetricURLs(s, sampleUnknownNode, sampleMetricsGraphURL)
result := detailed.RenderMetricURLs(s, sampleUnknownNode, report.MakeReport(), sampleMetricsGraphURL)

assert.Empty(t, result.Metrics[0].URL)
assert.Empty(t, result.Metrics[1].URL)
}

func TestRenderMetricURLs_Pod(t *testing.T) {
s := nodeSummaryWithMetrics("foo", sampleMetrics)
result := detailed.RenderMetricURLs(s, samplePodNode, sampleMetricsGraphURL)
result := detailed.RenderMetricURLs(s, samplePodNode, report.MakeReport(), sampleMetricsGraphURL)

checkURL(t, result.Metrics[0].URL, sampleMetricsGraphURL,
[]string{"container_memory_usage_bytes", `pod_name=\"foo\"`, `namespace=\"noospace\"`})
Expand All @@ -68,7 +68,7 @@ func TestRenderMetricURLs_Pod(t *testing.T) {

func TestRenderMetricURLs_Container(t *testing.T) {
s := nodeSummaryWithMetrics("foo", sampleMetrics)
result := detailed.RenderMetricURLs(s, sampleContainerNode, sampleMetricsGraphURL)
result := detailed.RenderMetricURLs(s, sampleContainerNode, report.MakeReport(), sampleMetricsGraphURL)

checkURL(t, result.Metrics[0].URL, sampleMetricsGraphURL,
[]string{"container_memory_usage_bytes", `name=\"cooname\"`})
Expand All @@ -77,7 +77,7 @@ func TestRenderMetricURLs_Container(t *testing.T) {
}

func TestRenderMetricURLs_EmptyMetrics(t *testing.T) {
result := detailed.RenderMetricURLs(detailed.NodeSummary{}, samplePodNode, sampleMetricsGraphURL)
result := detailed.RenderMetricURLs(detailed.NodeSummary{}, samplePodNode, report.MakeReport(), sampleMetricsGraphURL)

m := result.Metrics[0]
assert.Equal(t, docker.CPUTotalUsage, m.ID)
Expand All @@ -94,7 +94,7 @@ func TestRenderMetricURLs_EmptyMetrics(t *testing.T) {

func TestRenderMetricURLs_CombinedEmptyMetrics(t *testing.T) {
s := nodeSummaryWithMetrics("foo", []report.MetricRow{{ID: docker.MemoryUsage, Priority: 1}})
result := detailed.RenderMetricURLs(s, samplePodNode, sampleMetricsGraphURL)
result := detailed.RenderMetricURLs(s, samplePodNode, report.MakeReport(), sampleMetricsGraphURL)

assert.NotEmpty(t, result.Metrics[0].URL)
assert.False(t, result.Metrics[0].ValueEmpty)
Expand All @@ -106,7 +106,7 @@ func TestRenderMetricURLs_CombinedEmptyMetrics(t *testing.T) {

func TestRenderMetricURLs_QueryReplacement(t *testing.T) {
s := nodeSummaryWithMetrics("foo", sampleMetrics)
result := detailed.RenderMetricURLs(s, samplePodNode, "http://example.test/?q=:query")
result := detailed.RenderMetricURLs(s, samplePodNode, report.MakeReport(), "http://example.test/?q=:query")

checkURL(t, result.Metrics[0].URL, "http://example.test/?q=",
[]string{"container_memory_usage_bytes", `pod_name="foo"`, `namespace="noospace"`})
Expand Down
2 changes: 1 addition & 1 deletion render/detailed/summary.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ func MakeNodeSummary(rc RenderContext, n report.Node) (NodeSummary, bool) {
summary.Tables = topology.TableTemplates.Tables(n)
}
}
return RenderMetricURLs(summary, n, rc.MetricsGraphURL), true
return RenderMetricURLs(summary, n, rc.Report, rc.MetricsGraphURL), true
}

// SummarizeMetrics returns a copy of the NodeSummary where the metrics are
Expand Down

0 comments on commit 14f77fc

Please sign in to comment.