zephyr/rims_app/src/log.cpp
2025-06-20 11:21:24 +02:00

103 lines
2.9 KiB
C++

#include "log.hpp"
#include "zephyr/kernel.h"
#include <cassert>
#include <cstring>
#include <thread>
namespace rims {
K_FIFO_DEFINE(klogFifoQueue);
fifo_queue<log_EgressMessage, 8> logEgressQueue{klogFifoQueue};
static std::size_t g_droppedLogs{0};
void Log::trace(const char *fmt, ...) const {
va_list args;
va_start(args, fmt);
formatLog(Level::Trace, fmt, args);
va_end(args);
}
void Log::debug(const char *fmt, ...) const {
va_list args;
va_start(args, fmt);
formatLog(Level::Debug, fmt, args);
va_end(args);
}
void Log::info(const char *fmt, ...) const {
va_list args;
va_start(args, fmt);
formatLog(Level::Info, fmt, args);
va_end(args);
}
void Log::warning(const char *fmt, ...) const {
va_list args;
va_start(args, fmt);
formatLog(Level::Warning, fmt, args);
va_end(args);
}
void Log::error(const char *fmt, ...) const {
va_list args;
va_start(args, fmt);
formatLog(Level::Error, fmt, args);
va_end(args);
}
void Log::critical(const char *fmt, ...) const {
va_list args;
va_start(args, fmt);
formatLog(Level::Critical, fmt, args);
va_end(args);
}
static constexpr log_LogLevel toPbLogLevel(Log::Level level) {
return static_cast<log_LogLevel>(level);
}
static void setBasename(char *destination, const char *path) {
const char *basename = strrchr(path, '/'); // Find the last occurrence of '/'
if (basename) {
basename++; // Move past the '/'
} else {
basename = path; // No '/' found, use the whole string
}
strncpy(destination, basename, 31); // Copy basename, leaving space for null terminator
destination[31] = '\0'; // Ensure null termination
}
void Log::formatLog(Level level, const char *fmt, va_list args) const {
if (should_log(level)) {
// handle case when queue if full and we are waitnig for free space
bool ok{false};
do {
ok = logEgressQueue.try_produce([this, &args, &fmt, level](log_EgressMessage &logmsg) {
logmsg = log_EgressMessage_init_zero;
logmsg.has_request_id = false;
logmsg.which_data = log_EgressMessage_logEntry_tag;
logmsg.data.logEntry.systick = k_uptime_ticks();
logmsg.data.logEntry.level = toPbLogLevel(level);
logmsg.data.logEntry.lineNumber = this->_sl.line();
setBasename(logmsg.data.logEntry.sourceFile, this->_sl.file_name());
/// to long logs are trimmed, fuck them
vsnprintf(logmsg.data.logEntry.logLine, sizeof(logmsg.data.logEntry.logLine), fmt, args);
return true;
});
// this is out of scope of try_produce, no spinlock will be invalidated
if (not ok) {
g_droppedLogs++;
std::this_thread::sleep_for(std::chrono::microseconds{100});
}
} while (not ok);
}
}
} // namespace rims