Logging

Note

The experimental Rust SDK does not expose this logging API. Output from Rust’s print! and eprint! macros is visible to the host, so it must not contain confidential data.

To add your own lines to the node’s output you should use the CCF_APP_* macros defined in ccf/ds/logger.h:

#include "ccf/ds/logger.h"

int x = 5;
CCF_APP_INFO("x is currently {}", x);

Applications written in JavaScript and TypeScript can produce similar log lines using standard functions console.log, console.info, console.warn, and console.error:

x = 5
console.info(`x is ${x}`)

Either approach will produce a line in the node’s stdout like:

2022-07-12T12:34:56.626262Z        0   [info ][app] ../src/my_app/my_app.cpp:42    | x is 5

These logging functions do several things:

  • Variable substitution. See libfmt for more details of the formatting syntax used in C++

  • Declare the severity of the entry. CCF defines 5 levels (trace, debug, info, fail, and fatal), and production nodes will generally ignore entries below info

  • Prefix formatted metadata. The produced log line will include a timestamp, the name and line number where the line was produced, and an [app] tag

  • Write directly to stdout through the framework logger

CCF bundles the header-only C++ interface from fmt 12.2.0. Applications using fmt directly should include <fmt/format.h> for fmt::format rather than relying on <fmt/core.h> to include it, and <fmt/std.h> for std::byte formatting. The CCF_APP_* logging macros remain available through ccf/ds/logger.h.

Note

The app’s logging entries will be interleaved (line-by-line) with the framework’s logging messages. Filter for entries containing [app] to extract only application log lines.

Note

Since these logs are produced during execution, they will generally only appear on a single node and not every replica. They may also log information about uncommitted or re-executed transactions, as they are emitted independently of transaction commit.