- Update open-x4-sdk submodule to 9f76376 (BatteryMonitor ESP-IDF 5.x compat) - Add RTC_NOINIT bounds check for logHead in Logging.cpp - Add drawTextRotated90CCW to GfxRenderer for dictionary UI - Add getWordXpos() accessor to TextBlock for dictionary word selection - Fix bare include paths (ActivityResult.h, RenderLock.h) across 10 files - Fix rvalue ref binding in setResult() lambdas (std::move pattern) - Fix std::max type mismatch (uint8_t vs int) in EpubReaderActivity - Fix FsFile forward declaration conflict in Dictionary.h - Restore StringUtils::checkFileExtension() and sortFileList() - Restore RecentBooksStore::removeBook() Made-with: Cursor
85 lines
2.2 KiB
C++
85 lines
2.2 KiB
C++
#include "Logging.h"
|
|
|
|
#include <string>
|
|
|
|
#define MAX_ENTRY_LEN 256
|
|
#define MAX_LOG_LINES 16
|
|
|
|
// Simple ring buffer log, useful for error reporting when we encounter a crash
|
|
RTC_NOINIT_ATTR char logMessages[MAX_LOG_LINES][MAX_ENTRY_LEN];
|
|
RTC_NOINIT_ATTR size_t logHead = 0;
|
|
|
|
void addToLogRingBuffer(const char* message) {
|
|
// RTC_NOINIT memory may contain garbage after flash erase or power loss
|
|
if (logHead >= MAX_LOG_LINES) {
|
|
logHead = 0;
|
|
}
|
|
strncpy(logMessages[logHead], message, MAX_ENTRY_LEN - 1);
|
|
logMessages[logHead][MAX_ENTRY_LEN - 1] = '\0';
|
|
logHead = (logHead + 1) % MAX_LOG_LINES;
|
|
}
|
|
|
|
// Since logging can take a large amount of flash, we want to make the format string as short as possible.
|
|
// This logPrintf prepend the timestamp, level and origin to the user-provided message, so that the user only needs to
|
|
// provide the format string for the message itself.
|
|
void logPrintf(const char* level, const char* origin, const char* format, ...) {
|
|
va_list args;
|
|
va_start(args, format);
|
|
char buf[MAX_ENTRY_LEN];
|
|
char* c = buf;
|
|
// add the timestamp
|
|
{
|
|
unsigned long ms = millis();
|
|
int len = snprintf(c, sizeof(buf), "[%lu] ", ms);
|
|
if (len < 0) {
|
|
return; // encoding error, skip logging
|
|
}
|
|
c += len;
|
|
}
|
|
// add the level
|
|
{
|
|
const char* p = level;
|
|
size_t remaining = sizeof(buf) - (c - buf);
|
|
while (*p && remaining > 1) {
|
|
*c++ = *p++;
|
|
remaining--;
|
|
}
|
|
if (remaining > 1) {
|
|
*c++ = ' ';
|
|
}
|
|
}
|
|
// add the origin
|
|
{
|
|
int len = snprintf(c, sizeof(buf) - (c - buf), "[%s] ", origin);
|
|
if (len < 0) {
|
|
return; // encoding error, skip logging
|
|
}
|
|
c += len;
|
|
}
|
|
// add the user message
|
|
vsnprintf(c, sizeof(buf) - (c - buf), format, args);
|
|
va_end(args);
|
|
if (logSerial) {
|
|
logSerial.print(buf);
|
|
}
|
|
addToLogRingBuffer(buf);
|
|
}
|
|
|
|
std::string getLastLogs() {
|
|
std::string output;
|
|
for (size_t i = 0; i < MAX_LOG_LINES; i++) {
|
|
size_t idx = (logHead + i) % MAX_LOG_LINES;
|
|
if (logMessages[idx][0] != '\0') {
|
|
output += logMessages[idx];
|
|
}
|
|
}
|
|
return output;
|
|
}
|
|
|
|
void clearLastLogs() {
|
|
for (size_t i = 0; i < MAX_LOG_LINES; i++) {
|
|
logMessages[i][0] = '\0';
|
|
}
|
|
logHead = 0;
|
|
}
|