func BenchmarkNodeSetMerge(b *testing.B) { n, other := report.NodeSet{}, report.NodeSet{} for i := 0; i < 600; i++ { n = n.Add( report.MakeNodeWith(fmt.Sprint(i), map[string]string{ "a": "1", "b": "2", }), ) } for i := 400; i < 1000; i++ { other = other.Add( report.MakeNodeWith(fmt.Sprint(i), map[string]string{ "c": "1", "d": "2", }), ) } b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { benchmarkResult = n.Merge(other) } }
func (r *Reporter) addConnection(rpt *report.Report, t fourTuple, extraFromNode, extraToNode map[string]string) { var ( fromEndpointNodeID = report.MakeEndpointNodeID(r.hostID, t.fromAddr, strconv.Itoa(int(t.fromPort))) toEndpointNodeID = report.MakeEndpointNodeID(r.hostID, t.toAddr, strconv.Itoa(int(t.toPort))) fromNode = report.MakeNodeWith(fromEndpointNodeID, map[string]string{ Addr: t.fromAddr, Port: strconv.Itoa(int(t.fromPort)), }).WithEdge(toEndpointNodeID, report.EdgeMetadata{}) toNode = report.MakeNodeWith(toEndpointNodeID, map[string]string{ Addr: t.toAddr, Port: strconv.Itoa(int(t.toPort)), }) ) // In case we have a reverse resolution for the IP, we can use it for // the name... if toNames, err := r.reverseResolver.get(t.toAddr); err == nil { toNode = toNode.WithSet(ReverseDNSNames, report.MakeStringSet(toNames...)) } if extraFromNode != nil { fromNode = fromNode.WithLatests(extraFromNode) } if extraToNode != nil { toNode = toNode.WithLatests(extraToNode) } rpt.Endpoint = rpt.Endpoint.AddNode(fromNode) rpt.Endpoint = rpt.Endpoint.AddNode(toNode) }
func TestTagger(t *testing.T) { oldProcessTree := docker.NewProcessTreeStub defer func() { docker.NewProcessTreeStub = oldProcessTree }() docker.NewProcessTreeStub = func(_ process.Walker) (process.Tree, error) { return &mockProcessTree{map[int]int{3: 2}}, nil } var ( pid1NodeID = report.MakeProcessNodeID("somehost.com", "2") pid2NodeID = report.MakeProcessNodeID("somehost.com", "3") wantNode = report.MakeNodeWith(map[string]string{docker.ContainerID: "ping"}) ) input := report.MakeReport() input.Process.AddNode(pid1NodeID, report.MakeNodeWith(map[string]string{process.PID: "2"})) input.Process.AddNode(pid2NodeID, report.MakeNodeWith(map[string]string{process.PID: "3"})) want := report.MakeReport() want.Process.AddNode(pid1NodeID, report.MakeNodeWith(map[string]string{process.PID: "2"}).Merge(wantNode)) want.Process.AddNode(pid2NodeID, report.MakeNodeWith(map[string]string{process.PID: "3"}).Merge(wantNode)) tagger := docker.NewTagger(mockRegistryInstance, nil) have, err := tagger.Tag(input) if err != nil { t.Errorf("%v", err) } if !reflect.DeepEqual(want, have) { t.Errorf("%s", test.Diff(want, have)) } }
func TestApply(t *testing.T) { var ( endpointNodeID = "c" addressNodeID = "d" endpointNode = report.MakeNodeWith(map[string]string{"5": "6"}) addressNode = report.MakeNodeWith(map[string]string{"7": "8"}) ) r := report.MakeReport() r.Endpoint.Nodes[endpointNodeID] = endpointNode r.Address.Nodes[addressNodeID] = addressNode r = Apply(r, []Tagger{newTopologyTagger()}) for _, tuple := range []struct { want report.Node from report.Topology via string }{ {endpointNode.Merge(report.MakeNodeWith(map[string]string{"topology": "endpoint"})), r.Endpoint, endpointNodeID}, {addressNode.Merge(report.MakeNodeWith(map[string]string{"topology": "address"})), r.Address, addressNodeID}, } { if want, have := tuple.want, tuple.from.Nodes[tuple.via]; !reflect.DeepEqual(want, have) { t.Errorf("want %+v, have %+v", want, have) } } }
func TestReporter(t *testing.T) { want := report.MakeReport() want.Container = report.Topology{ Nodes: report.Nodes{ report.MakeContainerNodeID("", "ping"): report.MakeNodeWith(map[string]string{ docker.ContainerID: "ping", docker.ContainerName: "pong", docker.ImageID: "baz", }), }, } want.ContainerImage = report.Topology{ Nodes: report.Nodes{ report.MakeContainerNodeID("", "baz"): report.MakeNodeWith(map[string]string{ docker.ImageID: "baz", docker.ImageName: "bang", }), }, } reporter := docker.NewReporter(mockRegistryInstance, "") have, _ := reporter.Report() if !reflect.DeepEqual(want, have) { t.Errorf("%s", test.Diff(want, have)) } }
func TestApply(t *testing.T) { var ( endpointNodeID = "c" addressNodeID = "d" endpointNode = report.MakeNodeWith(map[string]string{"5": "6"}) addressNode = report.MakeNodeWith(map[string]string{"7": "8"}) ) p := New(0, 0, nil) p.AddTagger(NewTopologyTagger()) r := report.MakeReport() r.Endpoint.AddNode(endpointNodeID, endpointNode) r.Address.AddNode(addressNodeID, addressNode) r = p.tag(r) for _, tuple := range []struct { want report.Node from report.Topology via string }{ {endpointNode.Merge(report.MakeNode().WithID("c").WithTopology(report.Endpoint)), r.Endpoint, endpointNodeID}, {addressNode.Merge(report.MakeNode().WithID("d").WithTopology(report.Address)), r.Address, addressNodeID}, } { if want, have := tuple.want, tuple.from.Nodes[tuple.via]; !reflect.DeepEqual(want, have) { t.Errorf("want %+v, have %+v", want, have) } } }
func TestReporter(t *testing.T) { walker := &mockWalker{ processes: []process.Process{ {PID: 1, PPID: 0, Name: "init"}, {PID: 2, PPID: 1, Name: "bash"}, {PID: 3, PPID: 1, Name: "apache", Threads: 2}, {PID: 4, PPID: 2, Name: "ping", Cmdline: "ping foo.bar.local"}, {PID: 5, PPID: 1, Cmdline: "tail -f /var/log/syslog"}, }, } getDeltaTotalJiffies := func() (uint64, float64, error) { return 0, 0., nil } now := time.Now() mtime.NowForce(now) defer mtime.NowReset() reporter := process.NewReporter(walker, "", getDeltaTotalJiffies) want := report.MakeReport() want.Process = report.MakeTopology().AddNode( report.MakeProcessNodeID("", "1"), report.MakeNodeWith(map[string]string{ process.PID: "1", process.Name: "init", process.Threads: "0", }).WithMetric(process.MemoryUsage, report.MakeMetric().Add(now, 0.)), ).AddNode( report.MakeProcessNodeID("", "2"), report.MakeNodeWith(map[string]string{ process.PID: "2", process.Name: "bash", process.PPID: "1", process.Threads: "0", }).WithMetric(process.MemoryUsage, report.MakeMetric().Add(now, 0.)), ).AddNode( report.MakeProcessNodeID("", "3"), report.MakeNodeWith(map[string]string{ process.PID: "3", process.Name: "apache", process.PPID: "1", process.Threads: "2", }).WithMetric(process.MemoryUsage, report.MakeMetric().Add(now, 0.)), ).AddNode( report.MakeProcessNodeID("", "4"), report.MakeNodeWith(map[string]string{ process.PID: "4", process.Name: "ping", process.PPID: "2", process.Cmdline: "ping foo.bar.local", process.Threads: "0", }).WithMetric(process.MemoryUsage, report.MakeMetric().Add(now, 0.)), ).AddNode( report.MakeProcessNodeID("", "5"), report.MakeNodeWith(map[string]string{ process.PID: "5", process.PPID: "1", process.Cmdline: "tail -f /var/log/syslog", process.Threads: "0", }).WithMetric(process.MemoryUsage, report.MakeMetric().Add(now, 0.)), ) have, err := reporter.Report() if err != nil || !reflect.DeepEqual(want, have) { t.Errorf("%s (%v)", test.Diff(want, have), err) } }
func TestReporter(t *testing.T) { walker := &mockWalker{ processes: []process.Process{ {PID: 1, PPID: 0, Comm: "init"}, {PID: 2, PPID: 1, Comm: "bash"}, {PID: 3, PPID: 1, Comm: "apache", Threads: 2}, {PID: 4, PPID: 2, Comm: "ping", Cmdline: "ping foo.bar.local"}, {PID: 5, PPID: 1, Cmdline: "tail -f /var/log/syslog"}, }, } reporter := process.NewReporter(walker, "") want := report.MakeReport() want.Process = report.MakeTopology().AddNode( report.MakeProcessNodeID("", "1"), report.MakeNodeWith(map[string]string{ process.PID: "1", process.Comm: "init", process.Threads: "0", }), ).AddNode( report.MakeProcessNodeID("", "2"), report.MakeNodeWith(map[string]string{ process.PID: "2", process.Comm: "bash", process.PPID: "1", process.Threads: "0", }), ).AddNode( report.MakeProcessNodeID("", "3"), report.MakeNodeWith(map[string]string{ process.PID: "3", process.Comm: "apache", process.PPID: "1", process.Threads: "2", }), ).AddNode( report.MakeProcessNodeID("", "4"), report.MakeNodeWith(map[string]string{ process.PID: "4", process.Comm: "ping", process.PPID: "2", process.Cmdline: "ping foo.bar.local", process.Threads: "0", }), ).AddNode( report.MakeProcessNodeID("", "5"), report.MakeNodeWith(map[string]string{ process.PID: "5", process.PPID: "1", process.Cmdline: "tail -f /var/log/syslog", process.Threads: "0", }), ) have, err := reporter.Report() if err != nil || !reflect.DeepEqual(want, have) { t.Errorf("%s (%v)", test.Diff(want, have), err) } }
func TestWeaveTaggerOverlayTopology(t *testing.T) { oldExecCmd := exec.Command defer func() { exec.Command = oldExecCmd }() exec.Command = func(name string, args ...string) exec.Cmd { return testExec.NewMockCmdString(fmt.Sprintf("%s %s %s/24\n", mockContainerID, mockContainerMAC, mockContainerIP)) } s := httptest.NewServer(http.HandlerFunc(mockWeaveRouter)) defer s.Close() w := overlay.NewWeave(mockHostID, s.URL) defer w.Stop() w.Tick() { have, err := w.Report() if err != nil { t.Fatal(err) } if want, have := report.MakeTopology().AddNode( report.MakeOverlayNodeID(mockWeavePeerName), report.MakeNodeWith(map[string]string{ overlay.WeavePeerName: mockWeavePeerName, overlay.WeavePeerNickName: mockWeavePeerNickName, }), ), have.Overlay; !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } } { nodeID := report.MakeContainerNodeID(mockHostID, mockContainerID) want := report.Report{ Container: report.MakeTopology().AddNode(nodeID, report.MakeNodeWith(map[string]string{ docker.ContainerID: mockContainerID, overlay.WeaveDNSHostname: mockHostname, overlay.WeaveMACAddress: mockContainerMAC, }).WithSets(report.Sets{ docker.ContainerIPs: report.MakeStringSet(mockContainerIP), docker.ContainerIPsWithScopes: report.MakeStringSet(mockContainerIPWithScope), })), } have, err := w.Tag(report.Report{ Container: report.MakeTopology().AddNode(nodeID, report.MakeNodeWith(map[string]string{ docker.ContainerID: mockContainerID, })), }) if err != nil { t.Fatal(err) } if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } } }
func TestReporter(t *testing.T) { want := report.MakeReport() want.Container = report.Topology{ Nodes: report.Nodes{ report.MakeContainerNodeID("", "ping"): report.MakeNodeWith(map[string]string{ docker.ContainerID: "ping", docker.ContainerName: "pong", docker.ImageID: "baz", }), }, Controls: report.Controls{ docker.RestartContainer: report.Control{ ID: docker.RestartContainer, Human: "Restart", Icon: "fa-repeat", }, docker.StartContainer: report.Control{ ID: docker.StartContainer, Human: "Start", Icon: "fa-play", }, docker.StopContainer: report.Control{ ID: docker.StopContainer, Human: "Stop", Icon: "fa-stop", }, docker.PauseContainer: report.Control{ ID: docker.PauseContainer, Human: "Pause", Icon: "fa-pause", }, docker.UnpauseContainer: report.Control{ ID: docker.UnpauseContainer, Human: "Unpause", Icon: "fa-play", }, }, } want.ContainerImage = report.Topology{ Nodes: report.Nodes{ report.MakeContainerNodeID("", "baz"): report.MakeNodeWith(map[string]string{ docker.ImageID: "baz", docker.ImageName: "bang", }), }, Controls: report.Controls{}, } reporter := docker.NewReporter(mockRegistryInstance, "") have, _ := reporter.Report() if !reflect.DeepEqual(want, have) { t.Errorf("%s", test.Diff(want, have)) } }
func TestMapEndpointIdentity(t *testing.T) { for _, input := range []testcase{ {nrn(report.MakeNode()), false}, {nrn(report.MakeNodeWith(map[string]string{endpoint.Addr: "1.2.3.4"})), false}, {nrn(report.MakeNodeWith(map[string]string{endpoint.Port: "1234"})), false}, {nrn(report.MakeNodeWith(map[string]string{endpoint.Addr: "1.2.3.4", endpoint.Port: "1234"})), true}, {nrn(report.MakeNodeWith(map[string]string{endpoint.Addr: "1.2.3.4", endpoint.Port: "40000"})), true}, {nrn(report.MakeNodeWith(map[string]string{report.HostNodeID: report.MakeHostNodeID("foo"), endpoint.Addr: "10.0.0.1", endpoint.Port: "20001"})), true}, } { testMap(t, render.MapEndpointIdentity, input) } }
func TestTagger(t *testing.T) { mtime.NowForce(time.Now()) defer mtime.NowReset() oldProcessTree := docker.NewProcessTreeStub defer func() { docker.NewProcessTreeStub = oldProcessTree }() docker.NewProcessTreeStub = func(_ process.Walker) (process.Tree, error) { return &mockProcessTree{map[int]int{3: 2}}, nil } var ( pid1NodeID = report.MakeProcessNodeID("somehost.com", "2") pid2NodeID = report.MakeProcessNodeID("somehost.com", "3") ) input := report.MakeReport() input.Process.AddNode(pid1NodeID, report.MakeNodeWith(map[string]string{process.PID: "2"})) input.Process.AddNode(pid2NodeID, report.MakeNodeWith(map[string]string{process.PID: "3"})) have, err := docker.NewTagger(mockRegistryInstance, nil).Tag(input) if err != nil { t.Errorf("%v", err) } // Processes should be tagged with their container ID, and parents for _, nodeID := range []string{pid1NodeID, pid2NodeID} { node, ok := have.Process.Nodes[nodeID] if !ok { t.Errorf("Expected process node %s, but not found", nodeID) } // node should have the container id added if have, ok := node.Latest.Lookup(docker.ContainerID); !ok || have != "ping" { t.Errorf("Expected process node %s to have container id %q, got %q", nodeID, "ping", have) } // node should have the container as a parent if have, ok := node.Parents.Lookup(report.Container); !ok || !have.Contains(report.MakeContainerNodeID("ping")) { t.Errorf("Expected process node %s to have container %q as a parent, got %q", nodeID, "ping", have) } // node should have the container image as a parent if have, ok := node.Parents.Lookup(report.ContainerImage); !ok || !have.Contains(report.MakeContainerImageNodeID("baz")) { t.Errorf("Expected process node %s to have container image %q as a parent, got %q", nodeID, "baz", have) } } }
// Report implements Reporter. func (w *Weave) Report() (report.Report, error) { w.mtx.RLock() defer w.mtx.RUnlock() r := report.MakeReport() r.Container = r.Container.WithMetadataTemplates(report.MetadataTemplates{ WeaveMACAddress: {ID: WeaveMACAddress, Label: "Weave MAC", From: report.FromLatest, Priority: 17}, WeaveDNSHostname: {ID: WeaveDNSHostname, Label: "Weave DNS Name", From: report.FromLatest, Priority: 18}, }) for _, peer := range w.statusCache.Router.Peers { r.Overlay.AddNode(report.MakeNodeWith(report.MakeOverlayNodeID(peer.Name), map[string]string{ WeavePeerName: peer.Name, WeavePeerNickName: peer.NickName, })) } if w.statusCache.IPAM.DefaultSubnet != "" { r.Overlay.AddNode( report.MakeNode(report.MakeOverlayNodeID(w.statusCache.Router.Name)).WithSets( report.MakeSets().Add(host.LocalNetworks, report.MakeStringSet(w.statusCache.IPAM.DefaultSubnet)), ), ) } return r, nil }
// Report implements Reporter. func (r *Reporter) Report() (report.Report, error) { var ( rep = report.MakeReport() localCIDRs []string ) for _, localNet := range r.localNets { localCIDRs = append(localCIDRs, localNet.String()) } uptime, err := GetUptime() if err != nil { return rep, err } kernel, err := GetKernelVersion() if err != nil { return rep, err } rep.Host.AddNode(report.MakeHostNodeID(r.hostID), report.MakeNodeWith(map[string]string{ Timestamp: Now(), HostName: r.hostName, OS: runtime.GOOS, Load: GetLoad(), KernelVersion: kernel, Uptime: uptime.String(), }).WithSets(report.Sets{ LocalNetworks: report.MakeStringSet(localCIDRs...), })) return rep, nil }
func (c *mockContainer) GetNode() report.Node { return report.MakeNodeWith(map[string]string{ docker.ContainerID: c.c.ID, docker.ContainerName: c.c.Name, docker.ImageID: c.c.Image, }) }
func (r *Reporter) podTopology(services []Service) (report.Topology, report.Topology, error) { pods, containers := report.MakeTopology(), report.MakeTopology() selectors := map[string]labels.Selector{} for _, service := range services { selectors[service.ID()] = service.Selector() } err := r.client.WalkPods(func(p Pod) error { for serviceID, selector := range selectors { if selector.Matches(p.Labels()) { p.AddServiceID(serviceID) } } nodeID := report.MakePodNodeID(p.Namespace(), p.Name()) pods = pods.AddNode(nodeID, p.GetNode()) container := report.MakeNodeWith(map[string]string{ PodID: p.ID(), Namespace: p.Namespace(), }).WithParents(report.EmptySets.Add(report.Pod, report.MakeStringSet(nodeID))) for _, containerID := range p.ContainerIDs() { containers.AddNode(report.MakeContainerNodeID(containerID), container) } return nil }) return pods, containers, err }
func TestReporter(t *testing.T) { var ( release = "release" version = "version" network = "192.168.0.0/16" hostID = "hostid" hostname = "hostname" timestamp = time.Now() load = report.Metrics{ host.Load1: report.MakeMetric().Add(timestamp, 1.0), host.Load5: report.MakeMetric().Add(timestamp, 5.0), host.Load15: report.MakeMetric().Add(timestamp, 15.0), host.CPUUsage: report.MakeMetric().Add(timestamp, 30.0).WithMax(100.0), host.MemUsage: report.MakeMetric().Add(timestamp, 60.0).WithMax(100.0), } uptime = "278h55m43s" kernel = "release version" _, ipnet, _ = net.ParseCIDR(network) localNets = report.Networks([]*net.IPNet{ipnet}) ) mtime.NowForce(timestamp) defer mtime.NowReset() var ( oldGetKernelVersion = host.GetKernelVersion oldGetLoad = host.GetLoad oldGetUptime = host.GetUptime oldGetCPUUsagePercent = host.GetCPUUsagePercent oldGetMemoryUsageBytes = host.GetMemoryUsageBytes ) defer func() { host.GetKernelVersion = oldGetKernelVersion host.GetLoad = oldGetLoad host.GetUptime = oldGetUptime host.GetCPUUsagePercent = oldGetCPUUsagePercent host.GetMemoryUsageBytes = oldGetMemoryUsageBytes }() host.GetKernelVersion = func() (string, error) { return release + " " + version, nil } host.GetLoad = func(time.Time) report.Metrics { return load } host.GetUptime = func() (time.Duration, error) { return time.ParseDuration(uptime) } host.GetCPUUsagePercent = func() (float64, float64) { return 30.0, 100.0 } host.GetMemoryUsageBytes = func() (float64, float64) { return 60.0, 100.0 } want := report.MakeReport() want.Host.AddNode(report.MakeHostNodeID(hostID), report.MakeNodeWith(map[string]string{ host.Timestamp: timestamp.UTC().Format(time.RFC3339Nano), host.HostName: hostname, host.OS: runtime.GOOS, host.Uptime: uptime, host.KernelVersion: kernel, }).WithSets(report.Sets{ host.LocalNetworks: report.MakeStringSet(network), }).WithMetrics(load)) have, _ := host.NewReporter(hostID, hostname, localNets).Report() if !reflect.DeepEqual(want, have) { t.Errorf("%s", test.Diff(want, have)) } }
func TestMapServiceIdentity(t *testing.T) { for _, input := range []testcase{ {nrn(report.MakeNode()), false}, {nrn(report.MakeNodeWith(map[string]string{kubernetes.ServiceID: "ping/pong", kubernetes.ServiceName: "pong"})), true}, } { testMap(t, render.MapServiceIdentity, input) } }
// MetaNode gets the node metadata func (m meta) MetaNode(id string) report.Node { return report.MakeNodeWith(id, map[string]string{ ID: m.ID(), Name: m.Name(), Namespace: m.Namespace(), Created: m.Created(), }).AddTable(LabelPrefix, m.Labels()) }
func TestMapContainerImageIdentity(t *testing.T) { for _, input := range []testcase{ {nrn(report.MakeNode()), false}, {nrn(report.MakeNodeWith(map[string]string{docker.ImageID: "a1b2c3"})), true}, } { testMap(t, render.MapContainerImageIdentity, input) } }
func (s *service) GetNode() report.Node { return report.MakeNodeWith(map[string]string{ ServiceID: s.ID(), ServiceName: s.Name(), ServiceCreated: s.ObjectMeta.CreationTimestamp.Format(time.RFC822), Namespace: s.Namespace(), }) }
func TestMapAddressIdentity(t *testing.T) { for _, input := range []testcase{ {nrn(report.MakeNode()), false}, {nrn(report.MakeNodeWith(map[string]string{endpoint.Addr: "192.168.1.1"})), true}, } { testMap(t, render.MapAddressIdentity, input) } }
func TestMapProcessIdentity(t *testing.T) { for _, input := range []testcase{ {nrn(report.MakeNode()), false}, {nrn(report.MakeNodeWith(map[string]string{process.PID: "201"})), true}, } { testMap(t, render.MapProcessIdentity, input) } }
func TestTagger(t *testing.T) { var ( hostID = "foo" endpointNodeID = report.MakeEndpointNodeID(hostID, "1.2.3.4", "56789") // hostID ignored nodeMetadata = report.MakeNodeWith(map[string]string{"foo": "bar"}) ) r := report.MakeReport() r.Process.Nodes[endpointNodeID] = nodeMetadata want := nodeMetadata.Merge(report.MakeNodeWith(map[string]string{ report.HostNodeID: report.MakeHostNodeID(hostID), })) rpt, _ := host.NewTagger(hostID).Tag(r) have := rpt.Process.Nodes[endpointNodeID].Copy() if !reflect.DeepEqual(want, have) { t.Error(test.Diff(want, have)) } }
func (c *container) GetNode() report.Node { c.RLock() defer c.RUnlock() result := report.MakeNodeWith(map[string]string{ ContainerID: c.ID(), ContainerName: strings.TrimPrefix(c.container.Name, "/"), ContainerPorts: c.ports(), ContainerCreated: c.container.Created.Format(time.RFC822), ContainerCommand: c.container.Path + " " + strings.Join(c.container.Args, " "), ImageID: c.container.Image, ContainerIPs: strings.Join(append(c.container.NetworkSettings.SecondaryIPAddresses, c.container.NetworkSettings.IPAddress), " "), }) AddLabels(result, c.container.Config.Labels) if c.latestStats == nil { return result } result = result.Merge(report.MakeNodeWith(map[string]string{ NetworkRxDropped: strconv.FormatUint(c.latestStats.Network.RxDropped, 10), NetworkRxBytes: strconv.FormatUint(c.latestStats.Network.RxBytes, 10), NetworkRxErrors: strconv.FormatUint(c.latestStats.Network.RxErrors, 10), NetworkTxPackets: strconv.FormatUint(c.latestStats.Network.TxPackets, 10), NetworkTxDropped: strconv.FormatUint(c.latestStats.Network.TxDropped, 10), NetworkRxPackets: strconv.FormatUint(c.latestStats.Network.RxPackets, 10), NetworkTxErrors: strconv.FormatUint(c.latestStats.Network.TxErrors, 10), NetworkTxBytes: strconv.FormatUint(c.latestStats.Network.TxBytes, 10), MemoryMaxUsage: strconv.FormatUint(c.latestStats.MemoryStats.MaxUsage, 10), MemoryUsage: strconv.FormatUint(c.latestStats.MemoryStats.Usage, 10), MemoryFailcnt: strconv.FormatUint(c.latestStats.MemoryStats.Failcnt, 10), MemoryLimit: strconv.FormatUint(c.latestStats.MemoryStats.Limit, 10), // CPUPercpuUsage: strconv.FormatUint(stats.CPUStats.CPUUsage.PercpuUsage, 10), CPUUsageInUsermode: strconv.FormatUint(c.latestStats.CPUStats.CPUUsage.UsageInUsermode, 10), CPUTotalUsage: strconv.FormatUint(c.latestStats.CPUStats.CPUUsage.TotalUsage, 10), CPUUsageInKernelmode: strconv.FormatUint(c.latestStats.CPUStats.CPUUsage.UsageInKernelmode, 10), CPUSystemCPUUsage: strconv.FormatUint(c.latestStats.CPUStats.SystemCPUUsage, 10), })) return result }
func (t *Tagger) tag(tree process.Tree, topology *report.Topology) { for nodeID, node := range topology.Nodes { pidStr, ok := node.Latest.Lookup(process.PID) if !ok { continue } pid, err := strconv.ParseUint(pidStr, 10, 64) if err != nil { continue } var ( c Container candidate = int(pid) ) t.registry.LockedPIDLookup(func(lookup func(int) Container) { for { c = lookup(candidate) if c != nil { break } candidate, err = tree.GetParent(candidate) if err != nil { break } } }) if c == nil || ContainerIsStopped(c) || c.PID() == 1 { continue } node := report.MakeNodeWith(nodeID, map[string]string{ ContainerID: c.ID(), }).WithParents(report.EmptySets. Add(report.Container, report.MakeStringSet(report.MakeContainerNodeID(c.ID()))), ) // If we can work out the image name, add a parent tag for it image, ok := t.registry.GetContainerImage(c.Image()) if ok && len(image.RepoTags) > 0 { imageName := ImageNameWithoutVersion(image.RepoTags[0]) node = node.WithParents(report.EmptySets. Add(report.ContainerImage, report.MakeStringSet(report.MakeContainerImageNodeID(imageName))), ) } topology.AddNode(node) } }
// Tag implements Tagger. func (t Tagger) Tag(r report.Report) (report.Report, error) { other := report.MakeNodeWith(map[string]string{report.HostNodeID: t.hostNodeID}) // Explicity don't tag Endpoints and Addresses - These topologies include pseudo nodes, // and as such do their own host tagging for _, topology := range []report.Topology{r.Process, r.Container, r.ContainerImage, r.Host, r.Overlay} { for id, md := range topology.Nodes { topology.Nodes[id] = md.Merge(other) } } return r, nil }
func TestNodeMetadata(t *testing.T) { inputs := []struct { name string node report.Node want []detailed.MetadataRow }{ { name: "container", node: report.MakeNodeWith(map[string]string{ docker.ContainerID: fixture.ClientContainerID, docker.LabelPrefix + "label1": "label1value", }).WithTopology(report.Container).WithSets(report.Sets{ docker.ContainerIPs: report.MakeStringSet("10.10.10.0/24", "10.10.10.1/24"), }).WithLatest(docker.ContainerState, fixture.Now, docker.StateRunning), want: []detailed.MetadataRow{ {ID: docker.ContainerID, Label: "ID", Value: fixture.ClientContainerID}, {ID: docker.ContainerState, Label: "State", Value: "running"}, {ID: docker.ContainerIPs, Label: "IPs", Value: "10.10.10.0/24, 10.10.10.1/24"}, { ID: "label_label1", Label: "Label \"label1\"", Value: "label1value", }, }, }, { name: "unknown topology", node: report.MakeNodeWith(map[string]string{ docker.ContainerID: fixture.ClientContainerID, }).WithTopology("foobar").WithID(fixture.ClientContainerNodeID), want: nil, }, } for _, input := range inputs { have := detailed.NodeMetadata(input.node) if !reflect.DeepEqual(input.want, have) { t.Errorf("%s: %s", input.name, test.Diff(input.want, have)) } } }
func TestReporter(t *testing.T) { var ( release = "release" version = "version" network = "192.168.0.0/16" hostID = "hostid" now = "now" hostname = "hostname" timestamp = time.Now() load = report.Metrics{ host.Load1: report.MakeMetric().Add(timestamp, 1.0), host.Load5: report.MakeMetric().Add(timestamp, 5.0), host.Load15: report.MakeMetric().Add(timestamp, 15.0), } uptime = "278h55m43s" kernel = "release version" _, ipnet, _ = net.ParseCIDR(network) localNets = report.Networks([]*net.IPNet{ipnet}) ) var ( oldGetKernelVersion = host.GetKernelVersion oldGetLoad = host.GetLoad oldGetUptime = host.GetUptime oldNow = host.Now ) defer func() { host.GetKernelVersion = oldGetKernelVersion host.GetLoad = oldGetLoad host.GetUptime = oldGetUptime host.Now = oldNow }() host.GetKernelVersion = func() (string, error) { return release + " " + version, nil } host.GetLoad = func() report.Metrics { return load } host.GetUptime = func() (time.Duration, error) { return time.ParseDuration(uptime) } host.Now = func() string { return now } want := report.MakeReport() want.Host.AddNode(report.MakeHostNodeID(hostID), report.MakeNodeWith(map[string]string{ host.Timestamp: now, host.HostName: hostname, host.OS: runtime.GOOS, host.Uptime: uptime, host.KernelVersion: kernel, }).WithSets(report.Sets{ host.LocalNetworks: report.MakeStringSet(network), }).WithMetrics(load)) have, _ := host.NewReporter(hostID, hostname, localNets).Report() if !reflect.DeepEqual(want, have) { t.Errorf("%s", test.Diff(want, have)) } }
func (p *pod) GetNode() report.Node { n := report.MakeNodeWith(map[string]string{ PodID: p.ID(), PodName: p.Name(), Namespace: p.Namespace(), PodCreated: p.Created(), PodContainerIDs: strings.Join(p.ContainerIDs(), " "), }) if len(p.serviceIDs) > 0 { n.Metadata[ServiceIDs] = strings.Join(p.serviceIDs, " ") } return n }