Recording Logs

There are a few ways that a Fuchsia component generates log messages:

  • The fuchsia.logger.LogSink protocol.
  • The kernel's debuglog.
  • A combination of the above, routed through stdout or stderr.

LogSink/syslog

Components that want to generate log messages should connect to the fuchsia.logger.LogSink protocol and then handle the fuchsia.logger.LogSink/OnInit event. The fuchsia.logger.LogSink protocol must be used in the component manifest. This protocol is routed as part of the diagnostics dictionary. A component must have the fuchsia.logger.LogSink protocol routed to it directly so it can use it form parent, or more commonly, have the full diagnostics dictionary routed to it, in which case it can use the fuchsia.logger.LogSink protocol from parent/diagnostics.

The OnInit event includes an IOBuffer which is used to actually send log messages. If the IOBuffer is full, logs will be dropped. If there are any dropped log messages on the writer side, these are counted and that count is sent in the next successful message, after which the counter is reset. ffx log prints a warning when it's aware of dropped messages. The LogSink server must ensure the IOBuffer has sufficient space to prevent messages being dropped on the writer-side.

Different languages use different mechanisms to connect to LogSink:

debuglog handles

The kernel allows components to create debuglog handles from the root resource. Each handle allows its owner to write messages into the kernel's shared ring buffer. Each message has a limit of ZX_LOG_RECORD_DATA_MAX bytes, with content in excess being truncated.

In addition to being bindable to file descriptors, debuglog handles can be passed to the debuglog_write and debuglog_read syscalls.

If a component needs to send its standard streams to the debuglog, it must have the fuchsia.boot.WriteOnlyLog routed to it.

Most logs written to debuglog handles are written through stdio forwarding.

Standard streams: stdout and stderr

While these concepts may be familiar to you from other operating systems, their use in Fuchsia can be complicated to follow because they are routed differently in different parts of the system.

Drivers

Drivers use the LogSink protocol to log, but do so through the use of their own library. This library provides a wrapper around the syslog library, so that each driver has its own logger.

In addition, driver_manager binds stdout and stderr to debuglog. This allows driver_manager to output critical information to the debuglog, or to fallback to the debuglog.

Components

By default, components only have their stdout and stderr streams captured if they have access to a LogSink protocol for forwarding. For more information, see the ELF runner section on forwarding stdout and stderr streams.

Forwarding klog to syslog

The Archivist continually reads from the klog and forwards those messages to the syslog log. Messages from the klog can be dropped by the pipeline if they are rolled out of the klog buffer before the Archivist reads them into syslog.

All kernel log messages are sent to the system log with INFO severity because the debuglog syscalls do not have a way to express the severity of a message.