Diagnostics

Fuchsia has several observability systems that help you perform diagnostics on a component, such as:

Logs

Logs are time-ordered streams of diagnostic data emitted by Fuchsia programs. They most commonly take the form of low frequency human-oriented text strings describing changes to state in a subsystem.

Contents

A log contains several pieces of metadata that is mostly self-reported by each component that generates a specific log. At a minimum, a log message contains a timestamp and string contents.

Additionally, if a log message is written to the LogSink protocol using the supported libraries it includes a severity, a PID, a TID, a count of prior dropped logs, and a list of string tags. Not all of the metadata is required, but the supported libraries ensure that every field has a value when writing records to the socket obtained through LogSink.

Archivist inserts additional metadata to the data that a component writes to a socket. For more information about the fields that Archivist provides for a Fuchsia device log, see Log records.

Storage

Currently all log stores are rotated on a first-in-first-out (FIFO) basis, with newer messages overwriting older ones. Messages from any component can roll out messages from any other component.

Logs in Fuchsia can be stored in the following types of memory:

Volatile

There are two in-memory stores for logs on a Fuchsia device:

As you work with logs, it is important to understand how Fuchsia writes logs, so that you can better locate where a log may be stored as it explains which of these buffers is the intended point of transit for your message.

Persistent

The feedback data component maintains a persistent_disk_store of messages from the previous boot of the system.

You can see these messages when targeting your Fuchsia device with ffx target snapshot.

Work with Logs

To begin working with logging, you may want to:

Inspect

Inspect provides components with the ability to expose structured, hierarchical information about their state at runtime. Components host a mapped Virtual Memory Object (VMO) using the Inspect Format to expose an Inspect Hierarchy containing this internal state. Note: For more information about the Inspect VMO file format, see Inspect VMO file format.

Work with Inspect

To begin working with Inspect, you may want to:

Archivist

Archivist ingests data from Inspect and Fuchsia logs, making them available over the fuchsia.diagnostics/ArchiveAccessor protocol.

The Archivist ingests lifecycle events from the Component Framework through fuchsia.component.EventStream:

  • Capability requested: The Archivist receives Capability requested events for connections to fuchsia.logger.LogSink and fuchsia.inspect.InspectSink which allows it to attribute Inspect and logs.

CapabilityRequested event

CapabilityRequested event is the mechanisms that provide logs and Inspect with attribution metadata such as the moniker and component URL.

Archivist-manifest exposes fuchsia.logger.LogSink just like any other protocol capability, but it also uses an event from the framework, binding it to a protocol in its namespace:

To better understand how this works, take a look at the Archivist's CML file:

// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This shard is meant to contain stuff that is meant to be shared across all flavors of the
// archivist.
{
    include: [ "//src/diagnostics/archivist/meta/config.shard.cml" ],
    program: {
        runner: "elf",
        lifecycle: { stop_event: "notify" },
    },
    capabilities: [
        {
            dictionary: "diagnostics-accessors",
            path: "/svc/fuchsia.component.sandbox.DictionaryRouter",
        },
        {
            protocol: [
                "fuchsia.diagnostics.LogSettings",
                "fuchsia.diagnostics.LogStream",
                "fuchsia.inspect.InspectSink",
                "fuchsia.logger.Log",
                "fuchsia.logger.LogSink",
            ],
        },
    ],
    use: [
        {
            event_stream: [ "capability_requested" ],
            from: "parent",
            path: "/events/log_sink_requested_event_stream",
            filter: { name: "fuchsia.logger.LogSink" },
        },
        {
            event_stream: [ "capability_requested" ],
            from: "parent",
            path: "/events/inspect_sink_requested_event_stream",
            filter: { name: "fuchsia.inspect.InspectSink" },
        },
        {
            protocol: [ "fuchsia.tracing.provider.Registry" ],
            availability: "optional",
        },
        {
            protocol: [ "fuchsia.inspect.InspectSink" ],
            from: "self",
        },
        {
            protocol: [ "fuchsia.component.sandbox.CapabilityStore" ],
            from: "framework",
        },
    ],
    expose: [
        {
            protocol: [
                "fuchsia.diagnostics.LogSettings",
                "fuchsia.diagnostics.LogStream",
                "fuchsia.inspect.InspectSink",
                "fuchsia.logger.Log",
                "fuchsia.logger.LogSink",
            ],
            from: "self",
        },
        {
            dictionary: "diagnostics-accessors",
            from: "self",
        },
    ],
}

This causes Component Manager to redirect incoming requests from the default fuchsia.io namespace protocol to the fuchsia.component.EventStream protocol. Archivist receives events on this protocol, retrieving attribution metadata from the EventHeader sent by Component Manager along with the LogSink channel's handle. The moniker included in the descriptor is constructed in the event header.

Configuring a capability_requested event for LogSink does not affect capability routing itself, only the delivery of the channel to the Archivist as an Event instead of as an Open(). This means that the CML for passing the attributed LogSink remains the same for the rest of the component topology. For more information, see Life of a protocol open and the events documentation.

Attributing LogSink connections

When a Fuchsia component wants to write logs, it must obtain a connection to a fuchsia.logger.LogSink in its incoming directory, typically provided by an instance of the Archivist.

Typical Fuchsia service connections are anonymous such that the server and client have no identifying information about each other. The client only sees the service in its namespace, e.g. /svc/fuchsia.logger.LogSink, and the server sees an anonymous Open() request to its incoming namespace.

Attributed logging provides trustworthy attribution metadata to allow for better monitoring, storage, querying, and presentation of logs. This attribution metadata identifies the source of an incoming LogSink connection, which is accomplish through the CapabilityRequested event.