/* * log_manager.h -- OreBolt OS logging subsystem * * SPDX-License-Identifier: GPL-2.0-or-later * * Combines a flash-safe timed coalescer with a structured * log level interface. Provides both: * - LOG_INF/DBG/ERR macros (structured, leveled logging) * - timed_log_* functions (RAM-buffered, windowed disk flush) * * Structured logs: /data/vault/syslog.log (rotating, 64 KB max) * Failure records: /data/vault/failures.dat (binary, append-only) */ #ifndef LOG_MANAGER_H #define LOG_MANAGER_H #include #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif /* ================================================================== */ /* Structured Log Level Interface */ /* ================================================================== */ typedef enum { LOG_TRACE = 0, LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR, LOG_FATAL } log_level_t; int log_init(const char *path); void log_close(void); void log_write(log_level_t lvl, const char *module, const char *fmt, ...); /* Failure logging -- binary, durable, used by panic_purge_api.h. */ int log_failure_record(uint32_t code, const void *blob, size_t len); #define LOG_TRC(fmt, ...) log_write(LOG_TRACE, __func__, fmt, ##__VA_ARGS__) #define LOG_DBG(fmt, ...) log_write(LOG_DEBUG, __func__, fmt, ##__VA_ARGS__) #define LOG_INF(fmt, ...) log_write(LOG_INFO, __func__, fmt, ##__VA_ARGS__) #define LOG_WRN(fmt, ...) log_write(LOG_WARN, __func__, fmt, ##__VA_ARGS__) #define LOG_ERR(fmt, ...) log_write(LOG_ERROR, __func__, fmt, ##__VA_ARGS__) #define LOG_FTL(fmt, ...) log_write(LOG_FATAL, __func__, fmt, ##__VA_ARGS__) /* ================================================================== */ /* Flash-Safe Timed Coalescer (v1.3) */ /* ================================================================== */ typedef enum { WINDOW_30S = 30, WINDOW_1M = 60, WINDOW_2M = 120, WINDOW_5M = 300, WINDOW_10M = 600 } log_window_t; #define RAM_CHUNK_LIMIT (64 * 1024) typedef struct { char *ram_pool; size_t pool_idx; time_t window_start; uint32_t window_duration; FILE *file_handle; char base_path[128]; } timed_logger_t; static inline timed_logger_t* timed_log_init(const char *filepath, log_window_t window) { static const log_window_t valid_windows[] = { WINDOW_30S, WINDOW_1M, WINDOW_2M, WINDOW_5M, WINDOW_10M }; int valid = 0; for (size_t i = 0; i < sizeof(valid_windows) / sizeof(valid_windows[0]); i++) { if (window == valid_windows[i]) { valid = 1; break; } } if (!valid) return NULL; timed_logger_t *logger = malloc(sizeof(timed_logger_t)); if (!logger) return NULL; logger->ram_pool = malloc(RAM_CHUNK_LIMIT); if (!logger->ram_pool) { free(logger); return NULL; } strncpy(logger->base_path, filepath, sizeof(logger->base_path) - 1); logger->base_path[sizeof(logger->base_path) - 1] = '\0'; memset(logger->ram_pool, 0, RAM_CHUNK_LIMIT); logger->pool_idx = 0; logger->window_duration = (uint32_t)window; logger->window_start = time(NULL); logger->file_handle = NULL; return logger; } static inline void timed_log_flush_to_media(timed_logger_t *logger) { if (!logger || logger->pool_idx == 0) return; logger->file_handle = fopen(logger->base_path, "a"); if (!logger->file_handle) return; (void)fwrite(logger->ram_pool, 1, logger->pool_idx, logger->file_handle); int fd = fileno(logger->file_handle); if (fd >= 0) fdatasync(fd); fclose(logger->file_handle); logger->file_handle = NULL; memset(logger->ram_pool, 0, RAM_CHUNK_LIMIT); logger->pool_idx = 0; logger->window_start = time(NULL); } static inline void timed_log_write(timed_logger_t *logger, const char *data) { if (!logger || !data) return; size_t data_len = strlen(data); if (data_len >= RAM_CHUNK_LIMIT) return; if (logger->pool_idx + data_len >= RAM_CHUNK_LIMIT) { timed_log_flush_to_media(logger); } memcpy(&logger->ram_pool[logger->pool_idx], data, data_len); logger->pool_idx += data_len; if (time(NULL) - logger->window_start >= logger->window_duration) { timed_log_flush_to_media(logger); } } static inline void timed_log_close(timed_logger_t *logger) { if (!logger) return; timed_log_flush_to_media(logger); free(logger->ram_pool); free(logger); } #ifdef __cplusplus } #endif #endif /* LOG_MANAGER_H */