# Inspect Quickstart

This quickstart guides you through the basics of using
[Component Inspection][overview]. You will learn how to integrate Inspect into
your component using the language-specific libraries and review the data using
[`ffx inspect`][ffx-inspect].

For a more detailed walkthrough of Inspect concepts, see the
[Inspect codelab](codelab/codelab.md).

## Project setup

See below for the quick start guide in your language of choice:

* {C++}

  This section assumes you are writing an asynchronous component and that
  some part of your component (typically `main.cc`) looks like this:

  ```cpp
  async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
  auto context_ = sys::ComponentContext::CreateAndServeOutgoingDirectory();
  // ...
  loop.Run();
  ```

  This sets up an async loop, creates a `ComponentContext` wrapping handles
  provided by the runtime, and then runs that loop following some other
  initialization work.

  **Add the Inspect library dependencies to your `BUILD.gn` file:**

  ```gn
  {% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/diagnostics/inspect/cpp/BUILD.gn" region_tag="inspect_libs" adjust_indentation="auto" %}
  ```

  **Add the following includes:**

  ```cpp
  {% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/diagnostics/inspect/cpp/example_server_app.h" region_tag="inspect_imports" adjust_indentation="auto" %}
  ```

  **Add the following code to initialize Inspect:**

  ```cpp
  {% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/diagnostics/inspect/cpp/example_server_app.cc" region_tag="initialization" adjust_indentation="auto" %}
  ```

  You are now using Inspect! Create properties in the Inspect tree by attaching
  them to the root node:

  ```cpp
  {% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/diagnostics/inspect/cpp/example_server_app.cc" region_tag="properties" adjust_indentation="auto" %}
  ```

  Note: For a complete working example, see
  [//examples/diagnostics/inspect/cpp](/examples/diagnostics/inspect/cpp).

  See [Supported Data Types](#supported-types) for a full list of data
  types you can try.

  #### Health checks

  The health check subsystem provides a standardized inspection metric for
  component health. You can use the health node to report the overall status
  of your component:

  ```cpp
  {% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/diagnostics/inspect/cpp/example_server_app.cc" region_tag="health_check" adjust_indentation="auto" %}
  ```

  Note: For more details on health metrics, see [Health check][health-check].

  #### Testing

  To test your inspect code, you can use
  [//sdklib/inspect/testing/cpp/inspect.h](/sdk/lib/inspect/testing):

  ```cpp
  {% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/diagnostics/inspect/cpp/example_unittests.cc" region_tag="test_imports" adjust_indentation="auto" %}
  ```

  This library includes a full set of matchers to validate the contents of the
  Inspect tree.

  ```cpp
  {% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/diagnostics/inspect/cpp/example_unittests.cc" region_tag="inspect_test" adjust_indentation="auto" %}
  ```

* {Rust}

  This section assumes you are writing an asynchronous component and that some
  part of your component (typically `main.rs`) looks similar to this:

  ```rust
  async fn main() -> Result<(), Error> {
    // ...
    let mut service_fs = ServiceFs::new();
    // ...
    service_fs.take_and_serve_directory_handle().unwrap();
    service_fs.collect::<()>().await;
    Ok(())
  }
  ```

  **Add the Inspect library dependencies to your `BUILD.gn` file:**

  ```gn
  {% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/diagnostics/inspect/rust/BUILD.gn" region_tag="inspect_libs" adjust_indentation="auto" %}
  ```

  **Add the following code to initialize Inspect:**

  ```rust
  {% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/diagnostics/inspect/rust/src/echo_server.rs" region_tag="initialization" adjust_indentation="auto" %}
  ```

  You are now using Inspect! Create properties in the Inspect tree by attaching
  them to the root node:

  ```rust
  {% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/diagnostics/inspect/rust/src/echo_server.rs" region_tag="properties" adjust_indentation="auto" %}
  ```

  Note: For a complete working example, see
  [//examples/diagnostics/inspect/rust](/examples/diagnostics/inspect/rust).

  See [Supported Data Types](#supported-types) for a full list of data
  types you can try.

  #### Health checks

  The health check subsystem provides a standardized inspection metric for
  component health. You can use the health node to report the overall status
  of your component:

  ```rust
  {% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/diagnostics/inspect/rust/src/echo_server.rs" region_tag="health_check" adjust_indentation="auto" %}
  ```

  Note: For more details on health metrics, see [Health check][health-check].

  #### Testing

  To test your Inspect code, you can use `assert_data_tree` to validate the
  contents of the Inspect tree:

  ```rust
  {% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/diagnostics/inspect/rust/src/echo_server.rs" region_tag="inspect_test" adjust_indentation="auto" %}
  ```

  Note: To learn more about the Rust library, see the complete reference for
  [`fuchsia_inspect`](https://fuchsia-docs.firebaseapp.com/rust/fuchsia_inspect/index.html).


## Inspect Libraries {#inspect-libraries}

<!-- TODO(https://fxbug.dev/42165233): Replace code snippets with examples -->

Now that you have a `root_node` you may start building your
hierarchy. This section describes some important concepts and patterns
to help you get started.

* A Node may have any number of key/value pairs called **Properties**.
* The key for a Value is always a UTF-8 string, the value may be one of the
  [supported types](#supported-types) below.
* A Node may have any number of children, which are also Nodes.

* {C++}

  The code above gives you access to a single node named
  "root". `hello_world_property` is a Property that contains a string value
  (aptly called a **StringProperty**).

  * Values and Nodes are created under a parent Node.

  Class `Node` has creator methods for every type of
  supported value. `hello_world_property` was created using
  `CreateStringProperty`. You could create a child under the root node
  by calling `root_node.CreateChild("child name")`. Note that names must
  always be UTF-8 strings.

  * Values and Nodes have strict ownership semantics.

  `hello_world_property` owns the Property. When it is destroyed (goes
  out of scope) the underlying Property is deleted and no longer present
  in your component's Inspect output. This is true for child Nodes as well.

  If you are creating a value that doesn't need to be modified, use a
  [`ValueList`](/zircon/system/ulib/inspect/include/lib/inspect/cpp/vmo/types.h)
  to keep them alive until they are no longer needed.

  * Inspection is best-effort.

  Due to space limitations, the Inspect library may be unable to satisfy
  a `Create` request. This error is not surfaced to your code: you will
  receive a Node/Property object for which the methods are no-ops.

  * Pattern: Pass in child Nodes to child objects.

  It is useful to add an `inspect::Node` argument to the constructors
  for your own classes. The parent object, which should own its own
  `inspect::Node`, may then pass in the result of `CreateChild(...)`
  to its children when they are constructed:

  ```cpp
  class Child {
    public:
      Child(inspect::Node my_node) : my_node_(std::move(my_node)) {
        // Create a string that doesn't change, and emplace it in the ValueList
        my_node_.CreateString("version", "1.0", &values_);
        // Create metrics and properties on my_node_.
      }

    private:
      inspect::Node my_node_;
      inspect::StringProperty some_property_;
      inspect::ValueList values_;
      // ... more properties and metrics
  };

  class Parent {
    public:
      // ...

      void AddChild() {
        // Note: inspect::UniqueName returns a globally unique name with the specified prefix.
        children_.emplace_back(my_node_.CreateChild(inspect::UniqueName("child-")));
      }

    private:
      std::vector<Child> children_;
      inspect::Node my_node_;
  };
  ```

* {Rust}

  The Rust library provides two ways of managing nodes and properties: creation
  and recording.

  With the `create_*` methods, the ownership of the property or node object belongs
  to the caller. When the returned object is dropped, the property is removed.
  For example:

  ```rust
  {
      let property = root.create_int("name", 1);
  }
  ```

  In this example, `property` went out of scope so a drop on the property is
  called. Readers won't see this property.

  With the `record_*` methods, the lifetime of the property is tied to the parent
  node. When the node is deleted, the recorded property is deleted.

  ```rust
  {
      let node = root.create_child("name");
      {
        node.record_uint(2); // no return
      }
      // The uint property will still be visible to readers.
  }
  ```

  In this example, the uint property associated with `name` is visible to readers
  until the parent `node` goes out of scope.

### Dynamic values

This section describes support in the Inspect libraries for nodes that are
inflated lazily at read-time. The methods accept a callback function instead of
a value. The callback function is invoked when the property value is read.

* {C++}

  The C++ library has two property creators for dynamic values:
  `CreateLazyNode` and `CreateLazyValues`.

  Both of these methods take a callback returning a promise for an
  `inspect::Inspector`, the only difference is how the dynamic values are
  stored in the tree.

  `root->CreateLazyNode(name, callback)` creates a child node of
  `root` with the given `name`. The `callback` returns a promise for an
  `inspect::Inspector` whose root node is spliced into the parent hierarchy
  when read. The example below shows that a child called "lazy" exists with
  the string property "version" and has an additional child that is called
  "lazy."

  `root->CreateLazyValues(name, callback)` works like `root->CreateLazyNode(name,
  callback)`, except all properties and child nodes on the promised root node are
  added directly as values
  to the original `root`. In the second output of this example, the internal
  lazy nodes do not appear and their values are flattened into properties on
  `root`.

  ```cpp
  root->CreateLazy{Node,Values}("lazy", [] {
    Inspector a;
    a.GetRoot().CreateString("version", "1.0", &a);
    a.GetRoot().CreateLazy{Node,Values}("lazy", [] {
      Inspector b;
      b.GetRoot().RecordInt("value", 10);
      return fpromise::make_ok_promise(std::move(b));
    }, &a);

    return fpromise::make_ok_promise(std::move(a));
  });
  ```

  Output (CreateLazyNode):

  ```
  root:
    lazy:
      version = "1.0"
      lazy:
        value = 10
  ```

  Output (CreateLazyValues):

  ```
  root:
    value = 10
    version = "1.0"
  ```

  Warning: It is the developer's responsibility to ensure that names
  flattened from multiple lazy value nodes do not conflict. If they do,
  output behavior is undefined.

  The return value of `CreateLazy{Node,Values}` is a `LazyNode` that owns
  the passed callback.  The callback is never called once the `LazyNode` is
  destroyed. If you destroy a `LazyNode` concurrently with the execution of
  a callback, the destroy operation is blocked until the callback returns
  its promise.

  If you want to dynamically expose properties on `this`, you may simply
  write the following:

  ```cpp
  class Employee {
    public:
      Employee(inspect::Node node) : node_(std::move(node)) {
        calls_ = node_.CreateInt("calls", 0);

        // Create a lazy node that populates values on its parent
        // dynamically.
        // Note: The callback will never be called after the LazyNode is
        // destroyed, so it is safe to capture "this."
        lazy_ = node_.CreateLazyValues("lazy", [this] {
          // Create a new Inspector and put any data in it you want.
          inspect::Inspector inspector;

          // Keep track of the number of times this callback is executed.
          // This is safe because the callback is executed without locking
          // any state in the parent node.
          calls_.Add(1);

          // ERROR: You cannot modify the LazyNode from the callback. Doing
          // so may deadlock!
          // lazy_ = ...

          // The value is set to the result of calling a method on "this".
          inspector.GetRoot().RecordInt("performance_score",
                                        this->CalculatePerformance());

          // Callbacks return a fpromise::promise<Inspector>, so return a result
          // promise containing the value we created.
          // You can alternatively return a promise that is completed by
          // some asynchronous task.
          return fpromise::make_ok_promise(std::move(inspector));
        });
      }

    private:
      inspect::Node node_;
      inspect::IntProperty calls_;
      inspect::LazyNode lazy_;
  };
  ```

* {Rust}

  Refer to [C++ Dynamic Value Support](#c++), as similar concepts apply in Rust.

  Example:

  ```rust
  root.create_lazy_{child,values}("lazy", [] {
      async move {
          let inspector = Inspector::default();
          inspector.root().record_string("version", "1.0");
          inspector.root().record_lazy_{node,values}("lazy", || {
              let inspector = Inspector::default();
              inspector.root().record_int("value", 10);
              // `_value`'s drop is called when the function returns, so it will be removed.
              // For these situations `record_` is provided.
              let _value = inspector.root().create_int("gone", 2);
              Ok(inspector)
          });
          Ok(inspector)
      }
      .boxed()
  });

  Output (create_lazy_node):
  root:
    lazy:
      version = "1.0"
      lazy:
        value = 10

  Output (create_lazy_values):
  root:
    value = 10
    version = "1.0"
  ```

### String references {#string-reference}

* {C++}

  You can use `inspect::StringReference` to reduce the memory footprint
  of an Inspect hierarchy that has a lot of repeated data. For instance,

  ```cpp
  using inspect::Inspector;

  Inspector inspector;

  for (int i = 0; i < 100; i++) {
    inspector.GetRoot().CreateChild("child", &inspector);
  }
  ```

  Will include 100 copies of the string `"child"` in your inspect
  output.

  Alternatively,

  ```cpp
  using inspect::Inspector;
  using inspect::StringReference;

  namespace {
    const StringReference kChild("child");
  }

  Inspector inspector;
  for (int i = 0; i < 100; i++) {
    inspector.GetRoot().CreateChild(kChild, &inspector)
  }
  ```

  Will generate only one copy of `"child"` which is referenced 100 times.

  This saves 16 bytes for each child node, and has a cost of 32 bytes
  for the shared data. The net result is a savings of 1568 bytes.

  This pattern is recommended anywhere a global constant key would be used.

* {Rust}

  String names are automatically de-duplicated in Rust Inspect. For example,

  ```rust
  use fuchsia_inspect::Inspector;

  let inspector = Inspector::default();
  for _ in 0..100 {
    inspector.root().record_child("child");
  }
  ```

  Will generate only 1 copy of `"child"` which is referenced 100 times.

  This saves 16 bytes for each child node, and has a cost of 32 bytes
  for the shared data. The net result is a savings of 1568 bytes.

## Viewing Inspect Data {#view-inspect-data}

You can use the [`ffx inspect`][ffx-inspect] command to view the Inspect data
you exported from your component.

This section assumes you have SSH access to your running Fuchsia system and
that you started running your component. We will use the name
`my_component.cm` as a placeholder for the name of your component's manifest.

Note: Your component's full URL may be
`fuchsia-pkg://fuchsia.com/my_component#meta/my_component.cm`, but
you only need the manifest name to find it. This is separate from
your component's *[moniker]*, which is the location it is running in
the component hierarchy. You may refer to your component by either
moniker or manifest name.

### Read your Inspect data

The command below prints the inspect hierarchies of all components
running in the system:

```posix-terminal
ffx inspect show
```

Using the output from `ffx inspect list`, you can specify a
single component (for example, `my_component.cm`) as input to
`ffx inspect show`:

```posix-terminal
ffx inspect show --manifest my_component.cm
```

Specifying `--manifest` above will return data for all instances
of your component running on the system. If you know a specific
moniker of your component (for example, `core/my_component`) you
may pass that instead:

```posix-terminal
ffx inspect show core/my_component
```

You may specify multiple components (for example, `core/font_provider`
and `core/my_component`):

```posix-terminal
ffx inspect show core/font_provider core/my_component
```

You can also specify a node and property value. To see the
list of all possible [selectors], use `ffx inspect selectors`:

```posix-terminal
ffx inspect selectors core/my_component
```

You may then specify a selector (for example, `core/my_component:root`)
as input to `ffx inspect show`:

```posix-terminal
ffx inspect show core/my_component:root
```

If you don't know the moniker for your component, you may use
`--manifest` with a selector that applies to all matched component
monikers (using `*`):

```posix-terminal
ffx inspect show --manifest my_component.cm *:root
```

This will print out the following if you followed the suggested
steps above:

```none {:.devsite-disable-click-to-copy}
root:
  hello = world
```

## Supported Data Types {#supported-types}

 Type | Description | Notes
  -----|-------------|-------
    IntProperty | A metric containing a signed 64-bit integer. | All Languages
    UIntProperty | A metric containing an unsigned 64-bit integer. | Not supported in Dart
    DoubleProperty | A metric containing a double floating-point number. | All Languages
    BoolProperty | A metric containing a double floating-point number. | All Languages
    {Int,Double,Uint}Array | An array of metric types, includes typed wrappers for various histograms. | Same language support as base metric type
    StringArray | An array of strings. Represented as a [StringReference](#string-reference). | Not supported in Dart.
    StringProperty | A property with a UTF-8 string value. | All Languages
    ByteVectorProperty | A property with an arbitrary byte value. | All Languages
    Node | A node under which metrics, properties, and more nodes may be nested. | All Languages
    LazyNode | Instantiates a complete tree of Nodes dynamically. | C++, Rust

<!-- Reference links -->

[ffx-inspect]: https://fuchsia.dev/reference/tools/sdk/ffx.md#inspect
[health-check]: /docs/development/diagnostics/inspect/health.md
[overview]: /docs/development/diagnostics/inspect/README.md
[moniker]: /docs/reference/components/moniker.md
[selectors]: /docs/reference/diagnostics/selectors.md
