diff --git a/render/detailed_node.go b/render/detailed_node.go index 80f718a89..59d8b6ac9 100644 --- a/render/detailed_node.go +++ b/render/detailed_node.go @@ -3,6 +3,7 @@ package render import ( "fmt" "reflect" + "sort" "strconv" "github.com/weaveworks/scope/probe/docker" @@ -12,7 +13,14 @@ import ( ) const ( - mb = 1 << 20 + mb = 1 << 20 + connectionsRank = 100 + containerImageRank = 4 + containerRank = 3 + processRank = 2 + hostRank = 1 + endpointRank = 0 // this is the least important table, so sort to bottom + addressRank = 0 // also least important; never merged with endpoints ) // DetailedNode is the data type that's yielded to the JavaScript layer when @@ -30,6 +38,7 @@ type DetailedNode struct { type Table struct { Title string `json:"title"` // e.g. Bandwidth Numeric bool `json:"numeric"` // should the major column be right-aligned? + Rank int `json:"-"` // used to sort tables; not emitted. Rows []Row `json:"rows"` } @@ -40,10 +49,16 @@ type Row struct { ValueMinor string `json:"value_minor,omitempty"` // e.g. KB/s } +type tables []Table + +func (t tables) Len() int { return len(t) } +func (t tables) Swap(i, j int) { t[i], t[j] = t[j], t[i] } +func (t tables) Less(i, j int) bool { return t[i].Rank > t[j].Rank } + // MakeDetailedNode transforms a renderable node to a detailed node. It uses // aggregate metadata, plus the set of origin node IDs, to produce tables. func MakeDetailedNode(r report.Report, n RenderableNode) DetailedNode { - tables := []Table{} + tables := tables{} { rows := []Row{} if val, ok := n.AggregateMetadata[KeyMaxConnCountTCP]; ok { @@ -56,7 +71,7 @@ func MakeDetailedNode(r report.Report, n RenderableNode) DetailedNode { rows = append(rows, Row{"Bytes egress", strconv.FormatInt(int64(val), 10), ""}) } if len(rows) > 0 { - tables = append(tables, Table{"Connections", true, rows}) + tables = append(tables, Table{"Connections", true, connectionsRank, rows}) } } @@ -77,6 +92,9 @@ outer: } } + // Sort tables by rank + sort.Sort(tables) + return DetailedNode{ ID: n.ID, LabelMajor: n.LabelMajor, @@ -124,6 +142,7 @@ func endpointOriginTable(nmd report.NodeMetadata) (Table, bool) { Title: "Origin Endpoint", Numeric: false, Rows: rows, + Rank: endpointRank, }, len(rows) > 0 } @@ -136,6 +155,7 @@ func addressOriginTable(nmd report.NodeMetadata) (Table, bool) { Title: "Origin Address", Numeric: false, Rows: rows, + Rank: addressRank, }, len(rows) > 0 } @@ -157,6 +177,7 @@ func processOriginTable(nmd report.NodeMetadata) (Table, bool) { Title: "Origin Process", Numeric: false, Rows: rows, + Rank: processRank, }, len(rows) > 0 } @@ -187,6 +208,7 @@ func containerOriginTable(nmd report.NodeMetadata) (Table, bool) { Title: "Origin Container", Numeric: false, Rows: rows, + Rank: containerRank, }, len(rows) > 0 } @@ -204,6 +226,7 @@ func containerImageOriginTable(nmd report.NodeMetadata) (Table, bool) { Title: "Origin Container Image", Numeric: false, Rows: rows, + Rank: containerImageRank, }, len(rows) > 0 } @@ -225,5 +248,6 @@ func hostOriginTable(nmd report.NodeMetadata) (Table, bool) { Title: "Origin Host", Numeric: false, Rows: rows, + Rank: hostRank, }, len(rows) > 0 } diff --git a/render/detailed_node_test.go b/render/detailed_node_test.go index eb2a3c617..a5ec42004 100644 --- a/render/detailed_node_test.go +++ b/render/detailed_node_test.go @@ -31,6 +31,7 @@ func TestOriginTable(t *testing.T) { serverProcessNodeID: { Title: "Origin Process", Numeric: false, + Rank: 2, Rows: []render.Row{ {"Name (comm)", "apache", ""}, {"PID", serverPID, ""}, @@ -39,6 +40,7 @@ func TestOriginTable(t *testing.T) { serverHostNodeID: { Title: "Origin Host", Numeric: false, + Rank: 1, Rows: []render.Row{ {"Host name", serverHostName, ""}, {"Load", "0.01 0.01 0.01", ""}, @@ -69,11 +71,41 @@ func TestMakeDetailedNode(t *testing.T) { { Title: "Connections", Numeric: true, + Rank: 100, Rows: []render.Row{ {"Bytes ingress", "150", ""}, {"Bytes egress", "1500", ""}, }, }, + { + Title: "Origin Container", + Numeric: false, + Rank: 3, + Rows: []render.Row{ + {"ID", "5e4d3c2b1a", ""}, + {"Name", "server", ""}, + {"Image ID", "imageid456", ""}, + }, + }, + { + Title: "Origin Process", + Numeric: false, + Rank: 2, + Rows: []render.Row{ + {"Name (comm)", "apache", ""}, + {"PID", "215", ""}, + }, + }, + { + Title: "Origin Host", + Numeric: false, + Rank: 1, + Rows: []render.Row{ + {"Host name", "server.hostname.com", ""}, + {"Load", "0.01 0.01 0.01", ""}, + {"Operating system", "Linux", ""}, + }, + }, { Title: "Origin Endpoint", Numeric: false, @@ -82,32 +114,6 @@ func TestMakeDetailedNode(t *testing.T) { {"Port", "80", ""}, }, }, - { - Title: "Origin Process", - Numeric: false, - Rows: []render.Row{ - {"Name (comm)", "apache", ""}, - {"PID", "215", ""}, - }, - }, - { - Title: "Origin Container", - Numeric: false, - Rows: []render.Row{ - {"ID", "5e4d3c2b1a", ""}, - {"Name", "server", ""}, - {"Image ID", "imageid456", ""}, - }, - }, - { - Title: "Origin Host", - Numeric: false, - Rows: []render.Row{ - {"Host name", "server.hostname.com", ""}, - {"Load", "0.01 0.01 0.01", ""}, - {"Operating system", "Linux", ""}, - }, - }, }, } if !reflect.DeepEqual(want, have) {