blob: 0e6a3304b5f61eb1339d748cc8056600cd7fba72 [file] [log] [blame] [view]
# Recording Logs
There are a few ways you might see a Fuchsia program generate log messages:
* the LogSink service
* the kernel's debuglog
* a combination of these, routed through `stdout` or `stderr`
## `LogSink`/syslog
Components that want to generate log messages call [`fuchsia.logger/LogSink.Connect`]. The
[`fuchsia.logger.LogSink`] service must be [`use`d in the component manifest][syslog-use-shard].
`Connect` takes a socket, into which the actual log messages are [written] by the syslog library.
If the socket's buffer is full, the [writing thread will drop logs]. Dropped messages on the writer
side are counted and that count is sent in the next successful message, after which the counter is
reset. `log_listener` [prints a warning] when it's aware of dropped messages.
The `LogSink` service must drain all of the sockets it receives quickly enough to prevent messages
being dropped on the writer-side. `LogSink` is responsible for draining those sockets to fill
internal buffers (TODO(https://fxbug.dev/42124432): No longer true since https://fxrev.dev/490158).
This can result in high CPU usage in both the writing component and the `LogSink` when logging
heavily.
Different languages use different mechanisms to talk to `LogSink`. See the relevant pages for more
information:
* [C++ logging]
* [Go logging]
* [Rust logging]
## debuglog handles
The kernel allows programs to create debuglog handles from the root resource, each handle allowing
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. The read syscall is used to transfer from the
debuglog to the system log.
Components that want to send their standard streams to the debuglog gain access through the
[`fuchsia.boot.WriteOnlyLog`] protocol.
Most logs written to debuglog handles are written through stdio forwarding.
## Standard streams: `stdout` and `stderr`
These concepts are familiar to many from other operating systems but their use in Fuchsia can be
complicated to follow because they are routed differently in different parts of the system.
### Drivers
Drivers log to the `LogSink` sink service, but do so through the use of [`zxlogf`]. This function
provides a wrapper around the syslog library, so that each driver will have 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 for certain product
configurations where the `LogSink` service is not available.
### Components
By default, [components] only have their `stdout` and `stderr` streams captured
if they have access to a `LogSink` service 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 main 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 -- these are not yet tracked.
All kernel log messages are sent to the system log with INFO severity because the debuglog syscalls
lack a way to express the severity of a message.
[`fuchsia.logger/LogSink.Connect`]: https://fuchsia.dev/reference/fidl/fuchsia.logger#Connect
[`fuchsia.logger.LogSink`]: https://fuchsia.dev/reference/fidl/fuchsia.logger#LogSink
[syslog-use-shard]: /sdk/lib/syslog/use.shard.cml
[written]: /zircon/system/ulib/syslog/fx_logger.cc?l=72&drc=1bdbf8a4e6f758c3b1782dee352071cc592ca3ab
[writing thread will drop logs]: /zircon/system/ulib/syslog/fx_logger.cc?l=130&drc=1bdbf8a4e6f758c3b1782dee352071cc592ca3ab
[prints a warning]: /src/diagnostics/log_listener/src/main.rs?l=918&drc=3a02d1922c0519b4c7d639879ec0503de9c79f0c
[C++ logging]: /docs/development/languages/c-cpp/logging.md
[Go logging]: /docs/development/languages/go/logging.md
[Rust logging]: /docs/development/languages/rust/logging.md
[kernel's shared ring buffer]: /zircon/kernel/lib/debuglog/debuglog.cc?l=37&drc=1bdbf8a4e6f758c3b1782dee352071cc592ca3ab
[bindable to file descriptors]: /sdk/lib/fdio/include/lib/fdio/fdio.h?l=36&drc=1bdbf8a4e6f758c3b1782dee352071cc592ca3ab
[`debuglog_write`]: /reference/syscalls/debuglog_write.md
[`debuglog_read`]: /reference/syscalls/debuglog_read.md
[`zxlogf`]: /sdk/lib/driver/compat/cpp/logging.h?l=59&drc=7cf6769e0971693fc1307c6059826596452c75b2
[kernel params]: /docs/reference/kernel/kernel_cmdline.md#drivernamelogflags
[`fuchsia.sys/LaunchInfo`]: https://fuchsia.dev/reference/fidl/fuchsia.sys#LaunchInfo
[`stdout-to-debuglog`]: /src/sys/lib/stdout-to-debuglog
[`fuchsia.boot.WriteOnlyLog`]: https://fuchsia.dev/reference/fidl/fuchsia.boot#WriteOnlyLog
[`ddk/debug.h`]: /src/lib/ddk/include/ddk/debug.h
[components]: /docs/concepts/components/v2/introduction.md
[ELF]: /docs/concepts/components/v2/elf_runner.md
[forwarding stdout and stderr streams]: /docs/concepts/components/v2/elf_runner.md#forwarding_stdout_and_stderr_streams