Safe API Framework
Layered API framework for safety-related applications (ERTMS RBC reference targeting CENELEC EN 50128 SIL 4)
Loading...
Searching...
No Matches
sapi_log.c File Reference

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

Include dependency graph for sapi_log.c:

Go to the source code of this file.

Data Structures

struct  sapi_log_level_name_t
 One canonical level spelling <-> value pair for sapi_log_level_from_string(). More...

Functions

static void sapi_log_append_event_field (sapi_string_t *line, const char *key, const char *value)
 Appends " Key=Value" to *line (a leading space, then key, "=", then value or "" if value is NULL) - the Key=Value pair convention sapi_log_write_event() uses for every field. Best-effort: a SAPI_STATUS_RESOURCE_EXHAUSTED from any concat is silently accepted (line is left truncated at whatever fit) - REQ-OAL-LOG-001, this must never fail the caller's control flow, so there is nothing to report here.
static void sapi_log_append_event_field_u32 (sapi_string_t *line, const char *key, uint32_t value)
 Formats value in base 10 and appends it as "Key=value" via sapi_log_append_event_field(). Uses a small local sapi_string_t/buffer, independent of *line's own storage.
sapi_status_t sapi_log_register_backend (const sapi_log_backend_t *backend)
 Registers the backend implementation used by sapi_log_init()/ sapi_log_write() (ADR-005 section 2.1/2.5). Call once at startup.
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.
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.
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.
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.
static bool sapi_log_fields_begin_pair (sapi_log_fields_t *fields, const char *key)
 Appends the "[ ]key=" prefix of one pair (leading space only if the builder already holds something). Best-effort; a truncated concat is silently accepted (REQ-OAL-LOG-001).
sapi_log_fields_tsapi_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_tsapi_log_fields_add_u32 (sapi_log_fields_t *fields, const char *key, uint32_t value)
sapi_log_fields_tsapi_log_fields_add_i32 (sapi_log_fields_t *fields, const char *key, int32_t value)
sapi_log_fields_tsapi_log_fields_add_u64 (sapi_log_fields_t *fields, const char *key, uint64_t value)
sapi_log_fields_tsapi_log_fields_add_i64 (sapi_log_fields_t *fields, const char *key, int64_t value)
sapi_log_fields_tsapi_log_fields_add_hex_u32 (sapi_log_fields_t *fields, const char *key, uint32_t value, uint8_t min_digits)
sapi_log_fields_tsapi_log_fields_add_bool (sapi_log_fields_t *fields, const char *key, bool value)
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.

Variables

static const sapi_log_backend_ts_backend = NULL
 Currently registered backend, or NULL if none (ADR-005).
static sapi_log_level_t s_min_level = SAPI_LOG_LEVEL_DEBUG
 Minimum severity forwarded to the backend (sapi_log_set_level()). SAPI_LOG_LEVEL_DEBUG = nothing filtered - the historical behaviour before this threshold existed.
static const sapi_log_level_name_t s_level_names []
 The four canonical spellings, kept in sync with sapi_log_level_to_string().

Detailed Description

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.

sapi_log_write_event()'s structured-line formatting (added alongside this file's own module) is what introduces this module's only two new dependencies, safeapi::string (bounded formatting - ADR-006) and safeapi::timer (TIMESTAMP field - sapi_timer_now()); sapi_log_write() itself and the backend dispatch below are unchanged and still have neither dependency.

Definition in file sapi_log.c.

Function Documentation

◆ sapi_log_append_event_field()

void sapi_log_append_event_field ( sapi_string_t * line,
const char * key,
const char * value )
static

Appends " Key=Value" to *line (a leading space, then key, "=", then value or "" if value is NULL) - the Key=Value pair convention sapi_log_write_event() uses for every field. Best-effort: a SAPI_STATUS_RESOURCE_EXHAUSTED from any concat is silently accepted (line is left truncated at whatever fit) - REQ-OAL-LOG-001, this must never fail the caller's control flow, so there is nothing to report here.

Global variables declarations Local function declarations

Parameters
lineLine being built. Must not be NULL.
keyField key/label (e.g. "Cycle"). Must not be NULL.
valueField value to append; NULL is treated as an empty value.

Definition at line 384 of file sapi_log.c.

◆ sapi_log_append_event_field_u32()

void sapi_log_append_event_field_u32 ( sapi_string_t * line,
const char * key,
uint32_t value )
static

Formats value in base 10 and appends it as "Key=value" via sapi_log_append_event_field(). Uses a small local sapi_string_t/buffer, independent of *line's own storage.

Parameters
lineLine being built. Must not be NULL.
keyField key/label. Must not be NULL.
valueValue to format.

Definition at line 392 of file sapi_log.c.

◆ sapi_log_fields_begin_pair()

bool sapi_log_fields_begin_pair ( sapi_log_fields_t * fields,
const char * key )
static

Appends the "[ ]key=" prefix of one pair (leading space only if the builder already holds something). Best-effort; a truncated concat is silently accepted (REQ-OAL-LOG-001).

Returns
true if fields and key are both non-NULL (i.e. the caller should append the value), false otherwise.

Definition at line 269 of file sapi_log.c.

Variable Documentation

◆ s_backend

const sapi_log_backend_t* s_backend = NULL
static

Currently registered backend, or NULL if none (ADR-005).

Local variables declarations

Definition at line 36 of file sapi_log.c.

◆ s_min_level

sapi_log_level_t s_min_level = SAPI_LOG_LEVEL_DEBUG
static

Minimum severity forwarded to the backend (sapi_log_set_level()). SAPI_LOG_LEVEL_DEBUG = nothing filtered - the historical behaviour before this threshold existed.

Definition at line 41 of file sapi_log.c.

◆ s_level_names

const sapi_log_level_name_t s_level_names[]
static
Initial value:
= {
{ "DEBUG", SAPI_LOG_LEVEL_DEBUG },
{ "INFO", SAPI_LOG_LEVEL_INFO },
{ "WARNING", SAPI_LOG_LEVEL_WARNING },
{ "ERROR", SAPI_LOG_LEVEL_ERROR }
}
@ SAPI_LOG_LEVEL_DEBUG
Definition sapi_log.h:35
@ SAPI_LOG_LEVEL_ERROR
Definition sapi_log.h:38
@ SAPI_LOG_LEVEL_INFO
Definition sapi_log.h:36
@ SAPI_LOG_LEVEL_WARNING
Definition sapi_log.h:37

The four canonical spellings, kept in sync with sapi_log_level_to_string().

Definition at line 45 of file sapi_log.c.