|
Safe API Framework
Layered API framework for safety-related applications (ERTMS RBC reference targeting CENELEC EN 50128 SIL 4)
|
Non-safety-related black-box/event-recorder logging (ADR-001). More...
Files | |
| file | src/oal/log/sapi_log.c |
| Logging service: dispatches to the backend registered via sapi_log_register_backend() (ADR-005). No backend registered is not an error for this service - see sapi_log.h. | |
Data Structures | |
| struct | sapi_log_fields_t |
| Bounded builder for sapi_log_write_event()'s extra_fields (or info) argument: accumulates space-separated key=value pairs, each typed at the call site, so a caller adding a couple of variable values does not hand-roll a sapi_string_concat()/sapi_string_append_u32() chain every time (MISRA C:2012 Rule 17.1 rules out a printf-style variadic here). More... | |
Macros | |
| #define | SAPI_LOG_EVENT_LINE_MAX_LEN 256U |
| Max length, in bytes and not counting the NUL terminator, of one sapi_log_write_event() line - fields are truncated, not rejected, if the formatted line would exceed this (REQ-OAL-LOG-001: a formatting limit must never turn into a blocked/failed caller). Sized generously for the 8 mandatory fields plus a typical extra_fields value; a longer extra_fields is where truncation would first show up in practice. | |
Enumerations | |
| enum | sapi_log_level_t { SAPI_LOG_LEVEL_DEBUG = 0 , SAPI_LOG_LEVEL_INFO = 1 , SAPI_LOG_LEVEL_WARNING = 2 , SAPI_LOG_LEVEL_ERROR = 3 } |
| Log message severity, passed to sapi_log_write(). More... | |
Functions | |
| sapi_status_t | sapi_log_init (void) |
| Initializes the logging backend. Safe to call once at startup. | |
| void | sapi_log_write (sapi_log_level_t level, const char *tag, const char *message) |
| Emits one log message. Non-blocking; never fails the caller's control flow even if the message is dropped. | |
| const char * | sapi_log_level_to_string (sapi_log_level_t level) |
| Renders a sapi_log_level_t as a fixed, human-readable tag - "DEBUG"/"INFO"/"WARNING"/"ERROR" - used as the LEVEL field of sapi_log_write_event()'s structured line and available to any backend/integrator wanting the same canonical spelling. | |
| sapi_status_t | sapi_log_level_from_string (const char *name, sapi_log_level_t *out_level) |
| Parses one of the canonical level spellings ("DEBUG", "INFO", "WARNING", "ERROR" - exactly as sapi_log_level_to_string() renders them, case-sensitive) into a sapi_log_level_t. | |
| void | sapi_log_set_level (sapi_log_level_t min_level) |
| Sets the minimum severity that sapi_log_write() and sapi_log_write_event() forward to the backend - a call whose level is below min_level is dropped before dispatch (and before any formatting work). Default is SAPI_LOG_LEVEL_DEBUG: nothing is filtered until this is called. | |
| sapi_log_level_t | sapi_log_get_level (void) |
| Returns the current minimum severity (see sapi_log_set_level()). REQ-OAL-LOG-015. | |
| void | sapi_log_write_event (sapi_log_level_t level, const char *site, uint32_t cycle, const char *source, const char *destination, const char *type, const char *info, const char *extra_fields) |
| Emits one structured inter-channel event/message-trail log line - for a message actually sent/received/decided between channels or nodes (e.g. an AB_SAMPLE frame, an M136 report, a checkpoint REQUEST/REPLY, a cross-compare AGREE/DISAGREE) - distinct from sapi_log_write()'s free-text diagnostic logging, which remains the right call for an event with no natural cycle/source/destination (e.g. an NVM write failure). | |
| void | sapi_log_fields_reset (sapi_log_fields_t *fields) |
| (Re)initialises a builder to empty. MUST be called before the first sapi_log_fields_add_*(); safe to call again to reuse the same builder for another line. | |
| const char * | sapi_log_fields_c_str (sapi_log_fields_t *fields) |
| NUL-terminated view of the accumulated pairs. | |
| void | sapi_log_write_event_fields (sapi_log_level_t level, const char *site, uint32_t cycle, const char *source, const char *destination, const char *type, const char *info, sapi_log_fields_t *fields) |
| sapi_log_write_event() with a builder passed directly as the extra fields - no sapi_log_fields_c_str() at the call site. | |
| sapi_log_fields_t * | sapi_log_fields_add_str (sapi_log_fields_t *fields, const char *key, const char *value) |
| Appends one key=value pair (preceded by a single separating space only when the builder is already non-empty). | |
| sapi_log_fields_t * | sapi_log_fields_add_u32 (sapi_log_fields_t *fields, const char *key, uint32_t value) |
| sapi_log_fields_t * | sapi_log_fields_add_i32 (sapi_log_fields_t *fields, const char *key, int32_t value) |
| sapi_log_fields_t * | sapi_log_fields_add_u64 (sapi_log_fields_t *fields, const char *key, uint64_t value) |
| sapi_log_fields_t * | sapi_log_fields_add_i64 (sapi_log_fields_t *fields, const char *key, int64_t value) |
| sapi_log_fields_t * | sapi_log_fields_add_hex_u32 (sapi_log_fields_t *fields, const char *key, uint32_t value, uint8_t min_digits) |
| sapi_log_fields_t * | sapi_log_fields_add_bool (sapi_log_fields_t *fields, const char *key, bool value) |
Non-safety-related black-box/event-recorder logging (ADR-001).
| #define SAPI_LOG_EVENT_LINE_MAX_LEN 256U |
Max length, in bytes and not counting the NUL terminator, of one sapi_log_write_event() line - fields are truncated, not rejected, if the formatted line would exceed this (REQ-OAL-LOG-001: a formatting limit must never turn into a blocked/failed caller). Sized generously for the 8 mandatory fields plus a typical extra_fields value; a longer extra_fields is where truncation would first show up in practice.
Definition at line 122 of file sapi_log.h.
| enum sapi_log_level_t |
Log message severity, passed to sapi_log_write().
Definition at line 33 of file sapi_log.h.
| sapi_status_t sapi_log_init | ( | void | ) |
Initializes the logging backend. Safe to call once at startup.
Definition at line 99 of file sapi_log.c.
| void sapi_log_write | ( | sapi_log_level_t | level, |
| const char * | tag, | ||
| const char * | message ) |
Emits one log message. Non-blocking; never fails the caller's control flow even if the message is dropped.
| level | Severity level. |
| tag | Short diagnostic source tag, backend-defined interpretation, may be NULL. |
| message | Human-readable message text, may be NULL. REQ-OAL-LOG-011 |
Definition at line 108 of file sapi_log.c.
| const char * sapi_log_level_to_string | ( | sapi_log_level_t | level | ) |
Renders a sapi_log_level_t as a fixed, human-readable tag - "DEBUG"/"INFO"/"WARNING"/"ERROR" - used as the LEVEL field of sapi_log_write_event()'s structured line and available to any backend/integrator wanting the same canonical spelling.
| level | Level to render; an unrecognized value (defensive only - not reachable through the public enum) renders as "UNKNOWN". |
Definition at line 162 of file sapi_log.c.
| sapi_status_t sapi_log_level_from_string | ( | const char * | name, |
| sapi_log_level_t * | out_level ) |
Parses one of the canonical level spellings ("DEBUG", "INFO", "WARNING", "ERROR" - exactly as sapi_log_level_to_string() renders them, case-sensitive) into a sapi_log_level_t.
| name | NUL-terminated candidate spelling. Must not be NULL. |
| out_level | Receives the parsed level on success. Must not be NULL (left unchanged on failure). |
Definition at line 125 of file sapi_log.c.
| void sapi_log_set_level | ( | sapi_log_level_t | min_level | ) |
Sets the minimum severity that sapi_log_write() and sapi_log_write_event() forward to the backend - a call whose level is below min_level is dropped before dispatch (and before any formatting work). Default is SAPI_LOG_LEVEL_DEBUG: nothing is filtered until this is called.
Runtime-settable so an integrator can quiet or open up logging without a rebuild (e.g. a remote "set log level" command). NOT a setup-only action (unlike sapi_log_register_backend()) - may be called at any time, from any thread: the threshold is one int-sized value, so a concurrent change racing an in-flight sapi_log_write() only ever means that one call sees the old or the new threshold, never a torn value, and at worst one best-effort log line is kept or dropped unexpectedly (REQ-OAL-LOG-001).
| min_level | Lowest level to keep. A value outside SAPI_LOG_LEVEL_DEBUG..SAPI_LOG_LEVEL_ERROR is ignored (the current threshold is left unchanged). REQ-OAL-LOG-015 |
Definition at line 146 of file sapi_log.c.
| sapi_log_level_t sapi_log_get_level | ( | void | ) |
Returns the current minimum severity (see sapi_log_set_level()). REQ-OAL-LOG-015.
Definition at line 157 of file sapi_log.c.
| void sapi_log_write_event | ( | sapi_log_level_t | level, |
| const char * | site, | ||
| uint32_t | cycle, | ||
| const char * | source, | ||
| const char * | destination, | ||
| const char * | type, | ||
| const char * | info, | ||
| const char * | extra_fields ) |
Emits one structured inter-channel event/message-trail log line - for a message actually sent/received/decided between channels or nodes (e.g. an AB_SAMPLE frame, an M136 report, a checkpoint REQUEST/REPLY, a cross-compare AGREE/DISAGREE) - distinct from sapi_log_write()'s free-text diagnostic logging, which remains the right call for an event with no natural cycle/source/destination (e.g. an NVM write failure).
Emits, via the same backend as sapi_log_write() (non-blocking, best-effort, same REQ-OAL-LOG-001 contract - a full backend buffer or an unregistered backend silently drops this call, never blocks or errors the caller):
i.e. space-separated Key=Value pairs, one per mandatory field, in that fixed order, as the message argument of the registered sapi_log_backend_t::write(), with source passed as that call's tag argument - an existing backend needs no changes to receive structured events (e.g. the shipped POSIX backend still prefixes its own "[LEVEL] tag: " for terminal readability; a consumer parsing the structured Key=Value fields should parse from the message value itself, not whatever cosmetic wrapping a specific backend adds around it).
Timestamp is sourced internally via sapi_timer_now() (milliseconds); "0" is emitted if no sapi_timer backend is registered or the call otherwise fails - REQ-OAL-LOG-001 means a timer problem must never prevent this call from returning, so a timestamp failure degrades the Timestamp field rather than skipping the whole event.
| level | Severity. |
| site | Caller-supplied node/site/instance identifier (e.g. "WEST", "EAST") - the framework has no concept of a "site" itself; this is opaque, caller-defined text, first in the emitted line so a log consumer merging output from multiple redundant instances can always tell them apart at a glance. Must not be NULL; pass "" if this integration has no such concept. |
| cycle | Cycle/iteration counter this event belongs to (e.g. sapi_appmanager_state_t::iteration_count). Use 0 if this event has no natural cycle. |
| source | Short identifier of the event's origin (e.g. "A/WEST"). Must not be NULL; pass "" if unknown. |
| destination | Short identifier of the event's target (e.g. "B", "C", "-" for no specific destination). Must not be NULL. |
| type | Short event/message-type tag (e.g. "AB_SAMPLE", "M136", "CHECKPOINT_REQUEST", "AGREE"). Must not be NULL. |
| info | Free-text human-readable detail. May be NULL (an empty Info= value is emitted). |
| extra_fields | Optional, caller-preformatted additional Key=Value text (e.g. "D_LRBG=42 CRC=OK"), appended verbatim after Info=... behind one separating space - not wrapped in another key, so it reads as more of the same space-separated Key=Value convention. May be NULL (omitted entirely - no trailing space is emitted either). |
Definition at line 188 of file sapi_log.c.
| void sapi_log_fields_reset | ( | sapi_log_fields_t * | fields | ) |
(Re)initialises a builder to empty. MUST be called before the first sapi_log_fields_add_*(); safe to call again to reuse the same builder for another line.
| fields | Builder to reset. A NULL fields is a silent no-op. REQ-OAL-LOG-017 |
Definition at line 254 of file sapi_log.c.
| sapi_log_fields_t * sapi_log_fields_add_str | ( | sapi_log_fields_t * | fields, |
| const char * | key, | ||
| const char * | value ) |
Appends one key=value pair (preceded by a single separating space only when the builder is already non-empty).
| fields | Builder (must have been sapi_log_fields_reset()). |
| key | Field key/label, e.g. "route". Must not be NULL. |
| value | Value: for _add_str a NULL string is written as an empty value; for _add_hex_u32, min_digits is the minimum digit count (zero-padded), prefixed with 0x; for _add_bool, "true"/"false" is written. |
fields, so a few calls can be chained inline. fields / NULL key, or a full backing store, silently leaves the builder unchanged (REQ-OAL-LOG-001). REQ-OAL-LOG-017 Definition at line 285 of file sapi_log.c.
| sapi_log_fields_t * sapi_log_fields_add_u32 | ( | sapi_log_fields_t * | fields, |
| const char * | key, | ||
| uint32_t | value ) |
Definition at line 294 of file sapi_log.c.
| sapi_log_fields_t * sapi_log_fields_add_i32 | ( | sapi_log_fields_t * | fields, |
| const char * | key, | ||
| int32_t | value ) |
Definition at line 303 of file sapi_log.c.
| sapi_log_fields_t * sapi_log_fields_add_u64 | ( | sapi_log_fields_t * | fields, |
| const char * | key, | ||
| uint64_t | value ) |
Definition at line 312 of file sapi_log.c.
| sapi_log_fields_t * sapi_log_fields_add_i64 | ( | sapi_log_fields_t * | fields, |
| const char * | key, | ||
| int64_t | value ) |
Definition at line 321 of file sapi_log.c.
| sapi_log_fields_t * sapi_log_fields_add_hex_u32 | ( | sapi_log_fields_t * | fields, |
| const char * | key, | ||
| uint32_t | value, | ||
| uint8_t | min_digits ) |
Definition at line 330 of file sapi_log.c.
| sapi_log_fields_t * sapi_log_fields_add_bool | ( | sapi_log_fields_t * | fields, |
| const char * | key, | ||
| bool | value ) |
Definition at line 341 of file sapi_log.c.
| const char * sapi_log_fields_c_str | ( | sapi_log_fields_t * | fields | ) |
NUL-terminated view of the accumulated pairs.
| fields | Builder. NULL / empty yields "". |
fields->storage, valid until the next sapi_log_fields_reset()/_add_*() on the same builder; never NULL. Pass it straight as sapi_log_write_event()'s extra_fields (or info). REQ-OAL-LOG-017 Definition at line 350 of file sapi_log.c.
| void sapi_log_write_event_fields | ( | sapi_log_level_t | level, |
| const char * | site, | ||
| uint32_t | cycle, | ||
| const char * | source, | ||
| const char * | destination, | ||
| const char * | type, | ||
| const char * | info, | ||
| sapi_log_fields_t * | fields ) |
sapi_log_write_event() with a builder passed directly as the extra fields - no sapi_log_fields_c_str() at the call site.
| fields | Extra key=value pairs; NULL or an empty builder emits no extra fields (identical to passing NULL to sapi_log_write_event()). Every other parameter is exactly as sapi_log_write_event(). REQ-OAL-LOG-017 |
Definition at line 366 of file sapi_log.c.