| # Inspect discovery and hosting |
| |
| [Inspect][inspect] is a powerful diagnostics feature for Fuchsia Components. |
| |
| This document describes the details about how components host their |
| Inspect data and how various tools discover that data. |
| |
| ## Hosting Inspect data |
| |
| A component may expose Inspect data in the following ways: |
| |
| * [`fuchsia.inspect.Tree`](#tree) (C++, Rust) |
| * [`VmoFile`](#vmofile) (Dart) |
| * [`fuchsia.inspect.deprecated.Inspect`](#deprecated) (Go) |
| |
| Components do not need to reach out to other services in |
| order to expose Inspect data. |
| |
| Components generally do not need to be concerned with which method is |
| being used, client libraries abstract out the specific mechanism for |
| hosting. Nearly all implementations will eventually use `Tree`. |
| |
| | Feature | `fuchsia.inspect.Tree` | `VmoFile` | `fuchsia.inspect.deprecated.Inspect` | Description | |
| | ---------------------- | ---------------------- | --------- | ------------------------------------ | ----------------------------------------------------------------------------------- | |
| | Non-lazy values | Yes | Yes | Yes | Components may record values such as strings and integers. | |
| | Lazy values | Yes | No | Yes | Components may generate values dynamically at read time. | |
| | Mutable tree | Yes | Yes | Yes | Components may modify the values stored in their output. | |
| | Post-mortem inspection | Yes | Yes | No | The values recorded by a component are available after that component exits. | |
| | Low-latency snapshots | Yes | Yes | No | A full snapshot of the data can be obtained with low-latency. | |
| | Consistent snapshots | Yes\* | Yes | No | The snapshot of the tree is guaranteed to represent its state at one point in time. | |
| |
| (\*: Each tree's snapshot is consistent, but inter-tree consistency is not guaranteed) |
| |
| ### `fuchsia.inspect.Tree` {#tree} |
| |
| `fuchsia.inspect.Tree` supports all features of the Inspect API, and it |
| is the recommended way to expose Inspect data from components. |
| |
| Components publish `fuchsia.inspect.Tree` using the |
| `fuchsia.inspect.InspectSink` protocol. |
| |
| #### Implementation |
| |
| The `fuchsia.inspect.Tree` [FIDL File][tree-fidl] defines the protocol |
| that is hosted by components to expose their Inspect data. |
| |
| The `Tree` protocol links together multiple [Inspect VMOs][vmo-format] |
| in a "tree of trees." |
| |
| ![Figure: Example of trees](tree-example.png) |
| |
| In the above figure, the tree named "root" handles protocol |
| `fuchsia.inspect.Tree` for connections on the top-level service hosted |
| under `fuchsia.inspect.Tree`. Child trees may be enumerated |
| and opened using methods on the protocol. For example, "child B" may |
| not exist in memory until opened and read. |
| |
| The protocol supports this behavior in the following ways: |
| |
| * `GetContent` |
| |
| This method obtains the content of the tree, currently in the form of |
| an [Inspect VMO][vmo-format]. By convention, calling this method on |
| the root tree should return a VMO that will be continually updated |
| with new data. The client should not need to re-read the content of |
| the tree to read new values. |
| |
| * `ListChildNames` |
| |
| This method accepts an iterator over which the names of children of |
| the tree will be returned. For example, the tree in the figure above |
| will return names "child A" and "child B" when run on the root tree. |
| |
| * `OpenChild` |
| |
| This method accepts a request for `fuchsia.inspect.Tree` that will |
| be bound to the tree specified by a given name. Using this method a |
| client may iterate through all trees exposed over the root iterface. |
| |
| ### `fuchsia.inspect.deprecated.Inspect` {#deprecated} |
| |
| This deprecated interface is used by Go to expose Inspect data. While |
| `fuchsia.inspect.Tree` exposes a "tree of trees," this interface exposes |
| only a single tree where subtrees may be dynamically instantiated. |
| |
| This interface is deprecated in favor of the VMO format hosted by Inspect |
| tree for the following reasons: |
| |
| * VMO format supports low-latency snapshots without communicating with |
| the hosting program. |
| * VMO format snapshots are always consistent for the whole tree. |
| * VMO format supports postmortem inspection, all Inspect data using the |
| deprecated interface dies with the component. |
| * `Tree` protocol supports the same dynamic features as the deprecated |
| interface. |
| |
| ## Reading Inspect data |
| |
| The two primary ways to read Inspect data are: |
| |
| 1. [iquery](#iquery) |
| 2. The [Archivist](#archivist) |
| |
| ### iquery {#iquery} |
| |
| [iquery][iquery] (Inspect Query) is the CLI for interacting with Inspect data. |
| |
| `iquery`'s primary mode of operation takes a list of selectors for Inspect data |
| and prints out the contained information. A selector consists of three parts |
| which are separated by a `:`: |
| |
| 1. The component selector: This is the moniker in v2 or the realm path plus the |
| component name in v1. |
| 2. The node path: The path to a node in the inspect hierarchy. |
| 3. The property path: The name of the property. |
| |
| For `iquery` only (1) is required. If only (1) is provided (for example |
| `realm/component`) then iquery will use a selector `realm/component:*` to |
| fetch all the inspect data. |
| |
| `iquery` includes two utility commands to know what components are available and |
| what selectors can be used: |
| |
| - `list`: iquery will print all component selectors that are available, this is |
| all v2 monikers and all v1 realm paths with component names. |
| - `selectors`: iquery will print all selectors available under the provided |
| selector locations. |
| |
| These modes could be used together as follows: |
| |
| ``` |
| $ iquery show `iquery list | grep component_name` |
| ``` |
| |
| Alternatively `iquery` also allows to print the inspect data at a location. A |
| location consists either of the path to a `.inspect` file, or the path to a |
| directory containing `fuchsia.inspect.Tree`. `iquery` includes a utility command |
| to list all files that contain inspect data (`list-files`). |
| |
| iquery's secondary mode of operation (triggered by `list-files`) recursively |
| identifies locations for Inspect data from the given directory path. The |
| two modes may be used together as follows: |
| |
| ``` |
| $ iquery list-files [component_moniker] |
| bootstrap/driver_manager |
| class/display-coordinator/000.inspect |
| ... additional output |
| |
| |
| $ iquery show --file 'class/display-coordinator/000.inspect' |
| ``` |
| |
| In the example above, `iquery list-files` is ran to find a list of Inspect |
| locations. Then, `iquery` is ran on one of the output to |
| recursively list data in the matching locations. You may instead write: |
| |
| ``` |
| $ fx iquery show --manifest component_name |
| ``` |
| |
| ### Archivist {#archivist} |
| |
| The Fuchsia Diagnostics Platform, hosted by the [Archivist][archivist], |
| is responsible for monitoring and aggregating Inspect data on demand. |
| |
| When running under component manager, diagnostics data is made available to the |
| Archivist through [event capabilities][events]. |
| |
| The Archivist is offered events by the root realm. Therefore, it sees events from |
| the whole system. The events it is allowed to see and is subscribed to are the |
| following: |
| |
| - **CapabilityRequested**: sent to the Archivist instead of a regular Directory |
| connection when a component connects to `InspectSink` or `LogSink`. This allows |
| Archivist to know the monikers and URLs of the components connecting to these |
| protocols. |
| |
| A component that wishes to expose Inspect needs to use the `fuchsia.inspect.InspectSink` |
| protocol. This typically looks as follows: |
| |
| ```json5 |
| { |
| use: [ |
| { |
| protocol: "fuchsia.inspect.InspectSink", |
| from: "parent", |
| }, |
| ], |
| } |
| ``` |
| |
| There's a useful manifest include that simplifies this and is required by Inspect libraries: |
| |
| ```json5 |
| { |
| include: [ |
| "inspect/client.shard.cml", |
| ] |
| } |
| ``` |
| |
| #### Reading Inspect from the Archivist |
| |
| The Archivist hosts [`fuchsia.diagnostics.ArchiveAccessor`][archive], |
| which provides the `StreamDiagnostics` method to obtain Inspect data from |
| running components. |
| |
| [archive]: /sdk/fidl/fuchsia.diagnostics/reader.fidl |
| [archivist]: /src/diagnostics/archivist |
| [events]: /docs/concepts/components/v2/capabilities/event.md |
| [inspect]: /docs/development/diagnostics/inspect/README.md |
| [iquery]: /docs/reference/diagnostics/consumers/iquery.md |
| [tree-fidl]: /sdk/fidl/fuchsia.inspect/tree.fidl |
| [vmo-format]: /docs/reference/platform-spec/diagnostics/inspect-vmo-format.md |