Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions barretenberg/cpp/src/barretenberg/bb/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -749,8 +749,11 @@ int parse_and_run_cli_command(int argc, char* argv[])
// If writing to an output folder, make sure it exists.
std::filesystem::create_directories(output_path);
}
debug_logging = flags.debug;
verbose_logging = debug_logging || flags.verbose;
if (flags.debug) {
bb_log_level = LogLevel::DEBUG;
} else if (flags.verbose) {
bb_log_level = LogLevel::VERBOSE;
}
slow_low_memory = flags.slow_low_memory;
#if !defined(__wasm__) || defined(ENABLE_WASM_BENCH)
if (!flags.storage_budget.empty()) {
Expand Down
14 changes: 8 additions & 6 deletions barretenberg/cpp/src/barretenberg/common/log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@
#include "barretenberg/common/log.hpp"

#ifndef __wasm__
bool verbose_logging = std::getenv("BB_VERBOSE") == nullptr ? false : std::string(std::getenv("BB_VERBOSE")) == "1";
// Default log level is INFO.
LogLevel bb_log_level = []() {
const char* verbose_ptr = std::getenv("BB_VERBOSE");
std::string verbose_str = verbose_ptr == nullptr ? "0" : std::string(verbose_ptr);
return verbose_str == "1" ? LogLevel::VERBOSE : LogLevel::INFO;
}();
#else
bool verbose_logging = true;
LogLevel bb_log_level = LogLevel::VERBOSE;
#endif

// Used for `debug` in log.hpp.
bool debug_logging = false;

// Used for `log_function` in log.hpp. Defaults to `logstr`.
LogFunction log_function = [](LogLevel /*unused*/, const char* msg) { logstr(msg); };
LogFunction log_function = [](LogLevel /*unused*/, const std::string& msg) { logstr(msg.c_str()); };

void set_log_function(LogFunction new_log_function)
{
Expand Down
71 changes: 34 additions & 37 deletions barretenberg/cpp/src/barretenberg/common/log.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#include <vector>

#include "barretenberg/env/logstr.hpp"
#include "barretenberg/stdlib/primitives/circuit_builders/circuit_builders_fwd.hpp"

#define BENCHMARK_INFO_PREFIX "##BENCHMARK_INFO_PREFIX##"
#define BENCHMARK_INFO_SEPARATOR "#"
Expand Down Expand Up @@ -58,54 +57,52 @@ template <typename... Args> std::string benchmark_format(Args... args)
return os.str();
}

// Log levels from TS foundation/src/log/log-levels.ts:
// ['silent', 'fatal', 'error', 'warn', 'info', 'verbose', 'debug', 'trace']
// Map: 0=silent, 1=fatal, 2=error, 3=warn, 4=info, 5=verbose, 6=debug, 7=trace
enum class LogLevel : int {
DEBUG = 0,
INFO = 1,
VERBOSE = 2,
IMPORTANT = 3,
SILENT = 0, // Works ok as 0 assuming nothing logs as SILENT.
FATAL = 1,
ERROR = 2,
WARN = 3,
INFO = 4,
VERBOSE = 5,
DEBUG = 6,
TRACE = 7,
};
extern LogLevel bb_log_level;

// This allows the logging sink to be customized. Useful for Typescript use-cases.
using LogFunction = std::function<void(LogLevel level, const char* msg)>;
using LogFunction = std::function<void(LogLevel level, const std::string& msg)>;
extern LogFunction log_function;
void set_log_function(LogFunction new_log_function);

extern bool debug_logging;
// In release mode (e.g., NDEBUG is defined), we don't compile debug logs.
// This logs (using log_function) if the log level is enabled.
// NOTE: Evaluation of __VA_ARGS__ is lazy since it's inside the if statement.
#define log_(level, ...) \
do { \
if (level <= bb_log_level) { \
log_function(level, format(__VA_ARGS__)); \
} \
} while (0)

#define log_fatal(...) log_(LogLevel::FATAL, __VA_ARGS__)
#define log_error(...) log_(LogLevel::ERROR, __VA_ARGS__)
#define log_warn(...) log_(LogLevel::WARN, __VA_ARGS__)
#define important(...) log_(LogLevel::WARN, "important: ", __VA_ARGS__)
#define info(...) log_(LogLevel::INFO, __VA_ARGS__)
#define vinfo(...) log_(LogLevel::VERBOSE, __VA_ARGS__)
#define log_verbose(...) log_(LogLevel::VERBOSE, __VA_ARGS__)

// The following logging levels are only compiled in debug mode (i.e., NDEBUG is not defined).
#ifndef NDEBUG
#define debug(...) debug_([&]() { return format(__VA_ARGS__); })
#define debug(...) log_(LogLevel::DEBUG, __VA_ARGS__)
#define log_trace(...) log_(LogLevel::TRACE, __VA_ARGS__)
#else
#define debug(...) (void)0
#define log_trace(...) (void)0
#endif

// We take a function so that evaluation is lazy.
inline void debug_(std::function<std::string()> func)
{
if (debug_logging) {
log_function(LogLevel::DEBUG, func().c_str());
}
}

template <typename... Args> inline void info(Args... args)
{
log_function(LogLevel::INFO, format(args...).c_str());
}

#define vinfo(...) vinfo_([&]() { return format(__VA_ARGS__); })

extern bool verbose_logging;
inline void vinfo_(std::function<std::string()> func)
{
if (verbose_logging) {
log_function(LogLevel::VERBOSE, func().c_str());
}
}

template <typename... Args> inline void important(Args... args)
{
log_function(LogLevel::IMPORTANT, format("important: ", args...).c_str());
}

/**
* @brief Info used to store circuit statistics during CI/CD with concrete structure. Writes straight to log
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,9 @@ T deserialize_msgpack_compact(std::vector<uint8_t>&& buf, std::function<T(msgpac
// Expect format marker for msgpack or msgpack-compact
const uint8_t FORMAT_MSGPACK = 2;
const uint8_t FORMAT_MSGPACK_COMPACT = 3;
uint8_t format = buf[0];
BB_ASSERT(format == FORMAT_MSGPACK || format == FORMAT_MSGPACK_COMPACT,
"deserialize_msgpack_compact: expected msgpack format marker (2 or 3), got " + std::to_string(format));
uint8_t format_u8 = buf[0];
BB_ASSERT(format_u8 == FORMAT_MSGPACK || format_u8 == FORMAT_MSGPACK_COMPACT,
"deserialize_msgpack_compact: expected msgpack format marker (2 or 3), got " + std::to_string(format_u8));

// Skip the format marker to get the data.
const char* buffer = &reinterpret_cast<const char*>(buf.data())[1];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,32 +18,43 @@ namespace {

// Log levels from TS foundation/src/log/log-levels.ts: ['silent', 'fatal', 'error', 'warn', 'info', 'verbose', 'debug',
// 'trace'] Map: 0=silent, 1=fatal, 2=error, 3=warn, 4=info, 5=verbose, 6=debug, 7=trace
constexpr int LOG_LEVEL_VERBOSE = 5;
constexpr int LOG_LEVEL_TRACE = 7;

// Helper to set logging flags based on TS log level
inline void set_logging_from_level(int log_level)
// Helper to set logging level based on TS log level
inline void set_logging_from_level(int ts_log_level)
{
// Turn verbose_logging on if log level is verbose (5) or above
verbose_logging = (log_level >= LOG_LEVEL_VERBOSE);
// Turn debug_logging on if log level is trace (7) or above
debug_logging = (log_level >= LOG_LEVEL_TRACE);
// Map TS log level (0-7) to C++ LogLevel enum
// TS: 0=silent, 1=fatal, 2=error, 3=warn, 4=info, 5=verbose, 6=debug, 7=trace
// C++: SILENT=0, FATAL=1, ERROR=2, WARN=3, INFO=4, VERBOSE=5, DEBUG=6, TRACE=7
// They map 1:1
if (ts_log_level >= 0 && ts_log_level <= 7) {
bb_log_level = static_cast<LogLevel>(ts_log_level);
} else {
log_warn("Invalid log level from TypeScript: ", ts_log_level, ". Using default.");
}
}

// Map C++ LogLevel enum to TypeScript log level string
// C++ LogLevel: DEBUG=0, INFO=1, VERBOSE=2, IMPORTANT=3
// C++ LogLevel: SILENT=0, FATAL=1, ERROR=2, WARN=3, INFO=4, VERBOSE=5, DEBUG=6, TRACE=7
// TS LogLevels: ['silent', 'fatal', 'error', 'warn', 'info', 'verbose', 'debug', 'trace']
inline const char* cpp_log_level_to_ts(LogLevel level)
{
switch (level) {
case LogLevel::DEBUG:
return "debug";
case LogLevel::SILENT:
return "silent";
case LogLevel::FATAL:
return "fatal";
case LogLevel::ERROR:
return "error";
case LogLevel::WARN:
return "warn";
case LogLevel::INFO:
return "info";
case LogLevel::VERBOSE:
return "verbose";
case LogLevel::IMPORTANT:
return "warn";
case LogLevel::DEBUG:
return "debug";
case LogLevel::TRACE:
return "trace";
default:
return "info";
}
Expand All @@ -53,18 +64,17 @@ inline const char* cpp_log_level_to_ts(LogLevel level)
// This allows C++ logging to call back to TypeScript logger from worker threads
LogFunction create_log_function_from_tsfn(const std::shared_ptr<Napi::ThreadSafeFunction>& logger_tsfn)
{
return [logger_tsfn](LogLevel level, const char* msg) {
return [logger_tsfn](LogLevel level, const std::string& msg) {
// Convert C++ LogLevel to TS log level string
const char* ts_level = cpp_log_level_to_ts(level);
std::string msg_str(msg);

// Call TypeScript logger function on the JS main thread
// Using BlockingCall to ensure synchronous execution
// Ignore errors - logging failures shouldn't crash the simulation
logger_tsfn->BlockingCall([ts_level, msg_str](Napi::Env env, Napi::Function js_logger) {
logger_tsfn->BlockingCall([ts_level, &msg](Napi::Env env, Napi::Function js_logger) {
// Create arguments: (level: string, msg: string)
auto level_js = Napi::String::New(env, ts_level);
auto msg_js = Napi::String::New(env, msg_str);
auto msg_js = Napi::String::New(env, msg);
js_logger.Call({ level_js, msg_js });
});
};
Expand Down
Loading