Пример #1
0
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(report.MakeNodeWith(pid1NodeID, map[string]string{process.PID: "2"}))
	input.Process.AddNode(report.MakeNodeWith(pid2NodeID, 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)
		}
	}
}
Пример #2
0
// MapEndpoint2Process maps endpoint Nodes to process
// Nodes.
//
// If this function is given a pseudo node, then it will just return it;
// Pseudo nodes will never have pids in them, and therefore will never
// be able to be turned into a Process node.
//
// Otherwise, this function will produce a node with the correct ID
// format for a process, but without any Major or Minor labels.
// It does not have enough info to do that, and the resulting graph
// must be merged with a process graph to get that info.
func MapEndpoint2Process(n report.Node, local report.Networks) report.Nodes {
	// Nodes without a hostid are treated as pseudo nodes
	if _, ok := n.Latest.Lookup(report.HostNodeID); !ok {
		return MapEndpoint2Pseudo(n, local)
	}

	pid, timestamp, ok := n.Latest.LookupEntry(process.PID)
	if !ok {
		return report.Nodes{}
	}

	id := report.MakeProcessNodeID(report.ExtractHostID(n), pid)
	node := NewDerivedNode(id, n).WithTopology(report.Process)
	node.Latest = node.Latest.Set(process.PID, timestamp, pid)
	node.Counters = node.Counters.Add(n.Topology, 1)
	return report.Nodes{id: node}
}
Пример #3
0
func (r *Reporter) processTopology() (report.Topology, error) {
	t := report.MakeTopology().
		WithMetadataTemplates(MetadataTemplates).
		WithMetricTemplates(MetricTemplates)
	now := mtime.Now()
	deltaTotal, maxCPU, err := r.jiffies()
	if err != nil {
		return t, err
	}

	err = r.walker.Walk(func(p, prev Process) {
		pidstr := strconv.Itoa(p.PID)
		nodeID := report.MakeProcessNodeID(r.scope, pidstr)
		node := report.MakeNode(nodeID)
		for _, tuple := range []struct{ key, value string }{
			{PID, pidstr},
			{Name, p.Name},
			{Cmdline, p.Cmdline},
			{Threads, strconv.Itoa(p.Threads)},
		} {
			if tuple.value != "" {
				node = node.WithLatests(map[string]string{tuple.key: tuple.value})
			}
		}

		if p.PPID > 0 {
			node = node.WithLatests(map[string]string{PPID: strconv.Itoa(p.PPID)})
		}

		if deltaTotal > 0 {
			cpuUsage := float64(p.Jiffies-prev.Jiffies) / float64(deltaTotal) * 100.
			node = node.WithMetric(CPUUsage, report.MakeMetric().Add(now, cpuUsage).WithMax(maxCPU))
		}

		node = node.WithMetric(MemoryUsage, report.MakeMetric().Add(now, float64(p.RSSBytes)).WithMax(float64(p.RSSBytesLimit)))
		node = node.WithMetric(OpenFilesCount, report.MakeMetric().Add(now, float64(p.OpenFilesCount)).WithMax(float64(p.OpenFilesLimit)))

		t.AddNode(node)
	})

	return t, err
}
Пример #4
0
	True = "true"

	ClientHostNodeID = report.MakeHostNodeID(ClientHostID)
	ServerHostNodeID = report.MakeHostNodeID(ServerHostID)

	Client54001NodeID    = report.MakeEndpointNodeID(ClientHostID, ClientIP, ClientPort54001)            // curl (1)
	Client54002NodeID    = report.MakeEndpointNodeID(ClientHostID, ClientIP, ClientPort54002)            // curl (2)
	Server80NodeID       = report.MakeEndpointNodeID(ServerHostID, ServerIP, ServerPort)                 // apache
	UnknownClient1NodeID = report.MakeEndpointNodeID(ServerHostID, UnknownClient1IP, UnknownClient1Port) // we want to ensure two unknown clients, connnected
	UnknownClient2NodeID = report.MakeEndpointNodeID(ServerHostID, UnknownClient2IP, UnknownClient2Port) // to the same server, are deduped.
	UnknownClient3NodeID = report.MakeEndpointNodeID(ServerHostID, UnknownClient3IP, UnknownClient3Port) // Check this one isn't deduped
	RandomClientNodeID   = report.MakeEndpointNodeID(ServerHostID, RandomClientIP, RandomClientPort)     // this should become an internet node
	NonContainerNodeID   = report.MakeEndpointNodeID(ServerHostID, ServerIP, NonContainerClientPort)
	GoogleEndpointNodeID = report.MakeEndpointNodeID(ServerHostID, GoogleIP, GooglePort)

	ClientProcess1NodeID      = report.MakeProcessNodeID(ClientHostID, Client1PID)
	ClientProcess2NodeID      = report.MakeProcessNodeID(ClientHostID, Client2PID)
	ServerProcessNodeID       = report.MakeProcessNodeID(ServerHostID, ServerPID)
	NonContainerProcessNodeID = report.MakeProcessNodeID(ServerHostID, NonContainerPID)

	ClientContainerID     = "a1b2c3d4e5"
	ClientContainerName   = "client"
	ServerContainerID     = "5e4d3c2b1a"
	ServerContainerName   = "task-name-5-server-aceb93e2f2b797caba01"
	ClientContainerNodeID = report.MakeContainerNodeID(ClientContainerID)
	ServerContainerNodeID = report.MakeContainerNodeID(ServerContainerID)

	ClientContainerHostname = ClientContainerName + ".hostname.com"
	ServerContainerHostname = ServerContainerName + ".hostname.com"

	ClientContainerImageID     = "imageid123"
Пример #5
0
func TestReporter(t *testing.T) {
	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"},
	}
	walker := &mockWalker{processes: processes}
	getDeltaTotalJiffies := func() (uint64, float64, error) { return 0, 0., nil }
	now := time.Now()
	mtime.NowForce(now)
	defer mtime.NowReset()

	rpt, err := process.NewReporter(walker, "", getDeltaTotalJiffies).Report()
	if err != nil {
		t.Error(err)
	}

	// It reports the init process
	node, ok := rpt.Process.Nodes[report.MakeProcessNodeID("", "1")]
	if !ok {
		t.Errorf("Expected report to include the pid 1 init")
	}
	if name, ok := node.Latest.Lookup(process.Name); !ok || name != processes[0].Name {
		t.Errorf("Expected %q got %q", processes[0].Name, name)
	}

	// It reports plain processes (with parent pid, and metrics)
	node, ok = rpt.Process.Nodes[report.MakeProcessNodeID("", "2")]
	if !ok {
		t.Errorf("Expected report to include the pid 2 bash")
	}
	if name, ok := node.Latest.Lookup(process.Name); !ok || name != processes[1].Name {
		t.Errorf("Expected %q got %q", processes[1].Name, name)
	}
	if ppid, ok := node.Latest.Lookup(process.PPID); !ok || ppid != fmt.Sprint(processes[1].PPID) {
		t.Errorf("Expected %d got %q", processes[1].PPID, ppid)
	}
	if memoryUsage, ok := node.Metrics[process.MemoryUsage]; !ok {
		t.Errorf("Expected memory usage metric, but not found")
	} else if sample := memoryUsage.LastSample(); sample == nil {
		t.Errorf("Expected memory usage metric to have a sample, but there were none")
	} else if sample.Value != 0. {
		t.Errorf("Expected memory usage metric sample %f, got %f", 0., sample.Value)
	}

	// It reports thread-counts
	node, ok = rpt.Process.Nodes[report.MakeProcessNodeID("", "3")]
	if !ok {
		t.Errorf("Expected report to include the pid 3 apache")
	}
	if threads, ok := node.Latest.Lookup(process.Threads); !ok || threads != fmt.Sprint(processes[2].Threads) {
		t.Errorf("Expected %d got %q", processes[2].Threads, threads)
	}

	// It reports the Cmdline
	node, ok = rpt.Process.Nodes[report.MakeProcessNodeID("", "4")]
	if !ok {
		t.Errorf("Expected report to include the pid 4 ping")
	}
	if cmdline, ok := node.Latest.Lookup(process.Cmdline); !ok || cmdline != fmt.Sprint(processes[3].Cmdline) {
		t.Errorf("Expected %q got %q", processes[3].Cmdline, cmdline)
	}

	// It reports processes without a Name
	node, ok = rpt.Process.Nodes[report.MakeProcessNodeID("", "5")]
	if !ok {
		t.Errorf("Expected report to include the pid 5 tail")
	}
	if name, ok := node.Latest.Lookup(process.Name); ok {
		t.Errorf("Expected no name, but got %q", name)
	}
	if cmdline, ok := node.Latest.Lookup(process.Cmdline); !ok || cmdline != fmt.Sprint(processes[4].Cmdline) {
		t.Errorf("Expected %q got %q", processes[4].Cmdline, cmdline)
	}
}