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 call fuchsia.logger.LogSink/ConnectStructured. 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.

ConnectStructured takes a socket where the actual log messages are written by the syslog library. If the socket buffer is full, the writing thread drops the logs by default. 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 drain all of the sockets that it receives fast enough 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 zxlogf. This function provides a wrapper around the syslog library, so that each driver has its own log message socket.

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.