Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace service cpu/mem link to 'Monitor' #3060

Merged
merged 2 commits into from
Feb 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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