diff --git a/app/api_topologies.go b/app/api_topologies.go index 14d31324d..4fa783486 100644 --- a/app/api_topologies.go +++ b/app/api_topologies.go @@ -11,6 +11,7 @@ import ( "time" "github.com/gorilla/mux" + opentracing "github.com/opentracing/opentracing-go" log "github.com/sirupsen/logrus" "github.com/weaveworks/scope/probe/docker" @@ -475,6 +476,8 @@ func (r *Registry) makeTopologyList(rep Reporter) CtxHandlerFunc { } 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) { @@ -490,6 +493,8 @@ func (r *Registry) renderTopologies(ctx context.Context, rpt report.Report, req } 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 diff --git a/app/multitenant/aws_collector.go b/app/multitenant/aws_collector.go index 4bb404c8a..4406b579e 100644 --- a/app/multitenant/aws_collector.go +++ b/app/multitenant/aws_collector.go @@ -15,6 +15,7 @@ import ( "github.com/aws/aws-sdk-go/service/dynamodb" "github.com/bluele/gcache" "github.com/nats-io/nats" + opentracing "github.com/opentracing/opentracing-go" "github.com/prometheus/client_golang/prometheus" log "github.com/sirupsen/logrus" @@ -336,10 +337,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 acb8c4f8e..5393c3141 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/detailed/summary.go b/render/detailed/summary.go index 6e1fb3bb5..7416ffdce 100644 --- a/render/detailed/summary.go +++ b/render/detailed/summary.go @@ -5,6 +5,8 @@ import ( "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" @@ -431,6 +433,9 @@ type NodeSummaries map[string]NodeSummary // Summaries converts RenderableNodes into a set of 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 { if summary, ok := MakeNodeSummary(rc, node); ok { diff --git a/render/func_name.go b/render/func_name.go new file mode 100644 index 000000000..63c768282 --- /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/render.go b/render/render.go index 6b1955a7c..a3c3d1b49 100644 --- a/render/render.go +++ b/render/render.go @@ -3,6 +3,9 @@ package render import ( "context" + opentracing "github.com/opentracing/opentracing-go" + otlog "github.com/opentracing/opentracing-go/log" + "github.com/weaveworks/scope/report" ) @@ -51,6 +54,8 @@ func (ts Transformers) Transform(nodes Nodes) Nodes { // Render renders the report and then transforms it 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)) } @@ -65,6 +70,8 @@ func MakeReduce(renderers ...Renderer) Renderer { // Render produces a set of Nodes given a Report. 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: @@ -74,7 +81,9 @@ func (r Reduce) Render(ctx context.Context, rpt report.Report) Nodes { for _, renderer := range r { renderer := renderer // Pike!! go func() { + span, ctx := opentracing.StartSpanFromContext(ctx, typeName(renderer)) c <- renderer.Render(ctx, rpt) + span.Finish() }() } for ; l > 1; l-- { @@ -101,6 +110,8 @@ 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(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(ctx, rpt) output = newJoinResults(nil) @@ -113,6 +124,8 @@ func (m Map) Render(ctx context.Context, 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) }