103 lines
2.9 KiB
C++
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
|