blob: 9a2da9d47d4dfa4e5d0c76716b6c8e01d55e285f [file] [log] [blame] [view]
# Netstack Inspect Data
Netstack exposes useful debugging information as inspectable data that can be
retrieved from snapshots (`inspect.json` within snapshots created by `fx
snapshot`) or by using the `iquery` tool (`fx iquery`).
In this document we list useful example queries into the inspect data that
netstack exposes.
We'll use the [`jq`] tool throughout, all queries can be used from an
`inspect.json` or `fx iquery --format=json` by piping either into `jq`, e.g.:
```
cat snapshot/inspect.json | fx jq '...'
```
```
fx iquery --format=json show netstack.cmx | fx jq '...'
```
## Inspect data
There are different sources of inspect data in Netstack, referenced by their
payload keys.
### Socket Info
`Socket Info` contains information of all currently open sockets, keyed by
socket identifier, e.g.:
```json
{
"12345": {
"NetworkProtocol": "IPv6",
"TransportProtocol": "UDP",
"State": "BOUND",
"LocalAddress": "[fe80::8d88:9942:4f32:7259]:546",
"RemoteAddress": ":0",
"BindAddress": "",
"BindNICID": "5",
"RegisterNICID": "5",
"Stats": { ... }
}
}
```
To retrieve all sockets from inspect data use:
```
fx jq '.[] | select(.moniker == "netstack.cmx") | .payload."Socket Info" | .[]?'
```
### NICs
`NICs` contains information about each of the network interfaces presently
installed in the netstack, keyed by their interface identifier, e.g:
```json
{
"2": {
"Name": "wlanx62",
"NICID": "3",
"AdminUp": "true",
"LinkOnline": "true",
"Up": "true",
"Running": "true",
"Loopback": "false",
"Promiscuous": "false",
"LinkAddress": "44:07:0b:e2:cf:62",
"ProtocolAddress0": "[arp] 617270/0",
"ProtocolAddress1": "[ipv4] 192.168.0.23/24",
"ProtocolAddress2": "[ipv6] fe80::916b:7615:6b2e:f8b3/64",
"ProtocolAddress3": "[ipv6] fe80::4607:bff:fee2:cf62/128",
"DHCP enabled": "true",
"MTU": 1500,
"Ethernet Info": { ... },
"DHCP Info": { ... },
"Stats": { ... }
}
}
```
To retrieve all NICs from inspect data use:
```
fx jq '.[] | select(.moniker == "netstack.cmx") | .payload."NICs" | .[]?'
```
To look at a single NIC with `id` or `name` simply append `| select(.NICID ==
"id")` or `| select(.Name == "name")`, respectively.
### Networking Stat Counters
`Networking Stat Counters` contain stack-global counters for traffic and errors,
e.g.:
```json
{
"UnknownProtocolRcvdPackets": 0,
"MalformedRcvdPackets": 0,
"DroppedPackets": 0,
"UDP": {
"PacketsReceived": 51551,
"UnknownPortErrors": 30509,
...
},
"TCP": {
"ActiveConnectionOpenings": 4443,
"PassiveConnectionOpenings": 53,
...
},
"IP": {...},
"ICMP": {...}
}
```
To get counters use:
```
fx jq '.[] | select(.moniker == "netstack.cmx")
| .payload."Networking Stat Counters"
| select(. != null)'
```
You can append `| .TCP `, or `| .UDP` to look at only the subset of interest if
needed.
## pprof
Netstack exposes [`pprof`] data that can be used to gather more information from
the Go runtime.
A typical snapshot will contain periodic `pprof` data which is gathered at set
intervals. You can query the available `pprof` information with:
```
fx jq -c '.[] | select(.moniker == "netstack.cmx")
| select(.payload.root.pprof != null)
| {file: .metadata.filename, keys: (.payload.root.pprof | keys)}'
```
Which will generate output like
```
{"file":"pprof/2020-10-22T16:21:49Z.inspect","keys":["allocs","block","goroutine","heap","mutex","threadcreate"]}
{"file":"pprof/now.inspect","keys":["allocs","block","goroutine","heap","mutex","threadcreate"]}
{"file":"pprof/2020-10-22T16:19:49Z.inspect","keys":["allocs","block","goroutine","heap","mutex","threadcreate"]}
{"file":"pprof/2020-10-22T16:20:49Z.inspect","keys":["allocs","block","goroutine","heap","mutex","threadcreate"]}
```
Each of the `pprof` profiles is encoded in base64. The following line gets all
the `pprof` files and decodes them at once (remember to either pipe in your
`inspect` data or add path to your inspect file after the `jq` command):
```bash
fx jq -rc '.[]
| select(.moniker == "netstack.cmx")
| select(.payload.root.pprof != null)
| . as $parent
| (.payload.root.pprof | to_entries | .[] | ($parent | .metadata.filename) + "_" + .key + " " + .value)' | \
while read f c; do echo $c | sed s/b64://g | base64 -d > $(echo $f | sed 's/pprof\///g'); done
```
You can modify the selector `.payload.root.pprof != null` and append `and
.metadata.filename == "pprof/now.inspect"` to only get the latest profile.
[`jq`]: https://stedolan.github.io/jq/
[`pprof`]: https://github.com/google/pprof