Diagnostics capabilities

This section provides guidance on migrating the capabilities for diagnostics features to Components v2.

Inspect

{% dynamic if user.is_googler %}

Note: If your component shares Inspect data in product feedback reports, you may also need to update the approved selectors to reference the new component moniker. For more details on updating feedback selectors, see go/tq-diagnostics-migration.

{% dynamic endif %}

If your component is using Inspect, you‘ll need to expose additional information to the framework. You can quickly determine if your component uses Inspect by looking for one of the following library dependencies in the component’s BUILD.gn:

  • //sdk/lib/sys/inspect/cpp
  • //src/lib/diagnostics/inspect/rust
  • dart_package_label.fuchsia_inspect

In Components v1, appmgr provides access to the component's /diagnostics directory, which contains Inspect data. Components v2 requires a component to explicitly expose /diagnostics to the framework. This allows the Archivist to read Inspect data for snapshots, ffx inspect, and more.

Note: For more details on the differences in data collection between Components v1 and Components v2, see the Archivist documentation.

When migrating the component manifest, you can add Inspect capabilities to your v2 component by including the following manifest shard:

// my_component.cml
{
    // Expose the diagnostics directory capability for Inspect
    include: [ "inspect/client.shard.cml" ],
    ...
}

Component moniker for selectors

If you added your component to core.cml, you can infer your component's moniker to be /core/component_name where component_name is the name of the child you added to core.cml.

You can see this hierarchy using ffx component list as well:

/
/bootstrap
/bootstrap/archivist
...
/core
...
/core/appmgr
/core/appmgr/app
/core/appmgr/app/sysmgr.cmx
/core/appmgr/app/sys
/core/appmgr/app/sys/build-info.cmx
/core/appmgr/app/sys/cobalt.cmx
...
/core/battery_manager
/core/font_provider
...
/startup

Alternatively you can use ffx inspect list to see available components for querying inspect data.

Inspect data in tests

If your test components read Inspect diagnostics data, migrate to the fuchsia.diagnostics.ArchiveAccessor service provided by the Archivist. Consider the following approaches you may be currently using from Components v1 to accomplish this:

  • Injected services. The test CMX contains fuchsia.diagnostics.ArchiveAccessor as an injected-service, reading isolated inspect data from an embedded Archivist limited to test components:

    {
        "fuchsia.test": {
            "injected-services": {
                "fuchsia.diagnostics.ArchiveAccessor":
                    "fuchsia-pkg://fuchsia.com/archivist-for-embedding#meta/archivist-for-embedding.cmx",
                ...
            }
        },
        ...
    }
    

    It means the test is reading isolated inspect data from an embedded Archivist that only sees test components.

  • Directly from the Hub.

In v2, there‘s an Archivist running inside each test. Instead of instantiating another Archivist in your test, you can use that embedded Archivist Accessor protocol directly in your test. Therefore you’ll need to do the following:

  1. When migrating tests, add the protocol capability to your test component:

    // my_component_test.cml (test component)
    {
        use: [
            {
                protocol: [ "fuchsia.diagnostics.ArchiveAccessor" ],
            },
        ]
    }
    
  2. Update your program to use the ArchiveReader library, which is available in C++, Rust, and Dart. See the Inspect Codelab for more details on using these libraries.

    Note: For components in other languages, use the ArchiveAccessor FIDL protocol directly.

  3. Update any monikers used in your test's diagnostic selectors.

    • If you declare a child component in the test CML, check the Integration Testing docs to learn more about your moniker.
    • If you are using RealmBuilder, check the Realm Builder docs to learn more about your moniker.

Logging

If your component requires access to logging, you'll need to declare the fuchsia.logger.LogSink capability in your manifest. In Components v1, you may have included diagnostics/syslog/client.shard.cmx or referenced the protocol directly under services in your CMX file.

You can add syslog capabilities to your v2 component by including the following manifest shard:

// my_component.cml
{
    // Expose the LogSink capability for syslog
    include: [ "syslog/client.shard.cml" ],
    ...
}

Additionally, Components v1 redirects stderr and stdout to debuglog, but in Components v2 they have no default destination. The debuglog is typically used for low-level debugging information from the kernel and device drivers. If your component writes log data to these streams, consider the following:

  • Redirect to syslog: Forward print statements to use the system's standard syslog buffer instead. This buffer is larger and capable of attributing logs per-component.
  • Redirect to debuglog: If you have integration tests or other use cases that require preserving the default Components v1 behavior for log messages, direct the streams back to the debuglog buffer.

Redirecting to syslog

To send stderr and stdout to syslog in your v2 component, you'll need to configure the ELF runner to forward the streams. This enables forwarding for all print statements, including those generated by libraries or runtime code.

When migrating your component manifest, include the following manifest shard to enable forwarding:

// my_component.cml
{
    // Enable forwarding of stdio to syslog
    include: [ "syslog/elf_stdio.shard.cml" ],
    ...
}

Note: Logging directly to syslog from your code provides additional features to your component, such as severity levels. To take advantage of these features, consider migrating your code to use the logging libraries highlighted in the syslog documentation.

Redirecting to debuglog

Your component may have external dependencies that rely on log messages in debuglog. One common use case is integration tests that directly parse log messages from the stdout of an emulator process using the emulatortest framework. In these cases, you'll need to manually direct log messages back to the debuglog buffer.

  1. When migrating your component manifest, request the fuchsia.boot.WriteOnlyLog capability.

    // my_component.cml
    {
        use: [
            ...
            {
                protocol: [
                    "fuchsia.boot.WriteOnlyLog",
                ],
            },
        ],
    }
    
  2. When adding your component, add the following to offer this capability to your component from core:

    // core.cml / component.core_shard.cml
    {
        offer: [
            ...
            {
                protocol: [ "fuchsia.boot.WriteOnlyLog" ],
                from: "parent",
                to: [ "#my_component" ],
            },
        ],
    }
    
  3. Direct stderr and stdout to debuglog in your program. You can use libraries for the initialization if your component is written in Rust or C++.

    Note: If the component isn't written in C++ or Rust you can use the existing libraries as a template for how to perform the initialization.

Hub

The hub provides access to detailed structural information about component instances at runtime. In Components v1, appmgr provides the v1 Hub through a specific directory structure populated in your component's namespace under /hub. In Components v2, many v1 Hub use cases have preferred alternative approaches.

When migrating to Components v2, consider the following alternatives:

  • Observing lifecycle events: Clients watching the filesystem to observe component instance changes should use event capabilities instead.
  • Reading inspect data: Clients reading Inspect data from out/diagnostics should migrate to the fuchsia.diagnostics.ArchiveAccessor service instead.
  • Connecting to exposed services: Clients connecting to services exposed through a component's out/svc directory should route these services and capability providers into their tests instead, similar to injected-services.

For other use cases, follow the instructions in this section to migrate to the v2 Hub provided by Component Manager.

Note: Features of the Hub are designed to support test components only. If you need to access the Hub outside of the test realm, reach out to component-framework-dev for assistance.

Route the hub directory

When migrating tests, you'll need to route the hub directory capability to your test component if any components in the test realm need to read data from the v2 Hub.

Following the example in Test uses injected services, add the hub directory capability to your CML file:

//my_component_test.cml
{
    use: [
        {
            directory: "hub",
            from: "framework",
            rights: [ "r*" ],
            path: "/hub",
        },
    ]
}

Update hub reference paths

Update your code to reference the content path from the v2 Hub directory structure. Here are some examples of path differences between the Hub implementations:

v1 Hub Pathv2 Hub Path
/hub/c/{{ '<var>' }}component-name{{ '</var>' }}/{{ '<var>' }}instance-id{{ '</var>' }}/url/hub/url
/hub/c/{{ '<var>' }}component-name{{ '</var>' }}/{{ '<var>' }}instance-id{{ '</var>' }}/in/{{ '<var>' }}svc-path{{ '</var>' }}/hub/exec/in/{{ '<var>' }}svc-path{{ '</var>' }}
/hub/c/{{ '<var>' }}component-name{{ '</var>' }}/{{ '<var>' }}instance-id{{ '</var>' }}/process-id/hub/exec/runtime/elf/process-id
/hub/c/{{ '<var>' }}child-component{{ '</var>' }}/hub/children/{{ '<var>' }}child-component{{ '</var>' }}

Note: The hub directory routed to your component is scoped to the current realm. To access hub contents from the parent realm, route the hub from parent instead of framework. This feature is not available with the v1 Hub.

What's next

Explore the following sections for additional migration guidance on specific features your components may support: