Files
kaptan/docs/src/logs.md
T
Onur Özkan f9a61a086f feat(firmware): validate configuration and migrate sensor-driven flight APIs
Validate configuration through its owning schemas and keep board
declarations separate from shared F722 resource ownership. Bound USB
transitions, isolate transport failures and retain restart-only activation.

Migrate navigation and flight consumers with the sensor and schema
contracts. Require explicit installation data and synchronous output
authority; board motor outputs remain inhibited.

Validation: assembled-prefix host tests, strict Clippy, platform/USB tests
and both ARM release builds. Final-source coverage and scoped Miri/Kani
evidence are retained separately from hardware qualification.
2026-11-07 18:12:11 +03:00

90 lines
4.2 KiB
Markdown

# 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.