Using the Log service

The Log service captures Kanzi Engine log messages into an in-memory ring buffer. You can view the captured log entries through the console, display them on-screen using the BasicUI overlay, access them programmatically through the API, or export them as part of a profiling trace.

Platform support

The Log service builds from sources on all known Kanzi target platforms.

How the Log service works

The Log service hooks into the Kanzi logging system by registering a custom logger in the Kanzi logger chain. Once registered, the logger automatically receives all Kanzi log messages without any additional application code.

Each log entry is formatted as a string containing:

  • Timestamp – Date and time with millisecond precision (for example, 2025-02-10 14:32:45.123)

  • Level – The log level (for example, Info, Warning, Error)

  • Category – The logging category (for example, Generic, Rendering)

  • Source location – File name and line number (included only for Error level)

  • Message – The log message text

Example log entry:

2025-02-10 14:32:45.123 Info:Generic> Application initialized

The log buffer operates as a ring buffer with a configurable maximum size (default: 100 entries). When the buffer is full, the oldest entry is removed to make room for new entries.

Viewing log entries

  • Use the loginfo command from the local or remote console to view the buffer contents.

  • Use the basicui command to switch to the Log screen for on-screen display of log entries.

  • Log entries are also included in the trace output as instant events. See Using the Profiling Trace service.

Trace integration

The Log service registers a parallel profiling logger that captures the same log messages with nanosecond-precision timestamps. These samples are exported to the trace file as instant events on a dedicated KanziLog thread, allowing log messages to be correlated with other profiling data in the Perfetto trace viewer.

The Log service defines its own profiling category (PROFILING_LOGGING) which is always enabled at compile time, independent of the build configuration of the Kanzi Engine. This means log entries are included in the trace in all build configurations (Debug, Release, and Profiling).

Accessing the log buffer from code

You can access the log buffer programmatically through the Log service API:

KanziMonitorModule* module = getKanziMonitorModule(domain);
LogService* logService = module->getLogService();
KanziMonitorLogger* logger = logService->getLogger();

// Read the entries. The visitor runs while the buffer is locked.
logger->withLog([](const kanzi::list<LogEntry>& entries) {
    for (const LogEntry& entry : entries)
    {
        // entry.timestamp, entry.level, entry.category, entry.message,
        // and entry.fileName / entry.lineNumber for errors.
    }
});

// Query the entry count and the buffer size.
size_t count = logger->getEntryCount();
size_t maxEntries = logger->getMaxEntries();

// Change the buffer size. This trims to the new size immediately.
logger->setMaxEntries(200);

// Clear the buffer.
logger->clearLog();

Warning

Kanzi Monitor writes to this buffer from several threads: the main thread, the remote console reader thread on every incoming connection, and the local console reader thread. withLog() therefore holds a lock for the duration of your visitor.

Keep the visitor short — it holds off every logging thread in the process, and a high log rate makes that back-pressure real. Do not store the reference it gives you, and do not call back into the logger from inside it: the lock is not recursive, so a nested call deadlocks. Copy out what you need instead, and do any file or socket I/O after withLog() returns.

Note

getLog(), which returned a reference to the container, was removed in Kanzi Monitor 1.41.2. A reference outlives the lock that would protect it, so that accessor could not be made thread-safe. See Migration guides.

Using diagnostics

The logdiag command provides diagnostic information about the KanziLog trace pipeline. This is useful for troubleshooting when log entries are missing from the trace output.

logdiag

Example output:

=== KanziLog Trace Diagnostics ===
PROFILING_LOGGING compile-time enabled: yes
PROFILING_LOGGING runtime enabled: yes
ProfilingLogger alive: yes
ProfilingLogger write count: 42
LoggerProfiler sample count: 42
General collection tasks: 2
  [0] registry_default_profiling
  [1] registry_logging_profiling
Logging storage registered: yes

The diagnostics report:

  • Whether the PROFILING_LOGGING profiling category is enabled at compile time and runtime.

  • Whether the ProfilingLogger is alive and how many log messages it captured.

  • The number of profiling samples collected by the LoggerProfiler.

  • The registered general collection tasks and whether the logging storage is present.

On some platforms (for example, Android application framework), the ProfilingLogger created during static initialization can be destroyed before the plugin initializes at runtime. The Log service detects this condition and automatically re-creates the ProfilingLogger during initialization, so that runtime log messages are captured in the trace.

Available commands

Command

Description

loginfo

Shows recent log information.

logdiag

Shows KanziLog trace pipeline diagnostics.

Available UI screens

The Log service registers a BasicUI screen with the UI service:

  • Log screen – Displays the contents of the log buffer as an on-screen text overlay. Use the basicui command to switch to this screen.

See also

Using the Profiling Trace service

Using the UI service

Configuring Kanzi Monitor