Log Manager API 快速参考
核心 littlefs 适配层 API(项目现有)
文件系统管理
fs_adapt_mount() // ✅ 挂载文件系统
fs_adapt_unmount() // ✅ 卸载文件系统
fs_adapt_mkdir(path) // ✅ 创建目录
文件操作
fd = fs_adapt_open(path, flags) // 打开文件,返回文件描述符 (fd)
fs_adapt_close(fd) // 关闭文件
bytes = fs_adapt_write(fd, buf, len) // 写入数据
bytes = fs_adapt_read(fd, buf, len) // 读取数据
fs_adapt_sync(fd) // 同步数据到 Flash
fs_adapt_delete(path) // 删除文件
fs_adapt_stat(path, &size) // 获取文件大小
fs_adapt_seek(fd, offset, whence) // 文件指针定位
文件打开标志(fcntl.h)
O_RDONLY // 只读
O_WRONLY // 只写
O_RDWR // 读写
O_CREAT // 创建(不存在时)
O_APPEND // 追加模式
O_TRUNC // 截断文件
O_EXCL // 若文件存在则失败
littlefs 定位方向
LFS_SEEK_SET // 从文件开头
LFS_SEEK_CUR // 从当前位置
LFS_SEEK_END // 从文件末尾
日志管理库 API(新增)
1️⃣ 初始化和清理
// ========= 初始化日志系统 =========
int log_manager_init(void);
// 返回值: 0=成功, -1=失败
// 功能: 挂载文件系统、创建日志目录、初始化管理器
// 调用时机: 应用启动时,其他日志操作前
// ========= 关闭日志系统 =========
int log_manager_cleanup(void);
// 返回值: 0=成功, -1=失败
// 功能: 同步数据、关闭当前文件、卸载文件系统
// 调用时机: 系统关闭时、不再需要日志时
示例:
if (log_manager_init() != 0) {
printf("日志系统初始化失败\n");
return -1;
}
// ... 使用日志 ...
log_manager_cleanup();
2️⃣ 日志写入
// ========= 写入简单日志 =========
int log_manager_write(const char *log_message);
// 参数: log_message - 日志内容(以 \0 结尾的字符串)
// 返回值: 写入字节数(含换行符), -1=失败
// 功能: 追加日志消息,自动添加换行符
// 自动功能: 检测文件大小,超过 1MB 自动轮转到新文件
// 示例:
log_manager_write("系统启动成功");
log_manager_write("传感器初始化完成");
// ========= 格式化日志(printf 风格)=========
int log_manager_printf(const char *format, ...);
// 参数: format - 格式字符串(同 printf)
// 返回值: 写入字节数, -1=失败
// 功能: 支持格式化输出
// 示例:
int temp = 28;
int humidity = 65;
log_manager_printf("温度: %d°C, 湿度: %d%%", temp, humidity);
log_manager_printf("电压: %.2fV, 电流: %.1fmA", 3.27f, 45.2f);
log_manager_printf("设备ID: %s, 版本: %s", "WS63-001", "v1.0");
// ========= 带级别的日志 =========
int log_manager_write_level(const char *level, const char *message);
// 参数:
// level - 日志级别: "INFO", "WARN", "ERROR", "DEBUG"
// message - 日志内容
// 返回值: 写入字节数, -1=失败
// 功能: 自动添加时间戳和级别前缀
// 示例:
log_manager_write_level("INFO", "系统初始化");
log_manager_write_level("WARN", "内存使用率高于 80%");
log_manager_write_level("ERROR", "连接超时,重试中");
log_manager_write_level("DEBUG", "调试信息:变量值 = 123");
// 输出格式示例:
// [14:30:22] [INFO ] 系统初始化
// [14:30:22] [WARN ] 内存使用率高于 80%
// [14:30:22] [ERROR] 连接超时,重试中
3️⃣ 日志读取
// ========= 读取整个日志文件 =========
int log_manager_read(const char *filename, char *buffer, size_t max_len);
// 参数:
// filename - 日志文件名(不含 /logs/)
// buffer - 输出缓冲区
// max_len - 缓冲区大小
// 返回值: 读取字节数, 0=文件不存在, -1=失败
// 功能: 读取整个文件内容到缓冲区,末尾添加 \0
// 示例:
char log_content[4096];
int bytes_read = log_manager_read("20250206_143022.log",
log_content,
sizeof(log_content));
if (bytes_read > 0) {
printf("日志内容:\n%s\n", log_content);
} else {
printf("文件不存在或读取失败\n");
}
// ========= 读取部分日志(指定偏移) =========
int log_manager_read_offset(const char *filename,
char *buffer, size_t max_len,
unsigned int offset);
// 参数:
// filename - 日志文件名
// buffer - 输出缓冲区
// max_len - 缓冲区大小
// offset - 文件开头的偏移字节数
// 返回值: 读取字节数, -1=失败
// 功能: 从指定位置读取数据(用于读取大文件的一部分)
// 示例:读取最后 512 字节
char last_512[512];
unsigned int file_size = 0;
log_manager_get_file_size("20250206_143022.log", &file_size);
if (file_size > 512) {
log_manager_read_offset("20250206_143022.log",
last_512, sizeof(last_512),
file_size - 512);
printf("最后 512 字节:\n%s\n", last_512);
}
4️⃣ 文件管理
// ========= 获取文件大小 =========
int log_manager_get_file_size(const char *filename, unsigned int *file_size);
// 参数:
// filename - 日志文件名
// file_size - 输出参数,存储文件大小
// 返回值: 0=成功, -1=文件不存在或失败
// 示例:
unsigned int size = 0;
if (log_manager_get_file_size("20250206_143022.log", &size) == 0) {
printf("文件大小: %u 字节\n", size);
}
// ========= 删除日志文件 =========
int log_manager_delete_file(const char *filename);
// 参数: filename - 要删除的日志文件名
// 返回值: 0=成功, -1=失败
// 示例:
if (log_manager_delete_file("20250206_143022.log") == 0) {
printf("文件已删除\n");
} else {
printf("删除失败\n");
}
// ========= 列出所有日志文件 =========
int log_manager_list_files(log_file_info_t *files,
int max_count,
int *actual_count);
// 参数:
// files - 文件信息数组的输出缓冲区
// max_count - 最多返回的文件数
// actual_count - 实际返回的文件数(可为 NULL)
// 返回值: 0=成功, -1=失败
// log_file_info_t 结构体:
// {
// char filename[256]; // 文件名
// unsigned int size; // 文件大小(字节)
// time_t created_time; // 创建时间戳
// time_t last_modified; // 最后修改时间
// }
// 示例:
log_file_info_t files[20];
int count = 0;
if (log_manager_list_files(files, 20, &count) == 0) {
printf("找到 %d 个日志文件:\n", count);
for (int i = 0; i < count; i++) {
printf(" [%d] %s - %u 字节\n", i+1,
files[i].filename, files[i].size);
}
}
// ========= 获取总日志大小 =========
int log_manager_get_total_size(unsigned int *total_size);
// 参数: total_size - 输出总大小(字节)
// 返回值: 0=成功, -1=失败
// 示例:
unsigned int total = 0;
if (log_manager_get_total_size(&total) == 0) {
printf("日志总大小: %u 字节 (%.2f MB)\n",
total, total / 1024.0 / 1024.0);
}
5️⃣ 日志清理
// ========= 保持最新的 N 个文件,删除旧文件 =========
int log_manager_cleanup_old_files(int max_files);
// 参数: max_files - 最多保留的文件数
// 返回值: 删除的文件数, -1=失败
// 功能: 当文件数超过 max_files 时,删除最旧的文件
// 示例:只保留最新的 10 个日志文件
int deleted = log_manager_cleanup_old_files(10);
printf("删除了 %d 个旧文件\n", deleted);
// ========= 删除所有日志文件 =========
int log_manager_clear_all(void);
// 返回值: 删除的文件数, -1=失败
// 功能: 删除 /logs 目录下的所有文件,然后创建新的空日志文件
// 注意: 谨慎使用!会丢失所有日志数据
// 示例:
if (log_manager_clear_all() >= 0) {
printf("所有日志已清空\n");
}
6️⃣ 文件名和信息
// ========= 生成时间戳文件名 =========
char* log_manager_generate_filename(char *filename, size_t max_len);
// 参数:
// filename - 输出缓冲区(至少 64 字节)
// max_len - 缓冲区大小
// 返回值: 指向 filename 的指针, NULL=失败
// 功能: 生成格式为 /logs/YYYYMMDD_HHMMSS.log 的文件名
// 示例:
char name[256];
log_manager_generate_filename(name, sizeof(name));
printf("生成的文件名: %s\n", name);
// 输出示例: /logs/20250206_143022.log
// ========= 获取当前日志文件信息 =========
int log_manager_get_current_file_info(log_file_info_t *current_file);
// 参数: current_file - 输出当前文件信息
// 返回值: 0=成功, -1=失败
// 示例:
log_file_info_t current;
if (log_manager_get_current_file_info(¤t) == 0) {
printf("当前日志文件: %s\n", current.filename);
printf("当前文件大小: %u 字节\n", current.size);
}
使用流程图
┌─────────────────┐
│ log_manager_init() 初始化系统
└────────┬────────┘
│
┌────▼────────────────────────┐
│ 选择日志操作 │
└───┬─────────────────────────┘
│
┌────┴──────────────────────────────┐
│ │
▼ ▼
写日志 读日志
├─ write() ├─ read()
├─ printf() └─ read_offset()
└─ write_level()
│
├─ 检查文件大小
├─ 超过1MB? → 自动轮转
├─ 调用 sync()
└─ 返回写入字节数
┌─────────────────────────────────────┐
│ 文件管理 │
├─ list_files() 列出所有文件 │
├─ get_file_size() 获取文件大小 │
├─ delete_file() 删除特定文件 │
├─ cleanup_old_files() 清理旧文件 │
└─ clear_all() 删除所有文件 │
│
▼
┌──────────────────────┐
│ log_manager_cleanup() 关闭系统
└──────────────────────┘
完整工作示例
#include "log_manager.h"
#include <stdio.h>
#include <time.h>
int main(void)
{
// 1. 初始化
if (log_manager_init() != 0) {
printf("初始化失败\n");
return -1;
}
// 2. 写入各种日志
log_manager_write("日志系统启动");
log_manager_printf("时间戳: %ld", time(NULL));
log_manager_write_level("INFO", "传感器初始化");
log_manager_write_level("WARN", "电池电量低");
log_manager_write_level("ERROR", "连接失败");
// 3. 获取当前文件信息
log_file_info_t current;
log_manager_get_current_file_info(¤t);
printf("当前日志: %s (%u 字节)\n", current.filename, current.size);
// 4. 列表所有文件
log_file_info_t files[20];
int count = 0;
log_manager_list_files(files, 20, &count);
printf("共 %d 个日志文件\n", count);
// 5. 读取日志
char buffer[1024];
log_manager_read("20250206_143022.log", buffer, sizeof(buffer));
printf("日志内容:\n%s\n", buffer);
// 6. 清理旧文件(保留 10 个)
log_manager_cleanup_old_files(10);
// 7. 关闭系统
log_manager_cleanup();
return 0;
}
常用代码片段
片段1:启动日志记录
log_manager_init();
log_manager_write_level("INFO", "=== 系统启动 ===");
log_manager_printf("固件版本: v1.0.0");
log_manager_printf("编译时间: %s %s", __DATE__, __TIME__);
片段2:周期性日志
while (1) {
int temp = read_sensor_temp();
log_manager_printf("温度: %d°C", temp);
sleep(60);
}
片段3:错误记录
void on_error(int code) {
log_manager_printf("错误代码: 0x%X", code);
log_manager_write_level("ERROR", "发生异常");
}
片段4:日志导出
void export_all_logs_via_uart(void) {
log_file_info_t files[20];
int count;
log_manager_list_files(files, 20, &count);
for (int i = 0; i < count; i++) {
char buffer[4096];
log_manager_read(files[i].filename, buffer, sizeof(buffer));
uart_send(buffer, strlen(buffer));
}
}
片段5:日志查询
void search_logs_by_keyword(const char *keyword) {
char buffer[4096];
log_file_info_t files[20];
int count;
log_manager_list_files(files, 20, &count);
for (int i = 0; i < count; i++) {
log_manager_read(files[i].filename, buffer, sizeof(buffer));
if (strstr(buffer, keyword) != NULL) {
printf("在 %s 中找到\n", files[i].filename);
}
}
}