# 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(fxbug.dev/84444): 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
