AxlLog – Logging

Domain-based logging with level filtering, custom handlers, ring buffer storage, and file output. GLib-style API with convenience macros (axl_error, axl_info, etc.) that inject __func__/__LINE__.

Header: <axl/axl-log.h>

Overview

AXL’s logging system lets each source file declare a log domain (a short string like "net" or "http"). Messages are filtered by level (ERROR through TRACE) globally and per-domain.

Basic Usage

#include <axl.h>

AXL_LOG_DOMAIN("mymodule");  // declare at file scope

void my_function(void) {
    axl_info("starting up");           // [INFO]  mymodule: starting up
    axl_debug("value=%d", 42);         // [DEBUG] mymodule: value=42
    axl_error("failed: %s", reason);   // [ERROR] mymodule: failed: ...
}

Log Levels

From most to least severe:

Level

Value

When to use

ERROR

0

Unrecoverable failures

WARNING

1

Recoverable problems

INFO

2

Significant state changes (default visible)

DEBUG

3

Detailed diagnostic info

TRACE

4

Very verbose, per-packet/per-call

The default level is INFO – messages at DEBUG and TRACE are suppressed unless explicitly enabled.

Level Filtering

// Show DEBUG messages globally
axl_log_set_level(AXL_LOG_DEBUG);

// Suppress everything below ERROR for the "net" domain
axl_log_set_domain_level("net", AXL_LOG_ERROR);

// Clear per-domain override (reverts to global level)
axl_log_clear_domain_level("net");

Custom Handlers

Route log messages to a custom function:

void my_handler(int level, const char *domain,
                const char *message, void *data) {
    // Write to a network socket, store in a buffer, etc.
}

axl_log_add_handler(my_handler, my_context);

Ring Buffer

Capture the last N messages in memory for crash reports or diagnostics:

AxlLogRing *ring = axl_log_ring_new(100);  // keep last 100 messages
axl_log_ring_attach(ring);

// ... application runs ...

// Retrieve captured messages (newest first)
for (size_t i = 0; i < axl_log_ring_count(ring); i++) {
    axl_printf("  %s\n", axl_log_ring_get(ring, i));
}
axl_log_ring_free(ring);

File Logging

Write log messages to a file on the UEFI filesystem:

axl_log_file_open("fs0:/app.log");
// ... all log messages are now also written to the file ...
axl_log_file_close();

API Reference

Defines

AXL_LOG_ERROR
AXL_LOG_WARNING
AXL_LOG_INFO
AXL_LOG_DEBUG
AXL_LOG_TRACE
AXL_LOG_DOMAIN(d)

AXL_LOG_DOMAIN:

Declare the log domain for the current source file. Place at the top of each .c file.

axl_error(...)

Convenience macros &#8212; inject func and LINE. Stay uppercase because they are macros, not functions.

axl_warning(...)
axl_info(...)
axl_debug(...)
axl_trace(...)

Typedefs

typedef void (*AxlLogHandler)(int level, const char *domain, const char *message, void *data)

Custom log handler callback.

typedef struct AxlLogRing AxlLogRing

Functions

void axl_log_full(int level, const char *domain, const char *func, int line, const char *fmt, ...)

Log a message with full source location.

Prefer the convenience macros (axl_error, axl_info, etc.) which fill in func/line.

Parameters:
  • level – log level (AXL_LOG_ERROR..AXL_LOG_TRACE)

  • domain – module name, or NULL

  • funcfunc (or NULL)

  • lineLINE (or 0)

  • fmt – standard C printf format string

void axl_log(int level, const char *domain, const char *fmt, ...)

Log a message without source location.

Parameters:
  • level – log level

  • domain – module name, or NULL

  • fmt – standard C printf format string

void axl_log_set_level(int level)

Set the global log level.

Messages above this level are suppressed. Default: AXL_LOG_INFO.

Parameters:
  • level – new global level

void axl_log_set_domain_level(const char *domain, int level)

Set the log level for a specific domain.

Parameters:
  • domain – domain name

  • level – level for this domain, or -1 to clear the override

void axl_log_add_handler(AxlLogHandler handler, void *data)

Add a global handler.

Receives all messages that pass level filtering.

Parameters:
  • handler – callback

  • data – opaque data passed to handler

void axl_log_add_domain_handler(const char *domain, int max_level, AxlLogHandler handler, void *data)

Add a handler that only fires for a specific domain and level range.

Parameters:
  • domain – domain to filter (NULL matches all)

  • max_level – maximum level to deliver

  • handler – callback

  • data – opaque data

void axl_log_remove_handler(AxlLogHandler handler)

Remove a previously added handler.

Parameters:
  • handler – handler to remove

void axl_log_suppress_console(void)

Suppress default console output.

Call after adding custom handlers.

void axl_log_set_console_timestamp(bool enable)

Enable or disable console timestamps.

Parameters:
  • enable – true to show HH:MM:SS.uuuuuu timestamps

void axl_log_set_fatal_level(int level)

Set the fatal level.

Messages at or below this level cause exit. Pass -1 to disable.

Parameters:
  • level – level at or below which messages cause exit

void axl_log_set_fatal_image_handle(void *image_handle)

Set the image handle needed for fatal exit via gBS->Exit.

Parameters:
  • image_handle – application image handle (void* to avoid EFI_HANDLE leak)

AxlLogRing *axl_log_ring_new(size_t max_entries, size_t entry_size)

Create a new log ring buffer.

Parameters:
  • max_entries – ring capacity

  • entry_size – max message length per entry (bytes)

Returns:

new ring, or NULL on failure.

void axl_log_ring_free(AxlLogRing *ring)

Free a log ring buffer. NULL-safe.

Parameters:
  • ring – ring to free

void axl_log_ring_attach(AxlLogRing *ring)

Attach a ring as a log handler.

Parameters:
  • ring – ring to attach

size_t axl_log_ring_count(AxlLogRing *ring)

Get the number of entries stored in a ring.

Parameters:
  • ring – ring to query

Returns:

number of entries stored.

bool axl_log_ring_get(AxlLogRing *ring, size_t index, AxlLogEntry *entry)

Retrieve an entry from a ring by index.

Parameters:
  • ring – ring to query

  • index – entry index (0 = newest)

  • entry – filled with entry data

Returns:

true if entry returned, false if index out of range.

int axl_log_file_attach(const char *path)

Open a log file and register a handler that buffers output.

Parameters:
  • path – UTF-8 file path (e.g. “fs0:/app.log”)

Returns:

0 on success, -1 on failure.

void axl_log_flush(void)

Flush the file handler’s buffer to disk.

struct AxlLogEntry

Public Members

const char *message
int level
const char *domain
uint64_t timestamp