From 3be8cf71dd82c15671d283a88ea193f6857400f1 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Fri, 26 Oct 2018 08:51:33 +0300 Subject: [PATCH] Add more Opentracing detail to the app (#3383) * Pass Go context down to Renderers This is useful for cancellation or tracing. * Add tracing spans to app Also log things like number of nodes in Map, total number of reports. --- app/api_topologies.go | 20 +++++++++------- app/api_topologies_test.go | 8 ++++--- app/api_topology.go | 6 ++--- app/benchmark_internal_test.go | 8 ++++--- app/multitenant/aws_collector.go | 5 ++++ app/multitenant/memcache_client.go | 5 ++++ render/benchmark_test.go | 3 ++- render/container.go | 13 +++++----- render/container_test.go | 13 +++++----- render/detailed/node_test.go | 9 +++---- render/detailed/parents_test.go | 12 ++++++---- render/detailed/summary.go | 7 +++++- render/detailed/summary_test.go | 5 ++-- render/endpoint.go | 8 ++++--- render/filters.go | 9 +++---- render/filters_test.go | 14 ++++++----- render/func_name.go | 17 +++++++++++++ render/host_test.go | 3 ++- render/memoise.go | 5 ++-- render/memoise_test.go | 16 +++++++------ render/metrics.go | 6 +++-- render/metrics_test.go | 3 ++- render/persistentvolume.go | 12 ++++++---- render/pod.go | 5 ++-- render/pod_test.go | 9 +++---- render/process.go | 8 ++++--- render/process_test.go | 7 +++--- render/render.go | 33 +++++++++++++++++++------- render/render_test.go | 11 +++++---- render/selectors.go | 4 +++- render/short_lived_connections_test.go | 5 ++-- 31 files changed, 187 insertions(+), 102 deletions(-) create mode 100644 render/func_name.go diff --git a/app/api_topologies.go b/app/api_topologies.go index 7298542b4f..136d6960f6 100644 --- a/app/api_topologies.go +++ b/app/api_topologies.go @@ -1,6 +1,7 @@ package app import ( + "context" "fmt" "net/http" "net/url" @@ -9,9 +10,8 @@ import ( "sync" "time" - "context" - "github.com/gorilla/mux" + opentracing "github.com/opentracing/opentracing-go" log "github.com/sirupsen/logrus" "github.com/weaveworks/scope/probe/docker" @@ -479,32 +479,36 @@ func (r *Registry) makeTopologyList(rep Reporter) CtxHandlerFunc { respondWith(w, http.StatusInternalServerError, err) return } - respondWith(w, http.StatusOK, r.renderTopologies(report, req)) + respondWith(w, http.StatusOK, r.renderTopologies(ctx, report, req)) } } -func (r *Registry) renderTopologies(rpt report.Report, req *http.Request) []APITopologyDesc { +func (r *Registry) renderTopologies(ctx context.Context, rpt report.Report, req *http.Request) []APITopologyDesc { + span, ctx := opentracing.StartSpanFromContext(ctx, "app.renderTopologies") + defer span.Finish() topologies := []APITopologyDesc{} req.ParseForm() r.walk(func(desc APITopologyDesc) { renderer, filter, _ := r.RendererForTopology(desc.id, req.Form, rpt) - desc.Stats = computeStats(rpt, renderer, filter) + desc.Stats = computeStats(ctx, rpt, renderer, filter) for i, sub := range desc.SubTopologies { renderer, filter, _ := r.RendererForTopology(sub.id, req.Form, rpt) - desc.SubTopologies[i].Stats = computeStats(rpt, renderer, filter) + desc.SubTopologies[i].Stats = computeStats(ctx, rpt, renderer, filter) } topologies = append(topologies, desc) }) return updateFilters(rpt, topologies) } -func computeStats(rpt report.Report, renderer render.Renderer, transformer render.Transformer) topologyStats { +func computeStats(ctx context.Context, rpt report.Report, renderer render.Renderer, transformer render.Transformer) topologyStats { + span, ctx := opentracing.StartSpanFromContext(ctx, "app.computeStats") + defer span.Finish() var ( nodes int realNodes int edges int ) - r := render.Render(rpt, renderer, transformer) + r := render.Render(ctx, rpt, renderer, transformer) for _, n := range r.Nodes { nodes++ if n.Topology != render.Pseudo { diff --git a/app/api_topologies_test.go b/app/api_topologies_test.go index c8d117914c..7c8511534f 100644 --- a/app/api_topologies_test.go +++ b/app/api_topologies_test.go @@ -2,6 +2,7 @@ package app_test import ( "bytes" + "context" "net/http/httptest" "net/url" "testing" @@ -118,7 +119,7 @@ func TestRendererForTopologyWithFiltering(t *testing.T) { input.Container.Nodes[fixture.ClientContainerNodeID] = input.Container.Nodes[fixture.ClientContainerNodeID].WithLatests(map[string]string{ docker.LabelPrefix + "works.weave.role": "system", }) - have := utils.Prune(render.Render(input, renderer, filter).Nodes) + have := utils.Prune(render.Render(context.Background(), input, renderer, filter).Nodes) want := utils.Prune(expected.RenderedContainers.Copy()) delete(want, fixture.ClientContainerNodeID) delete(want, render.MakePseudoNodeID(render.UncontainedID, fixture.ServerHostID)) @@ -149,7 +150,7 @@ func TestRendererForTopologyNoFiltering(t *testing.T) { input.Container.Nodes[fixture.ClientContainerNodeID] = input.Container.Nodes[fixture.ClientContainerNodeID].WithLatests(map[string]string{ docker.LabelPrefix + "works.weave.role": "system", }) - have := utils.Prune(render.Render(input, renderer, filter).Nodes) + have := utils.Prune(render.Render(context.Background(), input, renderer, filter).Nodes) want := utils.Prune(expected.RenderedContainers.Copy()) delete(want, render.MakePseudoNodeID(render.UncontainedID, fixture.ServerHostID)) delete(want, render.OutgoingInternetID) @@ -183,7 +184,8 @@ func getTestContainerLabelFilterTopologySummary(t *testing.T, exclude bool) (det return nil, err } - return detailed.Summaries(detailed.RenderContext{Report: fixture.Report}, render.Render(fixture.Report, renderer, filter).Nodes), nil + ctx := context.Background() + return detailed.Summaries(ctx, detailed.RenderContext{Report: fixture.Report}, render.Render(ctx, fixture.Report, renderer, filter).Nodes), nil } func TestAPITopologyAddsKubernetes(t *testing.T) { diff --git a/app/api_topology.go b/app/api_topology.go index d00824526b..9f2357af23 100644 --- a/app/api_topology.go +++ b/app/api_topology.go @@ -42,7 +42,7 @@ type rendererHandler func(context.Context, render.Renderer, render.Transformer, // Full topology. func handleTopology(ctx context.Context, renderer render.Renderer, transformer render.Transformer, rc detailed.RenderContext, w http.ResponseWriter, r *http.Request) { respondWith(w, http.StatusOK, APITopology{ - Nodes: detailed.Summaries(rc, render.Render(rc.Report, renderer, transformer).Nodes), + Nodes: detailed.Summaries(ctx, rc, render.Render(ctx, rc.Report, renderer, transformer).Nodes), }) } @@ -58,7 +58,7 @@ func handleNode(ctx context.Context, renderer render.Renderer, transformer rende // filtering, which gives us the node (if it exists at all), and // then (2) applying the filter separately to that result. If the // node is lost in the second step, we simply put it back. - nodes := renderer.Render(rc.Report) + nodes := renderer.Render(ctx, rc.Report) node, ok := nodes.Nodes[nodeID] if !ok { http.NotFound(w, r) @@ -145,7 +145,7 @@ func handleWebsocket( log.Errorf("Error generating report: %v", err) return } - newTopo := detailed.Summaries(RenderContextForReporter(rep, re), render.Render(re, renderer, filter).Nodes) + newTopo := detailed.Summaries(ctx, RenderContextForReporter(rep, re), render.Render(ctx, re, renderer, filter).Nodes) diff := detailed.TopoDiff(previousTopo, newTopo) previousTopo = newTopo diff --git a/app/benchmark_internal_test.go b/app/benchmark_internal_test.go index 9164ffe064..18e79fdd9c 100644 --- a/app/benchmark_internal_test.go +++ b/app/benchmark_internal_test.go @@ -1,6 +1,7 @@ package app import ( + "context" "flag" "math/rand" "net/http" @@ -100,7 +101,7 @@ func renderForTopology(b *testing.B, topologyID string, report report.Report) re if err != nil { b.Fatal(err) } - return render.Render(report, renderer, filter).Nodes + return render.Render(context.Background(), report, renderer, filter).Nodes } func benchmarkRenderTopology(b *testing.B, topologyID string) { @@ -111,7 +112,7 @@ func benchmarkRenderTopology(b *testing.B, topologyID string) { func BenchmarkRenderList(b *testing.B) { benchmarkRender(b, func(report report.Report) { - topologyRegistry.renderTopologies(report, &http.Request{Form: url.Values{}}) + topologyRegistry.renderTopologies(context.Background(), report, &http.Request{Form: url.Values{}}) }) } @@ -140,12 +141,13 @@ func BenchmarkRenderProcessNames(b *testing.B) { } func benchmarkSummarizeTopology(b *testing.B, topologyID string) { + ctx := context.Background() r := getReport(b) rc := detailed.RenderContext{Report: r} nodes := renderForTopology(b, topologyID, r) b.ResetTimer() for i := 0; i < b.N; i++ { - detailed.Summaries(rc, nodes) + detailed.Summaries(ctx, rc, nodes) } } diff --git a/app/multitenant/aws_collector.go b/app/multitenant/aws_collector.go index 4bb404c8a7..4d77a016cd 100644 --- a/app/multitenant/aws_collector.go +++ b/app/multitenant/aws_collector.go @@ -15,6 +15,8 @@ import ( "github.com/aws/aws-sdk-go/service/dynamodb" "github.com/bluele/gcache" "github.com/nats-io/nats" + opentracing "github.com/opentracing/opentracing-go" + otlog "github.com/opentracing/opentracing-go/log" "github.com/prometheus/client_golang/prometheus" log "github.com/sirupsen/logrus" @@ -336,10 +338,13 @@ func (c *awsCollector) getReports(ctx context.Context, reportKeys []string) ([]r } func (c *awsCollector) Report(ctx context.Context, timestamp time.Time) (report.Report, error) { + span, ctx := opentracing.StartSpanFromContext(ctx, "awsCollector.Report") + defer span.Finish() reportKeys, err := c.getReportKeys(ctx, timestamp) if err != nil { return report.MakeReport(), err } + span.LogFields(otlog.Int("keys", len(reportKeys)), otlog.String("timestamp", timestamp.String())) log.Debugf("Fetching %d reports to %v", len(reportKeys), timestamp) reports, err := c.getReports(ctx, reportKeys) if err != nil { diff --git a/app/multitenant/memcache_client.go b/app/multitenant/memcache_client.go index acb8c4f8e8..5393c3141d 100644 --- a/app/multitenant/memcache_client.go +++ b/app/multitenant/memcache_client.go @@ -9,6 +9,8 @@ import ( "context" "github.com/bradfitz/gomemcache/memcache" + opentracing "github.com/opentracing/opentracing-go" + otlog "github.com/opentracing/opentracing-go/log" "github.com/prometheus/client_golang/prometheus" log "github.com/sirupsen/logrus" @@ -150,6 +152,8 @@ func memcacheStatusCode(err error) string { // FetchReports gets reports from memcache. func (c *MemcacheClient) FetchReports(ctx context.Context, keys []string) (map[string]report.Report, []string, error) { + span, ctx := opentracing.StartSpanFromContext(ctx, "Memcache.FetchReports") + defer span.Finish() defer memcacheRequests.Add(float64(len(keys))) var found map[string]*memcache.Item err := instrument.TimeRequestHistogramStatus(ctx, "Memcache.GetMulti", memcacheRequestDuration, memcacheStatusCode, func(_ context.Context) error { @@ -157,6 +161,7 @@ func (c *MemcacheClient) FetchReports(ctx context.Context, keys []string) (map[s found, err = c.client.GetMulti(keys) return err }) + span.LogFields(otlog.Int("keys", len(keys)), otlog.Int("hits", len(found))) if err != nil { return nil, keys, err } diff --git a/render/benchmark_test.go b/render/benchmark_test.go index 1c6b5aeacc..962f83a4a8 100644 --- a/render/benchmark_test.go +++ b/render/benchmark_test.go @@ -1,6 +1,7 @@ package render_test import ( + "context" "flag" "io/ioutil" "testing" @@ -51,7 +52,7 @@ func benchmarkRender(b *testing.B, r render.Renderer) { b.StopTimer() render.ResetCache() b.StartTimer() - benchmarkRenderResult = r.Render(report) + benchmarkRenderResult = r.Render(context.Background(), report) if len(benchmarkRenderResult.Nodes) == 0 { b.Errorf("Rendered topology contained no nodes") } diff --git a/render/container.go b/render/container.go index df78553d85..9dca12d64d 100644 --- a/render/container.go +++ b/render/container.go @@ -1,6 +1,7 @@ package render import ( + "context" "regexp" "github.com/weaveworks/scope/probe/docker" @@ -53,8 +54,8 @@ type connectionJoin struct { topology string } -func (c connectionJoin) Render(rpt report.Report) Nodes { - inputNodes := TopologySelector(c.topology).Render(rpt).Nodes +func (c connectionJoin) Render(ctx context.Context, rpt report.Report) Nodes { + inputNodes := TopologySelector(c.topology).Render(ctx, rpt).Nodes // Collect all the IPs we are trying to map to, and which ID they map from var ipNodes = map[string]string{} for _, n := range inputNodes { @@ -92,7 +93,7 @@ func (c connectionJoin) Render(rpt report.Report) Nodes { // from ipNodes, which is populated from c.topology, which // is where MapEndpoints will look. return id - }, c.topology).Render(rpt) + }, c.topology).Render(ctx, rpt) } // FilterEmpty is a Renderer which filters out nodes which have no children @@ -121,9 +122,9 @@ type containerWithImageNameRenderer struct { // Render produces a container graph where the the latest metadata contains the // container image name, if found. -func (r containerWithImageNameRenderer) Render(rpt report.Report) Nodes { - containers := r.Renderer.Render(rpt) - images := SelectContainerImage.Render(rpt) +func (r containerWithImageNameRenderer) Render(ctx context.Context, rpt report.Report) Nodes { + containers := r.Renderer.Render(ctx, rpt) + images := SelectContainerImage.Render(ctx, rpt) outputs := make(report.Nodes, len(containers.Nodes)) for id, c := range containers.Nodes { diff --git a/render/container_test.go b/render/container_test.go index f9565b9978..f86035d133 100644 --- a/render/container_test.go +++ b/render/container_test.go @@ -1,6 +1,7 @@ package render_test import ( + "context" "fmt" "testing" @@ -53,7 +54,7 @@ func testMap(t *testing.T, f render.MapFunc, input testcase) { } func TestContainerRenderer(t *testing.T) { - have := utils.Prune(render.ContainerWithImageNameRenderer.Render(fixture.Report).Nodes) + have := utils.Prune(render.ContainerWithImageNameRenderer.Render(context.Background(), fixture.Report).Nodes) want := utils.Prune(expected.RenderedContainers) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) @@ -67,7 +68,7 @@ func TestContainerFilterRenderer(t *testing.T) { input.Container.Nodes[fixture.ClientContainerNodeID] = input.Container.Nodes[fixture.ClientContainerNodeID].WithLatests(map[string]string{ docker.LabelPrefix + "works.weave.role": "system", }) - have := utils.Prune(render.Render(input, render.ContainerWithImageNameRenderer, filterApplication).Nodes) + have := utils.Prune(render.Render(context.Background(), input, render.ContainerWithImageNameRenderer, filterApplication).Nodes) want := utils.Prune(expected.RenderedContainers.Copy()) delete(want, fixture.ClientContainerNodeID) if !reflect.DeepEqual(want, have) { @@ -76,7 +77,7 @@ func TestContainerFilterRenderer(t *testing.T) { } func TestContainerHostnameRenderer(t *testing.T) { - have := utils.Prune(render.Render(fixture.Report, render.ContainerHostnameRenderer, render.Transformers(nil)).Nodes) + have := utils.Prune(render.Render(context.Background(), fixture.Report, render.ContainerHostnameRenderer, render.Transformers(nil)).Nodes) want := utils.Prune(expected.RenderedContainerHostnames) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) @@ -84,7 +85,7 @@ func TestContainerHostnameRenderer(t *testing.T) { } func TestContainerHostnameFilterRenderer(t *testing.T) { - have := utils.Prune(render.Render(fixture.Report, render.ContainerHostnameRenderer, filterSystem).Nodes) + have := utils.Prune(render.Render(context.Background(), fixture.Report, render.ContainerHostnameRenderer, filterSystem).Nodes) want := utils.Prune(expected.RenderedContainerHostnames.Copy()) delete(want, fixture.ClientContainerHostname) delete(want, fixture.ServerContainerHostname) @@ -95,7 +96,7 @@ func TestContainerHostnameFilterRenderer(t *testing.T) { } func TestContainerImageRenderer(t *testing.T) { - have := utils.Prune(render.Render(fixture.Report, render.ContainerImageRenderer, render.Transformers(nil)).Nodes) + have := utils.Prune(render.Render(context.Background(), fixture.Report, render.ContainerImageRenderer, render.Transformers(nil)).Nodes) want := utils.Prune(expected.RenderedContainerImages) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) @@ -103,7 +104,7 @@ func TestContainerImageRenderer(t *testing.T) { } func TestContainerImageFilterRenderer(t *testing.T) { - have := utils.Prune(render.Render(fixture.Report, render.ContainerImageRenderer, filterSystem).Nodes) + have := utils.Prune(render.Render(context.Background(), fixture.Report, render.ContainerImageRenderer, filterSystem).Nodes) want := utils.Prune(expected.RenderedContainerHostnames.Copy()) delete(want, fixture.ClientContainerHostname) delete(want, fixture.ServerContainerHostname) diff --git a/render/detailed/node_test.go b/render/detailed/node_test.go index b22ff40233..5e5f9e635f 100644 --- a/render/detailed/node_test.go +++ b/render/detailed/node_test.go @@ -1,6 +1,7 @@ package detailed_test import ( + "context" "fmt" "testing" @@ -18,7 +19,7 @@ import ( ) func child(t *testing.T, r render.Renderer, id string) detailed.NodeSummary { - s, ok := detailed.MakeNodeSummary(detailed.RenderContext{Report: fixture.Report}, r.Render(fixture.Report).Nodes[id]) + s, ok := detailed.MakeNodeSummary(detailed.RenderContext{Report: fixture.Report}, r.Render(context.Background(), fixture.Report).Nodes[id]) if !ok { t.Fatalf("Expected node %s to be summarizable, but wasn't", id) } @@ -30,7 +31,7 @@ func connectionID(nodeID string, addr string) string { } func TestMakeDetailedHostNode(t *testing.T) { - renderableNodes := render.HostRenderer.Render(fixture.Report).Nodes + renderableNodes := render.HostRenderer.Render(context.Background(), fixture.Report).Nodes renderableNode := renderableNodes[fixture.ClientHostNodeID] have := detailed.MakeNode("hosts", detailed.RenderContext{Report: fixture.Report}, renderableNodes, renderableNode) @@ -177,7 +178,7 @@ func TestMakeDetailedHostNode(t *testing.T) { func TestMakeDetailedContainerNode(t *testing.T) { id := fixture.ServerContainerNodeID - renderableNodes := render.ContainerWithImageNameRenderer.Render(fixture.Report).Nodes + renderableNodes := render.ContainerWithImageNameRenderer.Render(context.Background(), fixture.Report).Nodes renderableNode, ok := renderableNodes[id] if !ok { t.Fatalf("Node not found: %s", id) @@ -306,7 +307,7 @@ func TestMakeDetailedContainerNode(t *testing.T) { func TestMakeDetailedPodNode(t *testing.T) { id := fixture.ServerPodNodeID - renderableNodes := render.PodRenderer.Render(fixture.Report).Nodes + renderableNodes := render.PodRenderer.Render(context.Background(), fixture.Report).Nodes renderableNode, ok := renderableNodes[id] if !ok { t.Fatalf("Node not found: %s", id) diff --git a/render/detailed/parents_test.go b/render/detailed/parents_test.go index 3332d651da..d719595e44 100644 --- a/render/detailed/parents_test.go +++ b/render/detailed/parents_test.go @@ -1,6 +1,7 @@ package detailed_test import ( + "context" "fmt" "testing" @@ -14,6 +15,7 @@ import ( ) func TestParents(t *testing.T) { + ctx := context.Background() for _, c := range []struct { name string node report.Node @@ -21,25 +23,25 @@ func TestParents(t *testing.T) { }{ { name: "Node accidentally tagged with itself", - node: render.HostRenderer.Render(fixture.Report).Nodes[fixture.ClientHostNodeID].WithParents( + node: render.HostRenderer.Render(ctx, fixture.Report).Nodes[fixture.ClientHostNodeID].WithParents( report.MakeSets().Add(report.Host, report.MakeStringSet(fixture.ClientHostNodeID)), ), want: nil, }, { - node: render.HostRenderer.Render(fixture.Report).Nodes[fixture.ClientHostNodeID], + node: render.HostRenderer.Render(ctx, fixture.Report).Nodes[fixture.ClientHostNodeID], want: nil, }, { name: "Container image", - node: render.ContainerImageRenderer.Render(fixture.Report).Nodes[expected.ClientContainerImageNodeID], + node: render.ContainerImageRenderer.Render(ctx, fixture.Report).Nodes[expected.ClientContainerImageNodeID], want: []detailed.Parent{ {ID: fixture.ClientHostNodeID, Label: "client", TopologyID: "hosts"}, }, }, { name: "Container", - node: render.ContainerWithImageNameRenderer.Render(fixture.Report).Nodes[fixture.ClientContainerNodeID], + node: render.ContainerWithImageNameRenderer.Render(ctx, fixture.Report).Nodes[fixture.ClientContainerNodeID], want: []detailed.Parent{ {ID: expected.ClientContainerImageNodeID, Label: fixture.ClientContainerImageName, TopologyID: "containers-by-image"}, {ID: fixture.ClientPodNodeID, Label: "pong-a", TopologyID: "pods"}, @@ -47,7 +49,7 @@ func TestParents(t *testing.T) { }, }, { - node: render.ProcessRenderer.Render(fixture.Report).Nodes[fixture.ClientProcess1NodeID], + node: render.ProcessRenderer.Render(ctx, fixture.Report).Nodes[fixture.ClientProcess1NodeID], want: []detailed.Parent{ {ID: fixture.ClientContainerNodeID, Label: fixture.ClientContainerName, TopologyID: "containers"}, {ID: fixture.ClientHostNodeID, Label: "client", TopologyID: "hosts"}, diff --git a/render/detailed/summary.go b/render/detailed/summary.go index d50417eb62..a6c24c95dd 100644 --- a/render/detailed/summary.go +++ b/render/detailed/summary.go @@ -1,9 +1,12 @@ package detailed import ( + "context" "fmt" "strings" + opentracing "github.com/opentracing/opentracing-go" + "github.com/weaveworks/scope/probe/awsecs" "github.com/weaveworks/scope/probe/docker" "github.com/weaveworks/scope/probe/kubernetes" @@ -446,7 +449,9 @@ func (s nodeSummariesByID) Less(i, j int) bool { return s[i].ID < s[j].ID } type NodeSummaries map[string]NodeSummary // Summaries converts RenderableNodes into a set of NodeSummaries -func Summaries(rc RenderContext, rns report.Nodes) NodeSummaries { +func Summaries(ctx context.Context, rc RenderContext, rns report.Nodes) NodeSummaries { + span, ctx := opentracing.StartSpanFromContext(ctx, "detailed.Summaries") + defer span.Finish() result := NodeSummaries{} for id, node := range rns { diff --git a/render/detailed/summary_test.go b/render/detailed/summary_test.go index 07ba5e7a4c..8145978807 100644 --- a/render/detailed/summary_test.go +++ b/render/detailed/summary_test.go @@ -1,6 +1,7 @@ package detailed_test import ( + "context" "sort" "testing" "time" @@ -21,7 +22,7 @@ import ( func TestSummaries(t *testing.T) { { // Just a convenient source of some rendered nodes - have := detailed.Summaries(detailed.RenderContext{Report: fixture.Report}, render.ProcessRenderer.Render(fixture.Report).Nodes) + have := detailed.Summaries(context.Background(), detailed.RenderContext{Report: fixture.Report}, render.ProcessRenderer.Render(context.Background(), fixture.Report).Nodes) // The ids of the processes rendered above expectedIDs := []string{ fixture.ClientProcess1NodeID, @@ -53,7 +54,7 @@ func TestSummaries(t *testing.T) { processNode.Metrics = processNode.Metrics.Copy() processNode.Metrics[process.CPUUsage] = metric input.Process.Nodes[fixture.ClientProcess1NodeID] = processNode - have := detailed.Summaries(detailed.RenderContext{Report: input}, render.ProcessRenderer.Render(input).Nodes) + have := detailed.Summaries(context.Background(), detailed.RenderContext{Report: input}, render.ProcessRenderer.Render(context.Background(), input).Nodes) node, ok := have[fixture.ClientProcess1NodeID] if !ok { diff --git a/render/endpoint.go b/render/endpoint.go index 2e610b1f83..c645bb995e 100644 --- a/render/endpoint.go +++ b/render/endpoint.go @@ -1,6 +1,8 @@ package render import ( + "context" + "github.com/weaveworks/scope/report" ) @@ -27,10 +29,10 @@ func MapEndpoints(f endpointMapFunc, topology string) Renderer { return mapEndpoints{f: f, topology: topology} } -func (e mapEndpoints) Render(rpt report.Report) Nodes { +func (e mapEndpoints) Render(ctx context.Context, rpt report.Report) Nodes { local := LocalNetworks(rpt) - endpoints := SelectEndpoint.Render(rpt) - ret := newJoinResults(TopologySelector(e.topology).Render(rpt).Nodes) + endpoints := SelectEndpoint.Render(ctx, rpt) + ret := newJoinResults(TopologySelector(e.topology).Render(ctx, rpt).Nodes) for _, n := range endpoints.Nodes { // Nodes without a hostid are mapped to pseudo nodes, if diff --git a/render/filters.go b/render/filters.go index 8d02a5918f..c586c77dc2 100644 --- a/render/filters.go +++ b/render/filters.go @@ -1,6 +1,7 @@ package render import ( + "context" "strings" "github.com/weaveworks/common/mtime" @@ -23,8 +24,8 @@ type CustomRenderer struct { } // Render implements Renderer -func (c CustomRenderer) Render(rpt report.Report) Nodes { - return c.RenderFunc(c.Renderer.Render(rpt)) +func (c CustomRenderer) Render(ctx context.Context, rpt report.Report) Nodes { + return c.RenderFunc(c.Renderer.Render(ctx, rpt)) } // FilterFunc is the function type used by Filters @@ -112,8 +113,8 @@ func MakeFilterPseudo(f FilterFunc, r Renderer) Renderer { } // Render implements Renderer -func (f Filter) Render(rpt report.Report) Nodes { - return f.FilterFunc.Transform(f.Renderer.Render(rpt)) +func (f Filter) Render(ctx context.Context, rpt report.Report) Nodes { + return f.FilterFunc.Transform(f.Renderer.Render(ctx, rpt)) } // IsConnectedMark is the key added to Node.Metadata by diff --git a/render/filters_test.go b/render/filters_test.go index b31dfc1fb2..9ec5c3ecb3 100644 --- a/render/filters_test.go +++ b/render/filters_test.go @@ -1,6 +1,7 @@ package render_test import ( + "context" "testing" "github.com/weaveworks/common/test" @@ -23,7 +24,7 @@ func TestFilterRender(t *testing.T) { "baz": report.MakeNode("baz"), }} have := report.MakeIDList() - for id := range render.Render(report.MakeReport(), render.ColorConnected(renderer), render.FilterFunc(render.IsConnected)).Nodes { + for id := range render.Render(context.Background(), report.MakeReport(), render.ColorConnected(renderer), render.FilterFunc(render.IsConnected)).Nodes { have = have.Add(id) } want := report.MakeIDList("foo", "bar") @@ -39,13 +40,14 @@ func TestFilterRender2(t *testing.T) { "bar": report.MakeNode("bar").WithAdjacent("foo"), "baz": report.MakeNode("baz"), }} - have := render.Render(report.MakeReport(), renderer, filterBar).Nodes + have := render.Render(context.Background(), report.MakeReport(), renderer, filterBar).Nodes if have["foo"].Adjacency.Contains("bar") { t.Error("adjacencies for removed nodes should have been removed") } } func TestFilterUnconnectedPseudoNodes(t *testing.T) { + ctx := context.Background() // Test pseudo nodes that are made unconnected by filtering // are also removed. { @@ -56,7 +58,7 @@ func TestFilterUnconnectedPseudoNodes(t *testing.T) { } renderer := mockRenderer{Nodes: nodes} want := nodes - have := render.Render(report.MakeReport(), renderer, render.Transformers(nil)).Nodes + have := render.Render(ctx, report.MakeReport(), renderer, render.Transformers(nil)).Nodes if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } @@ -67,7 +69,7 @@ func TestFilterUnconnectedPseudoNodes(t *testing.T) { "bar": report.MakeNode("bar").WithAdjacent("baz"), "baz": report.MakeNode("baz").WithTopology(render.Pseudo), }} - have := render.Render(report.MakeReport(), renderer, filterBar).Nodes + have := render.Render(ctx, report.MakeReport(), renderer, filterBar).Nodes if _, ok := have["baz"]; ok { t.Error("expected the unconnected pseudonode baz to have been removed") } @@ -78,7 +80,7 @@ func TestFilterUnconnectedPseudoNodes(t *testing.T) { "bar": report.MakeNode("bar").WithAdjacent("foo"), "baz": report.MakeNode("baz").WithTopology(render.Pseudo).WithAdjacent("bar"), }} - have := render.Render(report.MakeReport(), renderer, filterBar).Nodes + have := render.Render(ctx, report.MakeReport(), renderer, filterBar).Nodes if _, ok := have["baz"]; ok { t.Error("expected the unconnected pseudonode baz to have been removed") } @@ -92,7 +94,7 @@ func TestFilterUnconnectedSelf(t *testing.T) { "foo": report.MakeNode("foo").WithAdjacent("foo"), } renderer := mockRenderer{Nodes: nodes} - have := render.Render(report.MakeReport(), render.ColorConnected(renderer), render.FilterFunc(render.IsConnected)).Nodes + have := render.Render(context.Background(), report.MakeReport(), render.ColorConnected(renderer), render.FilterFunc(render.IsConnected)).Nodes if len(have) > 0 { t.Error("expected node only connected to self to be removed") } diff --git a/render/func_name.go b/render/func_name.go new file mode 100644 index 0000000000..63c768282f --- /dev/null +++ b/render/func_name.go @@ -0,0 +1,17 @@ +package render + +import ( + "reflect" + "runtime" +) + +func functionName(i interface{}) string { + return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() +} + +func typeName(i interface{}) string { + if m, ok := i.(*memoise); ok { + return "memoise:" + typeName(m.Renderer) + } + return reflect.TypeOf(i).String() +} diff --git a/render/host_test.go b/render/host_test.go index 3f30188e61..a1a2b606ff 100644 --- a/render/host_test.go +++ b/render/host_test.go @@ -1,6 +1,7 @@ package render_test import ( + "context" "testing" "github.com/weaveworks/common/test" @@ -12,7 +13,7 @@ import ( ) func TestHostRenderer(t *testing.T) { - have := utils.Prune(render.HostRenderer.Render(fixture.Report).Nodes) + have := utils.Prune(render.HostRenderer.Render(context.Background(), fixture.Report).Nodes) want := utils.Prune(expected.RenderedHosts) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) diff --git a/render/memoise.go b/render/memoise.go index 93859327d8..69dcaee277 100644 --- a/render/memoise.go +++ b/render/memoise.go @@ -1,6 +1,7 @@ package render import ( + "context" "fmt" "math/rand" "sync" @@ -40,7 +41,7 @@ func Memoise(r Renderer) Renderer { // retrieves a promise from the cache and returns its value, otherwise // it stores a new promise and fulfils it by calling through to // m.Renderer. -func (m *memoise) Render(rpt report.Report) Nodes { +func (m *memoise) Render(ctx context.Context, rpt report.Report) Nodes { key := fmt.Sprintf("%s-%s", rpt.ID, m.id) m.Lock() @@ -53,7 +54,7 @@ func (m *memoise) Render(rpt report.Report) Nodes { renderCache.Set(key, promise) m.Unlock() - output := m.Renderer.Render(rpt) + output := m.Renderer.Render(ctx, rpt) promise.Set(output) diff --git a/render/memoise_test.go b/render/memoise_test.go index 79c779a362..d59d281f91 100644 --- a/render/memoise_test.go +++ b/render/memoise_test.go @@ -1,6 +1,7 @@ package render_test import ( + "context" "testing" "github.com/weaveworks/common/test" @@ -9,13 +10,13 @@ import ( "github.com/weaveworks/scope/test/reflect" ) -type renderFunc func(r report.Report) render.Nodes +type renderFunc func(ctx context.Context, r report.Report) render.Nodes -func (f renderFunc) Render(r report.Report) render.Nodes { return f(r) } +func (f renderFunc) Render(ctx context.Context, r report.Report) render.Nodes { return f(ctx, r) } func TestMemoise(t *testing.T) { calls := 0 - r := renderFunc(func(rpt report.Report) render.Nodes { + r := renderFunc(func(ctx context.Context, rpt report.Report) render.Nodes { calls++ return render.Nodes{Nodes: report.Nodes{rpt.ID: report.MakeNode(rpt.ID)}} }) @@ -27,7 +28,8 @@ func TestMemoise(t *testing.T) { rpt1 := report.MakeReport() - result1 := m.Render(rpt1) + ctx := context.Background() + result1 := m.Render(ctx, rpt1) // it should have rendered it. if _, ok := result1.Nodes[rpt1.ID]; !ok { t.Errorf("Expected rendered report to contain a node, but got: %v", result1) @@ -36,7 +38,7 @@ func TestMemoise(t *testing.T) { t.Errorf("Expected renderer to have been called the first time") } - result2 := m.Render(rpt1) + result2 := m.Render(ctx, rpt1) if !reflect.DeepEqual(result1, result2) { t.Errorf("Expected memoised result to be returned: %s", test.Diff(result1, result2)) } @@ -45,7 +47,7 @@ func TestMemoise(t *testing.T) { } rpt2 := report.MakeReport() - result3 := m.Render(rpt2) + result3 := m.Render(ctx, rpt2) if reflect.DeepEqual(result1, result3) { t.Errorf("Expected different result for different report, but were the same") } @@ -54,7 +56,7 @@ func TestMemoise(t *testing.T) { } render.ResetCache() - result4 := m.Render(rpt1) + result4 := m.Render(ctx, rpt1) if !reflect.DeepEqual(result1, result4) { t.Errorf("Expected original result to be returned: %s", test.Diff(result1, result4)) } diff --git a/render/metrics.go b/render/metrics.go index 92566519b2..2658cdd44a 100644 --- a/render/metrics.go +++ b/render/metrics.go @@ -1,6 +1,8 @@ package render import ( + "context" + "github.com/weaveworks/scope/report" ) @@ -17,8 +19,8 @@ type propagateSingleMetrics struct { r Renderer } -func (p propagateSingleMetrics) Render(rpt report.Report) Nodes { - nodes := p.r.Render(rpt) +func (p propagateSingleMetrics) Render(ctx context.Context, rpt report.Report) Nodes { + nodes := p.r.Render(ctx, rpt) outputs := make(report.Nodes, len(nodes.Nodes)) for id, n := range nodes.Nodes { var first report.Node diff --git a/render/metrics_test.go b/render/metrics_test.go index f604d2fabd..5e6f74e31e 100644 --- a/render/metrics_test.go +++ b/render/metrics_test.go @@ -1,6 +1,7 @@ package render_test import ( + "context" "testing" "time" @@ -159,7 +160,7 @@ func TestPropagateSingleMetrics(t *testing.T) { }, }, } { - got := render.PropagateSingleMetrics(c.topology, mockRenderer{report.Nodes{c.input.ID: c.input}}).Render(report.Report{}).Nodes + got := render.PropagateSingleMetrics(c.topology, mockRenderer{report.Nodes{c.input.ID: c.input}}).Render(context.Background(), report.Report{}).Nodes if !reflect.DeepEqual(got, c.output) { t.Errorf("[%s] Diff: %s", c.name, test.Diff(c.output, got)) } diff --git a/render/persistentvolume.go b/render/persistentvolume.go index 573c43c82b..946ace8ada 100644 --- a/render/persistentvolume.go +++ b/render/persistentvolume.go @@ -1,6 +1,8 @@ package render import ( + "context" + "github.com/weaveworks/scope/probe/kubernetes" "github.com/weaveworks/scope/report" ) @@ -23,7 +25,7 @@ var VolumesRenderer = volumesRenderer{} type volumesRenderer struct{} // Render renders PV & PVC nodes along with adjacency -func (v volumesRenderer) Render(rpt report.Report) Nodes { +func (v volumesRenderer) Render(ctx context.Context, rpt report.Report) Nodes { nodes := make(report.Nodes) for id, n := range rpt.PersistentVolumeClaim.Nodes { volume, _ := n.Latest.Lookup(kubernetes.VolumeName) @@ -48,7 +50,7 @@ var PodToVolumeRenderer = podToVolumesRenderer{} type podToVolumesRenderer struct{} // Render renders the Pod nodes having volumes adjacency. -func (v podToVolumesRenderer) Render(rpt report.Report) Nodes { +func (v podToVolumesRenderer) Render(ctx context.Context, rpt report.Report) Nodes { nodes := make(report.Nodes) for podID, podNode := range rpt.Pod.Nodes { ClaimName, _ := podNode.Latest.Lookup(kubernetes.VolumeClaim) @@ -72,7 +74,7 @@ var PVCToStorageClassRenderer = pvcToStorageClassRenderer{} type pvcToStorageClassRenderer struct{} // Render renders the PVC & Storage Class nodes with adjacency. -func (v pvcToStorageClassRenderer) Render(rpt report.Report) Nodes { +func (v pvcToStorageClassRenderer) Render(ctx context.Context, rpt report.Report) Nodes { nodes := make(report.Nodes) for scID, scNode := range rpt.StorageClass.Nodes { storageClass, _ := scNode.Latest.Lookup(kubernetes.Name) @@ -95,7 +97,7 @@ var PVToSnapshotRenderer = pvToSnapshotRenderer{} type pvToSnapshotRenderer struct{} //Render renders the PV & Snapshot nodes with adjacency. -func (v pvToSnapshotRenderer) Render(rpt report.Report) Nodes { +func (v pvToSnapshotRenderer) Render(ctx context.Context, rpt report.Report) Nodes { nodes := make(report.Nodes) for pvNodeID, p := range rpt.PersistentVolume.Nodes { volumeName, _ := p.Latest.Lookup(kubernetes.Name) @@ -119,7 +121,7 @@ type volumeSnapshotRenderer struct{} // Render renders the volumeSnapshots & volumeSnapshotData with adjacency // It checks for the volumeSnapshotData name in volumeSnapshot, adjacency is created by matching the volumeSnapshotData name. -func (v volumeSnapshotRenderer) Render(rpt report.Report) Nodes { +func (v volumeSnapshotRenderer) Render(ctx context.Context, rpt report.Report) Nodes { nodes := make(report.Nodes) for volumeSnapshotID, volumeSnapshotNode := range rpt.VolumeSnapshot.Nodes { snapshotData, _ := volumeSnapshotNode.Latest.Lookup(kubernetes.SnapshotData) diff --git a/render/pod.go b/render/pod.go index 49b97be876..7d8e489a29 100644 --- a/render/pod.go +++ b/render/pod.go @@ -1,6 +1,7 @@ package render import ( + "context" "strings" "github.com/weaveworks/scope/probe/docker" @@ -162,8 +163,8 @@ type Map2Parent struct { } // Render implements Renderer -func (m Map2Parent) Render(rpt report.Report) Nodes { - input := m.chainRenderer.Render(rpt) +func (m Map2Parent) Render(ctx context.Context, rpt report.Report) Nodes { + input := m.chainRenderer.Render(ctx, rpt) ret := newJoinResults(nil) for _, n := range input.Nodes { diff --git a/render/pod_test.go b/render/pod_test.go index d707110d39..c6dcd6c9a8 100644 --- a/render/pod_test.go +++ b/render/pod_test.go @@ -1,6 +1,7 @@ package render_test import ( + "context" "testing" "github.com/weaveworks/common/test" @@ -13,7 +14,7 @@ import ( ) func TestPodRenderer(t *testing.T) { - have := utils.Prune(render.PodRenderer.Render(fixture.Report).Nodes) + have := utils.Prune(render.PodRenderer.Render(context.Background(), fixture.Report).Nodes) want := utils.Prune(expected.RenderedPods) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) @@ -33,7 +34,7 @@ func TestPodFilterRenderer(t *testing.T) { kubernetes.Namespace: "kube-system", }) - have := utils.Prune(render.Render(input, render.PodRenderer, filterNonKubeSystem).Nodes) + have := utils.Prune(render.Render(context.Background(), input, render.PodRenderer, filterNonKubeSystem).Nodes) want := utils.Prune(expected.RenderedPods.Copy()) delete(want, fixture.ClientPodNodeID) if !reflect.DeepEqual(want, have) { @@ -42,7 +43,7 @@ func TestPodFilterRenderer(t *testing.T) { } func TestPodServiceRenderer(t *testing.T) { - have := utils.Prune(render.PodServiceRenderer.Render(fixture.Report).Nodes) + have := utils.Prune(render.PodServiceRenderer.Render(context.Background(), fixture.Report).Nodes) want := utils.Prune(expected.RenderedPodServices) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) @@ -57,7 +58,7 @@ func TestPodServiceFilterRenderer(t *testing.T) { kubernetes.Namespace: "kube-system", }) - have := utils.Prune(render.Render(input, render.PodServiceRenderer, filterNonKubeSystem).Nodes) + have := utils.Prune(render.Render(context.Background(), input, render.PodServiceRenderer, filterNonKubeSystem).Nodes) want := utils.Prune(expected.RenderedPodServices.Copy()) delete(want, fixture.ServiceNodeID) delete(want, render.IncomingInternetID) diff --git a/render/process.go b/render/process.go index 37e994133d..b3a841f347 100644 --- a/render/process.go +++ b/render/process.go @@ -1,6 +1,8 @@ package render import ( + "context" + "github.com/weaveworks/scope/probe/endpoint" "github.com/weaveworks/scope/probe/process" "github.com/weaveworks/scope/report" @@ -43,11 +45,11 @@ var ProcessNameRenderer = ColorConnected(CustomRenderer{RenderFunc: processes2Na type endpoints2Processes struct { } -func (e endpoints2Processes) Render(rpt report.Report) Nodes { +func (e endpoints2Processes) Render(ctx context.Context, rpt report.Report) Nodes { if len(rpt.Process.Nodes) == 0 { return Nodes{} } - endpoints := SelectEndpoint.Render(rpt).Nodes + endpoints := SelectEndpoint.Render(ctx, rpt).Nodes return MapEndpoints( func(n report.Node) string { pid, ok := n.Latest.Lookup(process.PID) @@ -62,7 +64,7 @@ func (e endpoints2Processes) Render(rpt report.Report) Nodes { return "" } return report.MakeProcessNodeID(hostID, pid) - }, report.Process).Render(rpt) + }, report.Process).Render(ctx, rpt) } // When there is more than one connection originating from a source diff --git a/render/process_test.go b/render/process_test.go index cdef54a15c..eb515c9f5d 100644 --- a/render/process_test.go +++ b/render/process_test.go @@ -1,6 +1,7 @@ package render_test import ( + "context" "testing" "github.com/weaveworks/common/test" @@ -12,7 +13,7 @@ import ( ) func TestEndpointRenderer(t *testing.T) { - have := utils.Prune(render.EndpointRenderer.Render(fixture.Report).Nodes) + have := utils.Prune(render.EndpointRenderer.Render(context.Background(), fixture.Report).Nodes) want := utils.Prune(expected.RenderedEndpoints) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) @@ -20,7 +21,7 @@ func TestEndpointRenderer(t *testing.T) { } func TestProcessRenderer(t *testing.T) { - have := utils.Prune(render.ProcessRenderer.Render(fixture.Report).Nodes) + have := utils.Prune(render.ProcessRenderer.Render(context.Background(), fixture.Report).Nodes) want := utils.Prune(expected.RenderedProcesses) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) @@ -28,7 +29,7 @@ func TestProcessRenderer(t *testing.T) { } func TestProcessNameRenderer(t *testing.T) { - have := utils.Prune(render.ProcessNameRenderer.Render(fixture.Report).Nodes) + have := utils.Prune(render.ProcessNameRenderer.Render(context.Background(), fixture.Report).Nodes) want := utils.Prune(expected.RenderedProcessNames) if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) diff --git a/render/render.go b/render/render.go index ee2429d61b..a3c3d1b497 100644 --- a/render/render.go +++ b/render/render.go @@ -1,6 +1,11 @@ package render import ( + "context" + + opentracing "github.com/opentracing/opentracing-go" + otlog "github.com/opentracing/opentracing-go/log" + "github.com/weaveworks/scope/report" ) @@ -13,7 +18,7 @@ type MapFunc func(report.Node) report.Node // Renderer is something that can render a report to a set of Nodes. type Renderer interface { - Render(report.Report) Nodes + Render(context.Context, report.Report) Nodes } // Nodes is the result of Rendering @@ -48,8 +53,10 @@ func (ts Transformers) Transform(nodes Nodes) Nodes { } // Render renders the report and then transforms it -func Render(rpt report.Report, renderer Renderer, transformer Transformer) Nodes { - return transformer.Transform(renderer.Render(rpt)) +func Render(ctx context.Context, rpt report.Report, renderer Renderer, transformer Transformer) Nodes { + span, ctx := opentracing.StartSpanFromContext(ctx, "Render:"+typeName(renderer)) + defer span.Finish() + return transformer.Transform(renderer.Render(ctx, rpt)) } // Reduce renderer is a Renderer which merges together the output of several @@ -62,7 +69,9 @@ func MakeReduce(renderers ...Renderer) Renderer { } // Render produces a set of Nodes given a Report. -func (r Reduce) Render(rpt report.Report) Nodes { +func (r Reduce) Render(ctx context.Context, rpt report.Report) Nodes { + span, ctx := opentracing.StartSpanFromContext(ctx, "Reduce.Render") + defer span.Finish() l := len(r) switch l { case 0: @@ -72,7 +81,9 @@ func (r Reduce) Render(rpt report.Report) Nodes { for _, renderer := range r { renderer := renderer // Pike!! go func() { - c <- renderer.Render(rpt) + span, ctx := opentracing.StartSpanFromContext(ctx, typeName(renderer)) + c <- renderer.Render(ctx, rpt) + span.Finish() }() } for ; l > 1; l-- { @@ -98,9 +109,11 @@ func MakeMap(f MapFunc, r Renderer) Renderer { // Render transforms a set of Nodes produces by another Renderer. // using a map function -func (m Map) Render(rpt report.Report) Nodes { +func (m Map) Render(ctx context.Context, rpt report.Report) Nodes { + span, ctx := opentracing.StartSpanFromContext(ctx, "Map.Render:"+functionName(m.MapFunc)) + defer span.Finish() var ( - input = m.Renderer.Render(rpt) + input = m.Renderer.Render(ctx, rpt) output = newJoinResults(nil) ) @@ -111,6 +124,8 @@ func (m Map) Render(rpt report.Report) Nodes { output.add(inRenderable.ID, outRenderable) } } + span.LogFields(otlog.Int("input.nodes", len(input.Nodes)), + otlog.Int("ouput.nodes", len(output.nodes))) return output.result(input) } @@ -129,9 +144,9 @@ func ConditionalRenderer(c Condition, r Renderer) Renderer { return conditionalRenderer{c, r} } -func (cr conditionalRenderer) Render(rpt report.Report) Nodes { +func (cr conditionalRenderer) Render(ctx context.Context, rpt report.Report) Nodes { if cr.Condition(rpt) { - return cr.Renderer.Render(rpt) + return cr.Renderer.Render(ctx, rpt) } return Nodes{} } diff --git a/render/render_test.go b/render/render_test.go index faf24e419d..34be8ace3f 100644 --- a/render/render_test.go +++ b/render/render_test.go @@ -1,6 +1,7 @@ package render_test import ( + "context" "reflect" "testing" @@ -13,7 +14,7 @@ type mockRenderer struct { report.Nodes } -func (m mockRenderer) Render(rpt report.Report) render.Nodes { +func (m mockRenderer) Render(_ context.Context, rpt report.Report) render.Nodes { return render.Nodes{Nodes: m.Nodes} } @@ -27,7 +28,7 @@ func TestReduceRender(t *testing.T) { "foo": report.MakeNode("foo"), "bar": report.MakeNode("bar"), } - have := renderer.Render(report.MakeReport()).Nodes + have := renderer.Render(context.Background(), report.MakeReport()).Nodes if !reflect.DeepEqual(want, have) { t.Errorf("want %+v, have %+v", want, have) } @@ -44,7 +45,7 @@ func TestMapRender1(t *testing.T) { }}, } want := report.Nodes{} - have := mapper.Render(report.MakeReport()).Nodes + have := mapper.Render(context.Background(), report.MakeReport()).Nodes if !reflect.DeepEqual(want, have) { t.Errorf("want %+v, have %+v", want, have) } @@ -64,7 +65,7 @@ func TestMapRender2(t *testing.T) { want := report.Nodes{ "bar": report.MakeNode("bar"), } - have := mapper.Render(report.MakeReport()).Nodes + have := mapper.Render(context.Background(), report.MakeReport()).Nodes if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } @@ -86,7 +87,7 @@ func TestMapRender3(t *testing.T) { "_foo": report.MakeNode("_foo").WithAdjacent("_baz"), "_baz": report.MakeNode("_baz").WithAdjacent("_foo"), } - have := mapper.Render(report.MakeReport()).Nodes + have := mapper.Render(context.Background(), report.MakeReport()).Nodes if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } diff --git a/render/selectors.go b/render/selectors.go index 0b995c38df..22856fdfd8 100644 --- a/render/selectors.go +++ b/render/selectors.go @@ -1,6 +1,8 @@ package render import ( + "context" + "github.com/weaveworks/scope/report" ) @@ -9,7 +11,7 @@ import ( type TopologySelector string // Render implements Renderer -func (t TopologySelector) Render(r report.Report) Nodes { +func (t TopologySelector) Render(ctx context.Context, r report.Report) Nodes { topology, _ := r.Topology(string(t)) return Nodes{Nodes: topology.Nodes} } diff --git a/render/short_lived_connections_test.go b/render/short_lived_connections_test.go index 214344f3f3..673fdc5dd3 100644 --- a/render/short_lived_connections_test.go +++ b/render/short_lived_connections_test.go @@ -1,6 +1,7 @@ package render_test import ( + "context" "fmt" "testing" @@ -109,7 +110,7 @@ var ( ) func TestShortLivedInternetNodeConnections(t *testing.T) { - have := utils.Prune(render.ContainerWithImageNameRenderer.Render(rpt).Nodes) + have := utils.Prune(render.ContainerWithImageNameRenderer.Render(context.Background(), rpt).Nodes) // Conntracked-only connections from the internet should be assigned to the internet pseudonode internet, ok := have[render.IncomingInternetID] @@ -123,7 +124,7 @@ func TestShortLivedInternetNodeConnections(t *testing.T) { } func TestPauseContainerDiscarded(t *testing.T) { - have := utils.Prune(render.ContainerWithImageNameRenderer.Render(rpt).Nodes) + have := utils.Prune(render.ContainerWithImageNameRenderer.Render(context.Background(), rpt).Nodes) // There should only be a connection from container1 and the destination should be container2 container1, ok := have[container1NodeID] if !ok {