Skip to content

Commit

Permalink
Revert "Avoid global by passing metricsGraphURL down"
Browse files Browse the repository at this point in the history
This reverts commit 1a00288.
  • Loading branch information
rndstr committed Aug 1, 2017
1 parent 1cfebb5 commit 4e73801
Show file tree
Hide file tree
Showing 13 changed files with 80 additions and 60 deletions.
2 changes: 1 addition & 1 deletion app/api_report_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (

func topologyServer() *httptest.Server {
router := mux.NewRouter().SkipClean(true)
app.RegisterTopologyRoutes(router, app.StaticCollector(fixture.Report), map[string]bool{"foo_capability": true}, "")
app.RegisterTopologyRoutes(router, app.StaticCollector(fixture.Report), map[string]bool{"foo_capability": true})
return httptest.NewServer(router)
}

Expand Down
12 changes: 6 additions & 6 deletions app/api_topologies.go
Original file line number Diff line number Diff line change
Expand Up @@ -548,17 +548,17 @@ func (r *Registry) RendererForTopology(topologyID string, values url.Values, rpt
return topology.renderer, nil, nil
}

type reporterHandler func(context.Context, Reporter, string, http.ResponseWriter, *http.Request)
type reporterHandler func(context.Context, Reporter, http.ResponseWriter, *http.Request)

func captureReporter(rep Reporter, metricsGraphURL string, f reporterHandler) CtxHandlerFunc {
func captureReporter(rep Reporter, f reporterHandler) CtxHandlerFunc {
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
f(ctx, rep, metricsGraphURL, w, r)
f(ctx, rep, w, r)
}
}

type rendererHandler func(context.Context, render.Renderer, render.Decorator, report.Report, string, http.ResponseWriter, *http.Request)
type rendererHandler func(context.Context, render.Renderer, render.Decorator, report.Report, http.ResponseWriter, *http.Request)

func (r *Registry) captureRenderer(rep Reporter, metricGraphsURL string, f rendererHandler) CtxHandlerFunc {
func (r *Registry) captureRenderer(rep Reporter, f rendererHandler) CtxHandlerFunc {
return func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
var (
topologyID = mux.Vars(req)["topology"]
Expand All @@ -579,6 +579,6 @@ func (r *Registry) captureRenderer(rep Reporter, metricGraphsURL string, f rende
respondWith(w, http.StatusInternalServerError, err)
return
}
f(ctx, renderer, decorator, rpt, metricGraphsURL, w, req)
f(ctx, renderer, decorator, rpt, w, req)
}
}
4 changes: 2 additions & 2 deletions app/api_topologies_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,14 +183,14 @@ func getTestContainerLabelFilterTopologySummary(t *testing.T, exclude bool) (det
return nil, err
}

return detailed.Summaries(fixture.Report, renderer.Render(fixture.Report, decorator), ""), nil
return detailed.Summaries(fixture.Report, renderer.Render(fixture.Report, decorator)), nil
}

func TestAPITopologyAddsKubernetes(t *testing.T) {
router := mux.NewRouter()
c := app.NewCollector(1 * time.Minute)
app.RegisterReportPostHandler(c, router)
app.RegisterTopologyRoutes(router, c, map[string]bool{"foo_capability": true}, "")
app.RegisterTopologyRoutes(router, c, map[string]bool{"foo_capability": true})
ts := httptest.NewServer(router)
defer ts.Close()

Expand Down
11 changes: 5 additions & 6 deletions app/api_topology.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ type APINode struct {
}

// Full topology.
func handleTopology(ctx context.Context, renderer render.Renderer, decorator render.Decorator, report report.Report, metricsGraphURL string, w http.ResponseWriter, r *http.Request) {
func handleTopology(ctx context.Context, renderer render.Renderer, decorator render.Decorator, report report.Report, w http.ResponseWriter, r *http.Request) {
respondWith(w, http.StatusOK, APITopology{
Nodes: detailed.Summaries(report, renderer.Render(report, decorator), metricsGraphURL),
Nodes: detailed.Summaries(report, renderer.Render(report, decorator)),
})
}

// Individual nodes.
func handleNode(ctx context.Context, renderer render.Renderer, decorator render.Decorator, report report.Report, metricsGraphURL string, w http.ResponseWriter, r *http.Request) {
func handleNode(ctx context.Context, renderer render.Renderer, decorator render.Decorator, report report.Report, w http.ResponseWriter, r *http.Request) {
var (
vars = mux.Vars(r)
topologyID = vars["topology"]
Expand All @@ -49,14 +49,13 @@ func handleNode(ctx context.Context, renderer render.Renderer, decorator render.
http.NotFound(w, r)
return
}
respondWith(w, http.StatusOK, APINode{Node: detailed.MakeNode(topologyID, report, rendered, node, metricsGraphURL)})
respondWith(w, http.StatusOK, APINode{Node: detailed.MakeNode(topologyID, report, rendered, node)})
}

// Websocket for the full topology.
func handleWebsocket(
ctx context.Context,
rep Reporter,
metricsGraphURL string,
w http.ResponseWriter,
r *http.Request,
) {
Expand Down Expand Up @@ -124,7 +123,7 @@ func handleWebsocket(
log.Errorf("Error generating report: %v", err)
return
}
newTopo := detailed.Summaries(report, renderer.Render(report, decorator), metricsGraphURL)
newTopo := detailed.Summaries(report, renderer.Render(report, decorator))
diff := detailed.TopoDiff(previousTopo, newTopo)
previousTopo = newTopo

Expand Down
8 changes: 4 additions & 4 deletions app/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,23 +91,23 @@ func gzipHandler(h http.HandlerFunc) http.HandlerFunc {
}

// RegisterTopologyRoutes registers the various topology routes with a http mux.
func RegisterTopologyRoutes(router *mux.Router, r Reporter, capabilities map[string]bool, metricsGraphURL string) {
func RegisterTopologyRoutes(router *mux.Router, r Reporter, capabilities map[string]bool) {
get := router.Methods("GET").Subrouter()
get.HandleFunc("/api",
gzipHandler(requestContextDecorator(apiHandler(r, capabilities))))
get.HandleFunc("/api/topology",
gzipHandler(requestContextDecorator(topologyRegistry.makeTopologyList(r))))
get.
HandleFunc("/api/topology/{topology}",
gzipHandler(requestContextDecorator(topologyRegistry.captureRenderer(r, metricsGraphURL, handleTopology)))).
gzipHandler(requestContextDecorator(topologyRegistry.captureRenderer(r, handleTopology)))).
Name("api_topology_topology")
get.
HandleFunc("/api/topology/{topology}/ws",
requestContextDecorator(captureReporter(r, metricsGraphURL, handleWebsocket))). // NB not gzip!
requestContextDecorator(captureReporter(r, handleWebsocket))). // NB not gzip!
Name("api_topology_topology_ws")
get.
MatcherFunc(URLMatcher("/api/topology/{topology}/{id}")).HandlerFunc(
gzipHandler(requestContextDecorator(topologyRegistry.captureRenderer(r, metricsGraphURL, handleNode)))).
gzipHandler(requestContextDecorator(topologyRegistry.captureRenderer(r, handleNode)))).
Name("api_topology_topology_id")
get.HandleFunc("/api/report",
gzipHandler(requestContextDecorator(makeRawReportHandler(r))))
Expand Down
8 changes: 5 additions & 3 deletions prog/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/weaveworks/scope/common/weave"
"github.com/weaveworks/scope/common/xfer"
"github.com/weaveworks/scope/probe/docker"
"github.com/weaveworks/scope/render/detailed"
"github.com/weaveworks/weave/common"
)

Expand All @@ -51,7 +52,7 @@ func init() {
}

// Router creates the mux for all the various app components.
func router(collector app.Collector, controlRouter app.ControlRouter, pipeRouter app.PipeRouter, externalUI bool, capabilities map[string]bool, metricsGraphURL string) http.Handler {
func router(collector app.Collector, controlRouter app.ControlRouter, pipeRouter app.PipeRouter, externalUI bool, capabilities map[string]bool) http.Handler {
router := mux.NewRouter().SkipClean(true)

// We pull in the http.DefaultServeMux to get the pprof routes
Expand All @@ -61,7 +62,7 @@ func router(collector app.Collector, controlRouter app.ControlRouter, pipeRouter
app.RegisterReportPostHandler(collector, router)
app.RegisterControlRoutes(router, controlRouter)
app.RegisterPipeRoutes(router, pipeRouter)
app.RegisterTopologyRoutes(router, collector, capabilities, metricsGraphURL)
app.RegisterTopologyRoutes(router, collector, capabilities)

uiHandler := http.FileServer(GetFS(externalUI))
router.PathPrefix("/ui").Name("static").Handler(
Expand Down Expand Up @@ -216,6 +217,7 @@ func appMain(flags appFlags) {
setLogLevel(flags.logLevel)
setLogFormatter(flags.logPrefix)
runtime.SetBlockProfileRate(flags.blockProfileRate)
detailed.SetMetricsGraphURL(flags.metricsGraphURL)

defer log.Info("app exiting")
rand.Seed(time.Now().UnixNano())
Expand Down Expand Up @@ -297,7 +299,7 @@ func appMain(flags appFlags) {
capabilities := map[string]bool{
xfer.HistoricReportsCapability: collector.HasHistoricReports(),
}
handler := router(collector, controlRouter, pipeRouter, flags.externalUI, capabilities, flags.metricsGraphURL)
handler := router(collector, controlRouter, pipeRouter, flags.externalUI, capabilities)
if flags.logHTTP {
handler = middleware.Log{
LogRequestHeaders: flags.logHTTPHeaders,
Expand Down
12 changes: 6 additions & 6 deletions render/detailed/connections.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,13 @@ func internetAddr(node report.Node, ep report.Node) (string, bool) {
return addr, true
}

func (c *connectionCounters) rows(r report.Report, ns report.Nodes, includeLocal bool, metricsGraphURL string) []Connection {
func (c *connectionCounters) rows(r report.Report, ns report.Nodes, includeLocal bool) []Connection {
output := []Connection{}
for row, count := range c.counts {
// Use MakeNodeSummary to render the id and label of this node
// TODO(paulbellamy): Would be cleaner if we hade just a
// MakeNodeID(ns[row.remoteNodeID]). As we don't need the whole summary.
summary, _ := MakeNodeSummary(r, ns[row.remoteNodeID], metricsGraphURL)
summary, _ := MakeNodeSummary(r, ns[row.remoteNodeID])
connection := Connection{
ID: fmt.Sprintf("%s-%s-%s-%s", row.remoteNodeID, row.remoteAddr, row.localAddr, row.port),
NodeID: summary.ID,
Expand Down Expand Up @@ -162,7 +162,7 @@ func (c *connectionCounters) rows(r report.Report, ns report.Nodes, includeLocal
return output
}

func incomingConnectionsSummary(topologyID string, r report.Report, n report.Node, ns report.Nodes, metricsGraphURL string) ConnectionsSummary {
func incomingConnectionsSummary(topologyID string, r report.Report, n report.Node, ns report.Nodes) ConnectionsSummary {
localEndpointIDs, localEndpointIDCopies := endpointChildIDsAndCopyMapOf(n)
counts := newConnectionCounters()

Expand All @@ -188,11 +188,11 @@ func incomingConnectionsSummary(topologyID string, r report.Report, n report.Nod
TopologyID: topologyID,
Label: "Inbound",
Columns: columnHeaders,
Connections: counts.rows(r, ns, isInternetNode(n), metricsGraphURL),
Connections: counts.rows(r, ns, isInternetNode(n)),
}
}

func outgoingConnectionsSummary(topologyID string, r report.Report, n report.Node, ns report.Nodes, metricsGraphURL string) ConnectionsSummary {
func outgoingConnectionsSummary(topologyID string, r report.Report, n report.Node, ns report.Nodes) ConnectionsSummary {
localEndpoints := endpointChildrenOf(n)
counts := newConnectionCounters()

Expand Down Expand Up @@ -220,7 +220,7 @@ func outgoingConnectionsSummary(topologyID string, r report.Report, n report.Nod
TopologyID: topologyID,
Label: "Outbound",
Columns: columnHeaders,
Connections: counts.rows(r, ns, isInternetNode(n), metricsGraphURL),
Connections: counts.rows(r, ns, isInternetNode(n)),
}
}

Expand Down
19 changes: 15 additions & 4 deletions render/detailed/links.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ import (
const urlQueryVarName = ":query"

var (
// As configured by the user
metricsGraphURL = ""

// Metadata for shown queries
shownQueries = []struct {
ID string
Expand Down Expand Up @@ -94,9 +97,17 @@ var (
}
)

// SetMetricsGraphURL sets the URL we deduce our eventual metric link from.
// Supports placeholders such as `:orgID` and `:query`. An empty url disables
// this feature. If the `:query` part is missing, a JSON version will be
// appended, see `queryParamsAsJSON()` for more info.
func SetMetricsGraphURL(url string) {
metricsGraphURL = url
}

// 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) NodeSummary {
if metricsGraphURL == "" {
return summary
}
Expand Down Expand Up @@ -127,7 +138,7 @@ func RenderMetricURLs(summary NodeSummary, n report.Node, metricsGraphURL string
}

ms = append(ms, metric)
ms[len(ms)-1].URL = buildURL(bs.String(), metricsGraphURL)
ms[len(ms)-1].URL = buildURL(bs.String())
found[metric.ID] = struct{}{}
}

Expand All @@ -151,7 +162,7 @@ func RenderMetricURLs(summary NodeSummary, n report.Node, metricsGraphURL string
ms = append(ms, report.MetricRow{
ID: metadata.ID,
Label: metadata.Label,
URL: buildURL(bs.String(), metricsGraphURL),
URL: buildURL(bs.String()),
Metric: &report.Metric{},
Priority: maxprio,
ValueEmpty: true,
Expand All @@ -164,7 +175,7 @@ func RenderMetricURLs(summary NodeSummary, n report.Node, metricsGraphURL string
}

// buildURL puts together the URL by looking at the configured `metricsGraphURL`.
func buildURL(query, metricsGraphURL string) string {
func buildURL(query string) string {
if strings.Contains(metricsGraphURL, urlQueryVarName) {
return strings.Replace(metricsGraphURL, urlQueryVarName, url.QueryEscape(query), -1)
}
Expand Down
22 changes: 16 additions & 6 deletions render/detailed/links_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,27 @@ var (

func TestRenderMetricURLs_Disabled(t *testing.T) {
s := detailed.NodeSummary{Label: "foo", Metrics: sampleMetrics}
result := detailed.RenderMetricURLs(s, samplePodNode, "")
result := detailed.RenderMetricURLs(s, samplePodNode)

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

func TestRenderMetricURLs_UnknownTopology(t *testing.T) {
detailed.SetMetricsGraphURL(sampleMetricsGraphURL)
defer detailed.SetMetricsGraphURL("")
s := detailed.NodeSummary{Label: "foo", Metrics: sampleMetrics}
result := detailed.RenderMetricURLs(s, sampleUnknownNode, sampleMetricsGraphURL)
result := detailed.RenderMetricURLs(s, sampleUnknownNode)

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

func TestRenderMetricURLs(t *testing.T) {
detailed.SetMetricsGraphURL(sampleMetricsGraphURL)
defer detailed.SetMetricsGraphURL("")
s := detailed.NodeSummary{Label: "foo", Metrics: sampleMetrics}
result := detailed.RenderMetricURLs(s, samplePodNode, sampleMetricsGraphURL)
result := detailed.RenderMetricURLs(s, samplePodNode)

u := "/prom/:orgID/notebook/new/%7B%22cells%22%3A%5B%7B%22queries%22%3A%5B%22sum%28container_memory_usage_bytes%7Bpod_name%3D%5C%22foo%5C%22%7D%29%22%5D%7D%5D%7D"
assert.Equal(t, u, result.Metrics[0].URL)
Expand All @@ -50,7 +54,9 @@ func TestRenderMetricURLs(t *testing.T) {
}

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

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

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

assert.NotEmpty(t, result.Metrics[0].URL)
assert.False(t, result.Metrics[0].ValueEmpty)
Expand All @@ -81,8 +89,10 @@ func TestRenderMetricURLs_CombinedEmptyMetrics(t *testing.T) {
}

func TestRenderMetricURLs_QueryReplacement(t *testing.T) {
detailed.SetMetricsGraphURL("http://example.test/?q=:query")
defer detailed.SetMetricsGraphURL("")
s := detailed.NodeSummary{Label: "foo", Metrics: sampleMetrics}
result := detailed.RenderMetricURLs(s, samplePodNode, "http://example.test/?q=:query")
result := detailed.RenderMetricURLs(s, samplePodNode)

u := "http://example.test/?q=sum%28container_memory_usage_bytes%7Bpod_name%3D%22foo%22%7D%29"
assert.Equal(t, u, result.Metrics[0].URL)
Expand Down
14 changes: 7 additions & 7 deletions render/detailed/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,15 @@ func (c *ControlInstance) CodecDecodeSelf(decoder *codec.Decoder) {

// MakeNode transforms a renderable node to a detailed node. It uses
// aggregate metadata, plus the set of origin node IDs, to produce tables.
func MakeNode(topologyID string, r report.Report, ns report.Nodes, n report.Node, metricsGraphURL string) Node {
summary, _ := MakeNodeSummary(r, n, metricsGraphURL)
func MakeNode(topologyID string, r report.Report, ns report.Nodes, n report.Node) Node {
summary, _ := MakeNodeSummary(r, n)
return Node{
NodeSummary: summary,
Controls: controls(r, n),
Children: children(r, n, metricsGraphURL),
Children: children(r, n),
Connections: []ConnectionsSummary{
incomingConnectionsSummary(topologyID, r, n, ns, metricsGraphURL),
outgoingConnectionsSummary(topologyID, r, n, ns, metricsGraphURL),
incomingConnectionsSummary(topologyID, r, n, ns),
outgoingConnectionsSummary(topologyID, r, n, ns),
},
}
}
Expand Down Expand Up @@ -181,13 +181,13 @@ var nodeSummaryGroupSpecs = []struct {
},
}

func children(r report.Report, n report.Node, metricsGraphURL string) []NodeSummaryGroup {
func children(r report.Report, n report.Node) []NodeSummaryGroup {
summaries := map[string][]NodeSummary{}
n.Children.ForEach(func(child report.Node) {
if child.ID == n.ID {
return
}
summary, ok := MakeNodeSummary(r, child, metricsGraphURL)
summary, ok := MakeNodeSummary(r, child)
if !ok {
return
}
Expand Down
Loading

0 comments on commit 4e73801

Please sign in to comment.