# liblog — 异步日志系统 API 参考

## 模块概述

liblog 是嵌入式装置专用的异步日志系统。支持 INFO/ERROR 两级日志，非阻塞写入。
首次调用自动初始化（pthread_once 懒启动）。控制台支持 ANSI 彩色输出，
文件支持按大小自动轮转。

**核心特性**:
- **消息池预分配**：10000 条消息槽位，运行时零 malloc
- **批量消费**：工作线程每次最多取 100 条，批量 I/O 减少系统调用
- **生产者-消费者模型**：`log_prt()` 入队（生产者）→ 工作线程出队写入（消费者）
- **文件轮转**：单文件超过 10MB 自动重命名为 `.1 → .2 → ... → .5`

## 常量与宏

| 宏 | 值 | 说明 |
|----|-----|------|
| `LOG_INFO` | 0 | INFO 级别（白色） |
| `LOG_ERROR` | 1 | ERROR 级别（红色） |
| `LOG_I(fmt, ...)` | — | INFO 便捷宏（自动填充文件名/函数名/行号） |
| `LOG_E(fmt, ...)` | — | ERROR 便捷宏 |

## 接口函数

### log_init(dir)
```c
int log_init(const char *dir);
```
手动初始化日志系统（可选）。首次调用 `log_prt()` 时会自动触发。
- `dir`: 日志目录路径，`NULL` 则默认 `/tmp/logs`
- 返回: 0 成功

### log_prt(level, file, func, line, fmt, ...)
```c
void log_prt(uint32_t level, const char *file, const char *func,
             uint32_t line, const char *fmt, ...);
```
核心日志函数（非阻塞）。从消息池取空闲块 → 填充时间/来源 → 入队 → 立即返回。

**参数**:
- `level`: `LOG_INFO` 或 `LOG_ERROR`
- `file`: `__FILE__`（源文件名）
- `func`: `__FUNCTION__`（函数名）
- `line`: `__LINE__`（行号）
- `fmt, ...`: printf 格式化

### log_file_on / log_file_off
```c
void log_file_on(void);
void log_file_off(void);
```
开启/关闭文件写入。默认关闭，通过 `log_init()` 开启。

### log_console_on / log_console_off
```c
void log_console_on(void);
void log_console_off(void);
```
开启/关闭控制台输出。默认开启。

### log_flush(void)
```c
void log_flush(void);
```
阻塞等待消息队列清空（所有日志写入完成）。

### log_cleanup(void)
```c
void log_cleanup(void);
```
停止工作线程、关闭文件句柄、释放消息池。

## 使用示例

```c
#include "myLog.h"

int main(void)
{
    // 手动初始化（可选），指定日志目录
    log_init("/var/log/myapp");

    // INFO 日志
    LOG_I("系统启动完成, CPU=%.1f%%, MEM=%uMB", 45.2, 128);

    // ERROR 日志（红色输出）
    LOG_E("通讯超时: channel=%d, addr=%u", 3, 0x01);

    // 开关控制
    log_console_off();  // 关闭控制台（仅写文件）
    LOG_I("仅文件输出");
    log_console_on();

    // 清理
    log_flush();
    log_cleanup();

    return 0;
}
```

## 依赖关系

- **依赖**: liblist (消息队列链表), libfunc (进程路径获取)
- **被依赖**: 所有需要日志的模块
