53 Commits

Author SHA1 Message Date
Bryan Boreham
dc14bd04df Exit joinResults.result() if context cancelled
These can be long-running operations, and if the client retries we get
the cancelled one running in parallel with the retry, slowing both down
and making it likely the next one will time out too.
2021-04-22 10:53:06 +00:00
Bryan Boreham
871751873b Stop render package depending on probe
This dependency makes it harder to see the structure of the program,
and sometimes complicates compilation.

Mostly just changing the source of strings that are already exported
from the report package.  A few new strings have to be moved there,
plus the function `IsPauseImageName()`.
2019-09-15 17:03:04 +00:00
Bryan Boreham
3be8cf71dd Add more Opentracing detail to the app (#3383)
* Pass Go context down to Renderers

This is useful for cancellation or tracing.

* Add tracing spans to app

Also log things like number of nodes in Map, total number of reports.
2018-10-26 11:21:33 +05:30
Alfonso Acosta
0a5fb7aad3 Remove ProcessWithContainerNameRenderer, it wasn't working (#3263) 2018-07-13 13:34:37 +02:00
Matthias Radestock
15b605f804 make process-by-name topology show something (again)
...when 'Hide Unconnected' is selected, which is the default.

Here's the problem...

The connectedness filter looks for `is_connected` marks in the Latest
map of the nodes. The mark is added by ColorConnected, which is
invoked by ProcessRenderer. That in turn is the base renderer for
ProcessNameRenderer, which is what the process-by-name view
renders. However, the process2Names mapping does not propagate any
metadata, hence there are no `is_connected` marks on the result
nodes. Consequently they are all filtered out.

The problem was introduced in #3009, when I added the ability for
users to chose whether to show or hide unconnected
processes (previously unconnected processes were always hidden) -
looks like I failed to check that the process-by-name view was working
with the new filter. Oops.

The fix is to move the ColorConnected call from ProcessRenderer to the
higher-level renderers - ProcessWithContainerNameRenderer (which is
what the 'Processes' view renders) and ProcessNameRenderer.

This has the beneficial side effect of improving performance for other
renderers which invoke ProcessRenderer, none of which need
connectedness-coloring.

Fixes #3205
2018-06-03 07:01:40 +01:00
Matthias Radestock
fd5fa7a962 refactor: extract common code in endpoint mapping
This isn't quite as neat as we'd want to make it, because two of the
three call sites still require a closure, but it's still an
improvement.

Note that every instance of MapEndpoints only ever maps to one
topology, which, furthermore, is a core report topology. Hence we can
just parameterise MapEndpoints with that topology, and then the map
functions can return just the node ids.
2018-01-07 08:20:06 +00:00
Matthias Radestock
3582c221fe processes are now always linkable 2018-01-02 09:47:15 +00:00
Matthias Radestock
c8ea7ba49e refactor: simplify joinResults.add*
After dropping extra metadata in the rest of this PR, our usage of
joinResults.add* only ever ends creating minimal nodes, from just an
id and topology. Hence joinResults.add* can be invoked with simply an
id and topology instead of a generic node creation function.
2017-12-29 14:40:18 +00:00
Matthias Radestock
a7b6bb09a1 refactor: lift closures and extract constants 2017-12-29 14:40:18 +00:00
Matthias Radestock
a3ba3a5a55 don't propagate Name in processes2Names
The name is already the id of the node, and that's what summarisation
renders. Nothing looks at process.Name.
2017-12-28 12:50:11 +00:00
Matthias Radestock
d7e90303a6 don't propagate PID in endpoints2Processes
The 'create' function passed to addChild is only ever invoked when we
cannot find a matching process in the process topology. In these cases
the host and pid will be _all_ the info we are ever going to have,
both of which are incorporated in the id. Node summarisation renders
that as best it can; adding the PID as metadata does not make a
difference but for a line with that info in the detail panel, which
adds nothing since the PID is already included in the label.
2017-12-28 12:50:11 +00:00
Matthias Radestock
27c2f3a5d2 refactor: use propagateLatest
instead of the equivalent long-hand code.
2017-12-28 12:50:11 +00:00
Matthias Radestock
e69c8209fb remove redundant operation
We were setting the very same k/v that we just looked up.
2017-12-28 12:50:11 +00:00
Matthias Radestock
56a1efd38a optimisation: pre-allocate some maps
This doesn't make much of a difference, since we don't create many of
these. But it's easy enough to do, and every little helps.
2017-12-26 00:35:02 +00:00
Matthias Radestock
ceb3539d35 ensure hostNodeIDs actually are what they claim
It's a dynamic type check of sorts.

In the process we stop abusing ParseNodeID for extracting the host,
which in turn allows us to clarify its purpose.
2017-12-25 18:14:34 +00:00
Matthias Radestock
a6f24fc151 remove superfluous lookups
Since we seed the joinResult with the nodes from the topology we are
mapping to, we know the 'create' function is only called when there is
no node with the specified id.

This neatly makes the 'create' function only do what it says,
i.e. return _new_ nodes.
2017-12-17 18:24:32 +00:00
Matthias Radestock
ac87c2b6e8 optimise & simplify node propagation in joinResult
Instead of copying unmatched nodes at the end, and matched nodes when
we encounter them, copy *all* nodes at the beginning.
2017-12-17 18:14:48 +00:00
Matthias Radestock
f16908aea9 refactor: fix up adjacencies as part of joinResult.result() 2017-12-17 18:14:47 +00:00
Matthias Radestock
e5117a652f remove superfluous fixupAdjacencies calls
fixupAdjacencies fixes up adjancencies of mapped nodes. The nodes at
the call sites we are removing aren't mapped.
2017-12-17 18:14:30 +00:00
Matthias Radestock
cc859926ef tiny simplifying refactor 2017-12-17 15:36:28 +00:00
Matthias Radestock
20138b9218 don't exclude NATed connections in mapping to processes
We used to ignore source endpoints that are associated with multiple
destination endpoints, which is a partial workaround for our inability
to correctly represent two connections from the same source ip/port
but different processes, or the same destination ip/port but different
processes. See #2665.

However, that condition is too coarse. In particular, we end up
ignoring endpoints that are connected to NATed destinations, since the
latter are represented by two (or more) endpoints.

The change here corrects that.
2017-12-15 11:40:43 +00:00
Matthias Radestock
956303694a always apply ColorConnected in process renderers
This eliminates the awkward distinction between ProcessRenderer and
ColorConnectedProcessRenderer.

It also ensures that processes resulting from direct rendering of the
process topology (/api/topology/processes is invoking
ProcessWithContainerNameRenderer and /api/topology/processes-by-name
is invoking ProcessNameRenderer) are colored and hence summarising
them correctly sets the 'linkable' property. This was the behaviour
prior to the revamping of the rendering pipeline. However, it doesn't
actually make a practical difference since process detail panels only
show other processes as connection endpoints, and these are always
marked linkable anyway.
2017-11-28 06:54:15 +00:00
Bryan Boreham
3e62f7b754 Rewrite MapProcess2Name to process all nodes in one pass
This is more efficient as there are typically many fewer names than
processes.
2017-11-22 10:33:00 +00:00
Matthias Radestock
346a0360ef Refactor: split addToResults into two functions
This is preparatory to future refactorings: all existing calls are to
Endpoints which have no children and where we don't want a Counter.

We make addChildAndChildren an obvious extension of addChild even
though it adds a dead code path (we never call addChildAndChildren
with an endpoint).
2017-11-22 10:30:18 +00:00
Matthias Radestock
ae153e57f5 refactor: remove Decorator from render.Renderer.Render() signature 2017-11-18 18:04:52 +00:00
Matthias Radestock
9bd8bd825b remove now superfluous Renderer.Stats method
step 2 (and final step) in producing stats as part of Rendering
2017-11-08 07:15:28 +00:00
Matthias Radestock
8f7e00f46a Stats are easily produced as part of Rendering
...so there is no need for a separate Stats method.

step 1: return stats from Render
2017-11-08 07:15:28 +00:00
Bryan Boreham
ec0689b5aa Code review: improve consistency of naming and ordering 2017-11-06 22:12:13 +00:00
Bryan Boreham
4feb451760 Refactor join-Renderer helper functions as methods
New type joinResult is created to hold the nodes and ID mapping.
The implementation move from host.go to render.go.
2017-11-06 22:12:13 +00:00
Bryan Boreham
cbba3c0fd3 Clarify use of 'id' in addToResults
Pass 'id' through to the create function and expect that the result Node has that ID.
Extract a function newPseudoNode for common calls.
2017-11-06 22:12:13 +00:00
Bryan Boreham
322aa76e02 Remove functions which are no longer called 2017-11-06 22:12:10 +00:00
Bryan Boreham
cbcb5f19fc Rewrite ProcessRenderer/MapEndpoint2Process as a single Renderer
This is much more efficient as we skip creating then merging all intermediate Nodes
2017-11-06 22:06:29 +00:00
Bryan Boreham
1b3e40ccb5 Refactor: extract pseudoNodeID function 2017-11-06 22:04:59 +00:00
Matthias Radestock
5f4f9da4df memoise a few more shared renderers 2017-11-05 00:21:45 +00:00
Matthias Radestock
b793a9efa8 memoise shared top-level renderers
and add a comment indicating non-memoisation of other, not shared
top-level renderers.

This memoisation is effective when the browser requests multiple
topologies for the same report.
2017-11-04 23:05:52 +00:00
Matthias Radestock
708931f98a ignore endpoints with >1 adjacency in process rendering
This eliminates the worst effects of #2665.
2017-06-29 22:34:05 +01:00
Matthias Radestock
e5a04ec5a4 do not filter endpoints by procspied/ebpf in renderers
The filtering of endpoints causes some connections to get missed for
non-eBPF-tracked connections. Furthermore, the filtering of endpoints
is entirely pointless when the probes run eBPF since the filters just
pass through eBPF-tracked endpoints (for good reason too; because
otherwise some connections would be missed). So in that case it is
just costing CPU and removing it actually improves performance.

Note that removing the filtering does not result in over-counting
connections since that is done by source ip:port pairs.

Fixes #2551.
Fixes #2558.
2017-06-27 20:28:13 +01:00
Matthias Radestock
d66b28de2a performance: only color connected once
ProcessRenderer was coloring connected nodes because we need that info
for rendering details panels. However, the main process topology view
renderers depending on ProcessRenderer were also doing coloring
themselves. For the 'processes' topology that was literally
duplicating work. For the 'processes-by-name' topology that was
throwing away the process coloring, and then coloring at the name
level.

Solution: remove the coloring from the ProcessRenderer, thus
eliminating the duplicate/thrown-away work, and introduce a
ColorConnectedProcessRenderer which is only used in places that
populate details panels.
2017-06-22 10:28:39 +01:00
Matthias Radestock
afbc1decab drop addr and port from Endpoint.Latest map
the information is constant and already present in the id, so we can
extract it from there.

That reduces the report size and improves report encoding/decoding
performance. It should reduce memory usage too and improve report
merging performance too.

NB: Probes with this change are incompatible with old apps.
2017-06-10 19:19:56 +01:00
Matthias Radestock
707add13a3 refactor: simplify some filters 2017-06-04 16:10:21 +01:00
Iago López Galeiras
9920c4ea48 Add eBPF connection tracking without dependencies on kernel headers
Based on work from Lorenzo, updated by Iago, Alban, Alessandro and
Michael.

This PR adds connection tracking using eBPF. This feature is not enabled by default.
For now, you can enable it by launching scope with the following command:

```
sudo ./scope launch --probe.ebpf.connections=true
```

This patch allows scope to get notified of every connection event,
without relying on the parsing of /proc/$pid/net/tcp{,6} and
/proc/$pid/fd/*, and therefore improve performance.

We vendor https://github.com/iovisor/gobpf in Scope to load the
pre-compiled ebpf program and https://github.com/weaveworks/tcptracer-bpf
to guess the offsets of the structures we need in the kernel. In this
way we don't need a different pre-compiled ebpf object file per kernel.
The pre-compiled ebpf program is included in the vendoring of
tcptracer-bpf.

The ebpf program uses kprobes/kretprobes on the following kernel functions:
- tcp_v4_connect
- tcp_v6_connect
- tcp_set_state
- inet_csk_accept
- tcp_close

It generates "connect", "accept" and "close" events containing the
connection tuple but also pid and netns.
Note: the IPv6 events are not supported in Scope and thus not passed on.

probe/endpoint/ebpf.go maintains the list of connections. Similarly to
conntrack, it also keeps the dead connections for one iteration in order
to report short-lived connections.

The code for parsing /proc/$pid/net/tcp{,6} and /proc/$pid/fd/* is still
there and still used at start-up because eBPF only brings us the events
and not the initial state. However, the /proc parsing for the initial
state is now done in foreground instead of background, via
newForegroundReader().

NAT resolution on connections from eBPF works in the same way as it did
on connections from /proc: by using conntrack. One of the two conntrack
instances is only started to get the initial state and then it is
stopped since eBPF detects short-lived connections.

The Scope Docker image size comparison:
- weaveworks/scope in current master:  22 MB (compressed),  68 MB
  (uncompressed)
- weaveworks/scope with this patchset: 23 MB (compressed), 69 MB
  (uncompressed)

Fixes #1168 (walking /proc to obtain connections is very expensive)

Fixes #1260 (Short-lived connections not tracked for containers in
shared networking namespaces)

Fixes #1962 (Port ebpf tracker to Go)

Fixes #1961 (Remove runtime kernel header dependency from ebpf tracker)
2017-03-08 22:11:12 +01:00
Filip Barl
2e9255b190 Addressed the comments and fixed the tests. 2017-02-20 11:40:40 +01:00
Alfonso Acosta
0a135e6330 Check for known services before external IPs
Known services can be internal (e.g. same VPC in AWS)
2017-01-31 15:37:57 +00:00
Matthias Radestock
5ce5d541d3 show forward DNS name for internet addresses
...if available.

Follow-up to #1863.
2016-09-22 21:01:44 +01:00
Alfonso Acosta
c5ac315b38 Review feedback 2016-09-20 16:50:29 +00:00
Alfonso Acosta
028ed32b6f Simplify service node matching 2016-09-19 14:38:59 +00:00
Alfonso Acosta
5c080ec062 Add pseudo-nodes for known services
AWS S3 and Dynamo to start with
2016-09-19 14:38:58 +00:00
Matthias Radestock
1091225bf6 get rid of Node.Copy()
A shallow copy is sufficient. Which we get for free in most cases
since Node is passed around by value.
2016-08-02 12:42:39 +00:00
Tom Wilkie
c80eb42a4f Add filters for pseudo nodes. (#1581)
* Add filters for pseudo nodes.

- Don't filter the internet node as a pseudo node.
- Rename pseudo filter to unmanaged/uncontained.
- Review feedback
- Move the FilterFoo funcs into the tests
- Drop the 'nodes' from filter labels.

* Fix experimental
2016-06-16 20:09:13 +01:00
Tom Wilkie
8f772a696d Add flag to disable reporting of processes (and procspied endpoints) 2016-05-17 17:29:09 +01:00