blob: d98088bfe43a54dcc9f2f57edb5e0d7431ceb837 [file] [log] [blame] [view]
# 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 [`use`d in the component manifest][syslog-use-shard]. 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`:
* [C++ logging]
* [Go logging]
* [Rust logging]
## 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
Note: For more information about driver logging, see
[Driver logging][driver-logging-docs].
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.
[`fuchsia.logger.LogSink/OnInit`]: https://fuchsia.dev/reference/fidl/fuchsia.logger#LogSink.OnInit
[`fuchsia.logger.LogSink`]: https://fuchsia.dev/reference/fidl/fuchsia.logger#LogSink
[syslog-use-shard]: /sdk/lib/syslog/use.shard.cml
[`IOBuffer`]: https://fuchsia.dev/reference/syscalls#io_buffers
[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
[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
[driver-logging-docs]: /docs/development/drivers/diagnostics/logging.md