mirror of
https://github.com/weaveworks/scope.git
synced 2026-03-05 11:11:13 +00:00
Only group processes not in containers AND doing network IO into uncontained nodes.
This commit is contained in:
@@ -59,6 +59,7 @@ var (
|
||||
Adjacency: adjacency,
|
||||
Origins: report.MakeIDList(
|
||||
test.RandomClientNodeID,
|
||||
test.GoogleEndpointNodeID,
|
||||
),
|
||||
}
|
||||
}
|
||||
@@ -124,14 +125,15 @@ var (
|
||||
},
|
||||
nonContainerProcessID: {
|
||||
ID: nonContainerProcessID,
|
||||
LabelMajor: "bash",
|
||||
LabelMajor: test.NonContainerComm,
|
||||
LabelMinor: fmt.Sprintf("%s (%s)", test.ServerHostID, test.NonContainerPID),
|
||||
Rank: test.NonContainerComm,
|
||||
Pseudo: false,
|
||||
Adjacency: report.MakeIDList(),
|
||||
Adjacency: report.MakeIDList(render.TheInternetID),
|
||||
Origins: report.MakeIDList(
|
||||
test.NonContainerProcessNodeID,
|
||||
test.ServerHostNodeID,
|
||||
test.NonContainerNodeID,
|
||||
),
|
||||
NodeMetadata: report.MakeNodeMetadata(),
|
||||
EdgeMetadata: report.EdgeMetadata{},
|
||||
@@ -180,16 +182,17 @@ var (
|
||||
EgressByteCount: newu64(2100),
|
||||
},
|
||||
},
|
||||
"bash": {
|
||||
ID: "bash",
|
||||
LabelMajor: "bash",
|
||||
test.NonContainerComm: {
|
||||
ID: test.NonContainerComm,
|
||||
LabelMajor: test.NonContainerComm,
|
||||
LabelMinor: "1 process",
|
||||
Rank: "bash",
|
||||
Rank: test.NonContainerComm,
|
||||
Pseudo: false,
|
||||
Adjacency: report.MakeIDList(),
|
||||
Adjacency: report.MakeIDList(render.TheInternetID),
|
||||
Origins: report.MakeIDList(
|
||||
test.NonContainerProcessNodeID,
|
||||
test.ServerHostNodeID,
|
||||
test.NonContainerNodeID,
|
||||
),
|
||||
NodeMetadata: report.MakeNodeMetadata(),
|
||||
EdgeMetadata: report.EdgeMetadata{},
|
||||
@@ -246,10 +249,11 @@ var (
|
||||
LabelMinor: test.ServerHostName,
|
||||
Rank: "",
|
||||
Pseudo: true,
|
||||
Adjacency: report.MakeIDList(),
|
||||
Adjacency: report.MakeIDList(render.TheInternetID),
|
||||
Origins: report.MakeIDList(
|
||||
test.NonContainerProcessNodeID,
|
||||
test.ServerHostNodeID,
|
||||
test.NonContainerNodeID,
|
||||
),
|
||||
NodeMetadata: report.MakeNodeMetadata(),
|
||||
EdgeMetadata: report.EdgeMetadata{},
|
||||
@@ -305,8 +309,9 @@ var (
|
||||
LabelMinor: test.ServerHostName,
|
||||
Rank: "",
|
||||
Pseudo: true,
|
||||
Adjacency: report.MakeIDList(),
|
||||
Adjacency: report.MakeIDList(render.TheInternetID),
|
||||
Origins: report.MakeIDList(
|
||||
test.NonContainerNodeID,
|
||||
test.NonContainerProcessNodeID,
|
||||
test.ServerHostNodeID,
|
||||
),
|
||||
|
||||
@@ -269,27 +269,79 @@ func (m LeafMap) EdgeMetadata(rpt report.Report, srcRenderableID, dstRenderableI
|
||||
return metadata
|
||||
}
|
||||
|
||||
// FilterUnconnected is a Renderer which filters out unconnected nodes.
|
||||
type FilterUnconnected struct {
|
||||
// CustomRenderer allow for mapping functions that recived the entire topology
|
||||
// in one call - useful for functions that need to consider the entire graph
|
||||
type CustomRenderer struct {
|
||||
RenderFunc func(RenderableNodes) RenderableNodes
|
||||
Renderer
|
||||
}
|
||||
|
||||
// Render produces a set of RenderableNodes given a Report
|
||||
func (f FilterUnconnected) Render(rpt report.Report) RenderableNodes {
|
||||
return OnlyConnected(f.Renderer.Render(rpt))
|
||||
// Render implements Renderer
|
||||
func (c CustomRenderer) Render(rpt report.Report) RenderableNodes {
|
||||
return c.RenderFunc(c.Renderer.Render(rpt))
|
||||
}
|
||||
|
||||
// IsConnected is the key added to NodeMetadata by ColorConnected
|
||||
// to indicate a node has an edge pointing to it or from it
|
||||
const IsConnected = "is_connected"
|
||||
|
||||
// OnlyConnected filters out unconnected RenderedNodes
|
||||
func OnlyConnected(input RenderableNodes) RenderableNodes {
|
||||
output := RenderableNodes{}
|
||||
for id, node := range ColorConnected(input) {
|
||||
if _, ok := node.NodeMetadata.Metadata[IsConnected]; ok {
|
||||
output[id] = node
|
||||
}
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
// FilterUnconnected produces a renderer that filters unconnected nodes
|
||||
// from the given renderer
|
||||
func FilterUnconnected(r Renderer) Renderer {
|
||||
return CustomRenderer{
|
||||
RenderFunc: OnlyConnected,
|
||||
Renderer: r,
|
||||
}
|
||||
}
|
||||
|
||||
// ColorConnected colors nodes with the IsConnected key if
|
||||
// they have edges to or from them.
|
||||
func ColorConnected(input RenderableNodes) RenderableNodes {
|
||||
connected := map[string]struct{}{}
|
||||
void := struct{}{}
|
||||
|
||||
for id, node := range input {
|
||||
if len(node.Adjacency) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
output[id] = node
|
||||
connected[id] = void
|
||||
for _, id := range node.Adjacency {
|
||||
output[id] = input[id]
|
||||
connected[id] = void
|
||||
}
|
||||
}
|
||||
|
||||
for id := range connected {
|
||||
node := input[id]
|
||||
node.NodeMetadata.Metadata[IsConnected] = "true"
|
||||
input[id] = node
|
||||
}
|
||||
return input
|
||||
}
|
||||
|
||||
// Filter removes nodes from a view based on a predicate.
|
||||
type Filter struct {
|
||||
Renderer
|
||||
f func(RenderableNode) bool
|
||||
}
|
||||
|
||||
// Render implements Renderer
|
||||
func (f Filter) Render(rpt report.Report) RenderableNodes {
|
||||
output := RenderableNodes{}
|
||||
for id, node := range f.Renderer.Render(rpt) {
|
||||
if f.f(node) {
|
||||
output[id] = node
|
||||
}
|
||||
}
|
||||
return output
|
||||
|
||||
@@ -149,18 +149,17 @@ func TestMapEdge(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFilterRender(t *testing.T) {
|
||||
renderer := render.FilterUnconnected{
|
||||
Renderer: mockRenderer{RenderableNodes: render.RenderableNodes{
|
||||
"foo": {ID: "foo", Adjacency: report.MakeIDList("bar")},
|
||||
"bar": {ID: "bar", Adjacency: report.MakeIDList("foo")},
|
||||
"baz": {ID: "baz", Adjacency: report.MakeIDList()},
|
||||
}},
|
||||
}
|
||||
renderer := render.FilterUnconnected(
|
||||
mockRenderer{RenderableNodes: render.RenderableNodes{
|
||||
"foo": {ID: "foo", Adjacency: report.MakeIDList("bar"), NodeMetadata: report.MakeNodeMetadata()},
|
||||
"bar": {ID: "bar", Adjacency: report.MakeIDList("foo"), NodeMetadata: report.MakeNodeMetadata()},
|
||||
"baz": {ID: "baz", Adjacency: report.MakeIDList(), NodeMetadata: report.MakeNodeMetadata()},
|
||||
}})
|
||||
want := render.RenderableNodes{
|
||||
"foo": {ID: "foo", Adjacency: report.MakeIDList("bar")},
|
||||
"bar": {ID: "bar", Adjacency: report.MakeIDList("foo")},
|
||||
"foo": {ID: "foo", Adjacency: report.MakeIDList("bar"), NodeMetadata: report.MakeNodeMetadata()},
|
||||
"bar": {ID: "bar", Adjacency: report.MakeIDList("foo"), NodeMetadata: report.MakeNodeMetadata()},
|
||||
}
|
||||
have := renderer.Render(report.MakeReport())
|
||||
have := sterilize(renderer.Render(report.MakeReport()), true)
|
||||
if !reflect.DeepEqual(want, have) {
|
||||
t.Errorf("want %+v, have %+v", want, have)
|
||||
}
|
||||
|
||||
@@ -82,8 +82,22 @@ var ProcessNameRenderer = Map{
|
||||
// graph by merging the process graph and the container topology.
|
||||
var ContainerRenderer = MakeReduce(
|
||||
Map{
|
||||
MapFunc: MapProcess2Container,
|
||||
Renderer: ProcessRenderer,
|
||||
MapFunc: MapProcess2Container,
|
||||
|
||||
// We only want processes in container _or_ processes with network connections
|
||||
// but we need to be careful to ensure we only include each edge once, by only
|
||||
// including the ProcessRenderer once.
|
||||
Renderer: Filter{
|
||||
f: func(n RenderableNode) bool {
|
||||
_, inContainer := n.NodeMetadata.Metadata[docker.ContainerID]
|
||||
_, isConnected := n.NodeMetadata.Metadata[IsConnected]
|
||||
return inContainer || isConnected
|
||||
},
|
||||
Renderer: CustomRenderer{
|
||||
RenderFunc: ColorConnected,
|
||||
Renderer: ProcessRenderer,
|
||||
},
|
||||
},
|
||||
},
|
||||
LeafMap{
|
||||
Selector: report.SelectContainer,
|
||||
|
||||
Reference in New Issue
Block a user