Files
esp32-bmc/main/log_handler.c
Valentin Haudiquet 6e88ce1137
All checks were successful
Build ESP32 BMC Firmware / build (push) Successful in 53s
log: add log query API endpoints and display logs on web interface
2026-03-12 16:20:01 +01:00

139 lines
2.9 KiB
C

#include "log_handler.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include <string.h>
static const char *TAG = "LOG_HANDLER";
// Ring buffer for logs
#define LOG_BUFFER_SIZE 8192
static char log_buffer[LOG_BUFFER_SIZE];
static size_t log_write_pos = 0;
static size_t log_read_pos = 0;
static size_t log_count = 0;
static SemaphoreHandle_t log_mutex = NULL;
static bool log_initialized = false;
// Vprintf callback for capturing logs
static int log_vprintf_cb(const char *fmt, va_list args) {
// First, call the default vprintf to output to console
int ret = vprintf(fmt, args);
// Then, capture to our ring buffer
if (log_mutex && log_initialized) {
char temp_buf[256];
int len = vsnprintf(temp_buf, sizeof(temp_buf), fmt, args);
if (len > 0 && len < (int)sizeof(temp_buf)) {
xSemaphoreTake(log_mutex, portMAX_DELAY);
for (int i = 0; i < len; i++) {
log_buffer[log_write_pos] = temp_buf[i];
log_write_pos = (log_write_pos + 1) % LOG_BUFFER_SIZE;
if (log_count < LOG_BUFFER_SIZE) {
log_count++;
} else {
// Buffer full, advance read position
log_read_pos = (log_read_pos + 1) % LOG_BUFFER_SIZE;
}
}
xSemaphoreGive(log_mutex);
}
}
return ret;
}
esp_err_t log_handler_init(void) {
if (log_initialized) {
ESP_LOGW(TAG, "Log handler already initialized");
return ESP_OK;
}
ESP_LOGI(TAG, "Initializing log handler");
log_mutex = xSemaphoreCreateMutex();
if (!log_mutex) {
ESP_LOGE(TAG, "Failed to create log mutex");
return ESP_ERR_NO_MEM;
}
log_write_pos = 0;
log_read_pos = 0;
log_count = 0;
memset(log_buffer, 0, LOG_BUFFER_SIZE);
// Set our custom vprintf function
esp_log_set_vprintf(log_vprintf_cb);
log_initialized = true;
ESP_LOGI(TAG, "Log handler initialized");
return ESP_OK;
}
esp_err_t log_handler_deinit(void) {
if (!log_initialized) {
return ESP_OK;
}
ESP_LOGI(TAG, "Deinitializing log handler");
// Restore default vprintf
esp_log_set_vprintf(vprintf);
if (log_mutex) {
vSemaphoreDelete(log_mutex);
log_mutex = NULL;
}
log_initialized = false;
return ESP_OK;
}
size_t log_get_buffer(char *buf, size_t buf_len) {
if (!buf || buf_len == 0 || !log_mutex) {
return 0;
}
xSemaphoreTake(log_mutex, portMAX_DELAY);
size_t to_copy = (log_count < buf_len) ? log_count : buf_len;
size_t copied = 0;
for (size_t i = 0; i < to_copy; i++) {
size_t pos = (log_read_pos + i) % LOG_BUFFER_SIZE;
buf[copied++] = log_buffer[pos];
}
xSemaphoreGive(log_mutex);
return copied;
}
void log_clear_buffer(void) {
if (!log_mutex) {
return;
}
xSemaphoreTake(log_mutex, portMAX_DELAY);
log_write_pos = 0;
log_read_pos = 0;
log_count = 0;
xSemaphoreGive(log_mutex);
}
size_t log_get_size(void) {
if (!log_mutex) {
return 0;
}
xSemaphoreTake(log_mutex, portMAX_DELAY);
size_t count = log_count;
xSemaphoreGive(log_mutex);
return count;
}