# Logs Logging macros work on host and flight targets: ```rust,ignore kaptan_log::debug!("estimator waiting for IMU"); kaptan_log::info!("configuration loaded"); kaptan_log::warn!("range aid stale"); kaptan_log::error!("sensor transfer failed"); kaptan_log::trace!("prediction step complete"); ``` All five macros emit `LOG`; their level never selects a different wire message. When a reportable firmware error escapes a `#[kaptan_err_reportable::propagate]` function, it makes one bounded admission attempt to the separate `ERROR` ingress. `kaptan-log` formats each event once into fixed 160-byte UTF-8 storage. Its core storage and admission paths use no allocation or blocking, and do not send MAVLink, change flight state or touch DMA. Formatting invokes caller-supplied `Display` implementations, which may allocate, block, ignore `fmt::Error` or do unbounded work. Overflow stops formatters that propagate the error and latches truncation even if a formatter ignores it. Bounded storage is not a universal worst-case execution-time guarantee. Producers must choose formatters suitable for their execution context. The composition fans the event into each enabled sink. The MAVLink worker drains its bounded sink queue. Reportable-error records contain the explicit ID and a static reference to the reporting point until the MAVLink adapter copies its `file:line` into the 96-byte `raised_at` field. Logs and reportable errors use independent fixed atomic ingresses; interrupt and worker producers make one nonblocking admission attempt, and only the MAVLink worker encodes or transmits a retained event. Panic and hard-fault paths still do not attempt live telemetry. ## Receiver contract `definitions/publish/log.xml` and `definitions/publish/error.xml` define the separate ordinary-log and reportable-error publications: ```text LOG { level, flags, message_length, message[160] } ERROR { error_id, raised_at[96] } ``` A GCS decoder generated from the same `kaptan.xml` revision must validate `message_length <= 160` for `LOG`. `ERROR.raised_at` is a zero-padded UTF-8 `file:line` prefix; receivers use bytes before the first zero, or the complete field when no zero is present. `LOG.level` is the typed severity-ordered Kaptan wire enum Trace (1), Debug (2), Info (3), Warn (4), or Error (5). Off (0) is a filter-only sentinel and is never emitted as a `LOG` event. `LOG.flags` currently owns only the Truncated bit (1). `error_id` is the stable nonzero catalog number explicitly assigned to the Rust error variant. Renaming or reordering a variant does not change it. `raised_at` identifies the reporting point where the `Err` entered diagnostics. Protocol failures remain in their owning response; for example, a rejected KCFG upload returns a `FILE_CONTROL` failure and readable bounded detail. Delivery is bounded and lossy under link pressure. Heartbeat and sensor telemetry use separate paths. Logs have no publication rate setting and are not periodic streams. The worker offers each retained event to USB and every MAVLink UART, then removes it once at least one transport admits it. Admission does not prove receipt or delivery to every link. If none admits it, the event remains pending. Opening USB does not take diagnostics away from UART. ## Filtering The single restart-only `mavlink.logging.level_filter` field uses Off (0), Trace (1), Debug (2), Info (3), Warn (4), and Error (5). `Info`, for example, accepts Info, Warn, and Error log events. `Off` suppresses `LOG` on MAVLink without suppressing reportable `ERROR` events or logs sent to another sink. There is no separate enable flag and no MAVLink-specific set of extra runtime log levels. F722 uses the validated boot-active filter. Empty storage uses factory values. Invalid storage selects the setup fallback, which also uses the factory filter but disables UART roles. Saved changes and factory reset do not alter the active filter until reboot. See [configuration recovery](configuration.md#recovery-and-activation). Events retain the compact typed `Level` and sink configuration retains the compact typed `LevelFilter`. Schema metadata supplies the filter choices to the configurator. Only the MAVLink adapter converts the five event levels to the typed Kaptan wire enum. The log ingress is transport-neutral and unfiltered.