-
Notifications
You must be signed in to change notification settings - Fork 2
Utils_Logger
SweerItTer edited this page Feb 1, 2026
·
3 revisions
Logger 是 utilsCore 核心模块的日志系统,提供线程安全的日志记录功能,支持毫秒级时间戳和格式化输出。
- 线程安全的日志写入
- 毫秒级时间戳
- 格式化输出支持
- 自动管理日志文件描述符
- 调试和问题诊断
- 系统运行监控
- 性能分析
- 时间差测量
- 依赖: C++ STL
- 被依赖: 所有需要日志记录的模块
Logger 是日志系统的封装类,提供:
- 静态方法调用
- 线程安全的日志写入
- 毫秒级时间戳
- 格式化输出支持
- 自动管理日志文件描述符
- 静态类: 所有方法都是静态的
- RAII: 使用 FileStream 自动管理文件资源
FileStream 是 FILE* 的 RAII 风格包装器,提供:
- 自动文件关闭
- 移动语义支持
- 禁止拷贝
class FileStream {
public:
FileStream() noexcept; // 默认构造
explicit FileStream(FILE* fp) noexcept; // 从 FILE* 构造,接管所有权
FileStream(FileStream&& other) noexcept; // 移动构造
FileStream& operator=(FileStream&& other) noexcept; // 移动赋值
FileStream(const FileStream&) = delete; // 禁止拷贝
FileStream& operator=(const FileStream&) = delete; // 禁止拷贝
~FileStream();
FILE* get() const noexcept; // 获取原始指针
FILE* release() noexcept; // 释放所有权
void reset() noexcept; // 安全关闭文件
void reset(FILE* fp) noexcept; // 重置为新的文件指针
explicit operator bool() const noexcept; // 检查是否有效
};// 创建 FileStream
FileStream fs(fopen("log.txt", "w"));
// 移动构造
FileStream fs2 = std::move(fs);
// 移动赋值
FileStream fs3;
fs3 = std::move(fs2);
// 检查是否有效
if (fs3) {
fprintf(fs3.get(), "Hello\n");
}
// 自动关闭文件static bool LogFlag;说明: 控制日志输出的全局标志,设置为 false 时禁用日志输出。
使用例程:
Logger::LogFlag = true; // 启用日志
Logger::LogFlag = false; // 禁用日志static void initLogger();参数说明: 无
返回值: 无
所有权归属:
- 无所有权转移
注意事项:
- 创建按时间命名的日志文件,格式为
YYYY-MM-DD_HH-MM-SS.log - 必须在其他日志方法前调用
- 建议在 main 函数中使用
- 日志文件名示例:
2026-02-01_10-30-45.log
使用例程:
int main() {
Logger::initLogger(); // 初始化日志系统
Logger::log(stdout, "Application started");
return 0;
}static void log(FILE *stream, const char* format, ...);参数说明:
-
stream(输入): 输出流(stdout,stderr, 或文件流) -
format(输入): 格式化字符串,遵循标准 printf 格式规范 -
...(输入): 可变参数,匹配格式化字符串
返回值: 无
所有权归属:
- 无所有权转移
注意事项:
- 线程安全的日志记录方法
- 支持 printf 风格格式化
- 自动添加时间戳格式:
[YYYY-MM-DD HH:MM:SS.mmm] - 如果日志系统未初始化,消息将被静默丢弃
- 受
LogFlag控制,如果LogFlag为 false,不会输出
使用例程:
// 记录简单消息
Logger::log(stdout, "Service started");
// 带参数的格式化日志
int error_code = 404;
Logger::log(stderr, "Request failed with error: %d", error_code);
// 多参数日志
float temp = 23.5f;
Logger::log(stdout, "Temperature: %.1f°C, Humidity: %d%%", temp, 45);inline std::string makeTimestamp(uint64_t &out_us_epoch);参数说明:
-
out_us_epoch(输出): 输出微秒时间戳(基于 CLOCK_MONOTONIC)
返回值: 时间戳字符串,格式为 YYYY-MM-DD HH:MM:SS.mmm
所有权归属:
- 无所有权转移
注意事项:
- 使用 CLOCK_MONOTONIC 获取微秒时间戳
- 使用系统实际时间生成时间戳字符串
- 线程安全
使用例程:
uint64_t timestamp;
std::string ts = mk::makeTimestamp(timestamp);
printf("Timestamp: %s, epoch: %lu\n", ts.c_str(), timestamp);inline auto timeDiffMs(uint64_t t1, const char* msg) -> uint64_t;参数说明:
-
t1(输入): 上一个时间点(微秒时间戳) -
msg(输入): 描述时间差的字符串
返回值: 当前时间点(微秒时间戳)
所有权归属:
- 无所有权转移
注意事项:
- 如果
LogFlag为 false,返回 0 - 自动计算时间差并输出到日志
- 时间差以毫秒为单位
- 线程安全
使用例程:
uint64_t t = 0;
mk::makeTimestamp(t);
// 执行操作
process_frame();
// 输出时间差
t = mk::timeDiffMs(t, "[Frame processing]");
// 输出: [Frame processing] = 15.234 ms[YYYY-MM-DD HH:MM:SS.mmm] 消息
[2026-02-01 10:30:45.123] Service started
[2026-02-01 10:30:46.456] Request failed with error: 404
[2026-02-01 10:30:47.789] Temperature: 23.5°C, Humidity: 45%
-
日志输出: 使用
std::mutex保护日志写入 -
文件访问: 使用
FileStreamRAII 管理文件资源
- 可以从多个线程并发记录日志
- 日志格式化是线程安全的
- 不要在日志函数中递归调用日志
int main() {
Logger::initLogger(); // 初始化日志系统
Logger::log(stdout, "Application started");
Logger::log(stdout, "Version: %s", "1.0.0");
return 0;
}try {
initialize_device();
} catch (const std::exception& e) {
Logger::log(stderr, "Exception caught: %s", e.what());
}uint64_t t = 0;
mk::makeTimestamp(t);
// 执行操作
process_frame(frame);
// 输出时间差
t = mk::timeDiffMs(t, "[Frame processing]");std::thread t1([]() {
for (int i = 0; i < 100; ++i) {
Logger::log(stdout, "Thread 1: %d", i);
}
});
std::thread t2([]() {
for (int i = 0; i < 100; ++i) {
Logger::log(stdout, "Thread 2: %d", i);
}
});
t1.join();
t2.join();// 禁用日志
Logger::LogFlag = false;
// 这些日志不会被输出
Logger::log(stdout, "This won't be logged");
// 重新启用日志
Logger::LogFlag = true;
Logger::log(stdout, "This will be logged");-
初始化: 必须先调用
initLogger()才能使用其他日志方法 -
LogFlag: 设置
LogFlag为 false 可以禁用日志输出 - 线程安全: 日志记录是线程安全的
-
格式化: 使用
printf风格的格式化字符串 - 时间戳: 自动添加毫秒级时间戳
-
文件管理: 使用
FileStreamRAII 管理文件资源 -
移动语义:
FileStream支持移动语义,禁止拷贝 - 静默丢弃: 如果日志系统未初始化,消息将被静默丢弃
主页
API 文档
DMA 模块
DRM 模块
- DRM 模块总览
- DeviceController - DRM 设备控制器
- DrmLayer - DRM 图层管理
- PlanesCompositor - DRM 平面合成器
- DrmBpp - DRM 格式定义
NET 模块
- NET 模块总览
- TcpServer - TCP 服务器
- SocketConnection - Socket 连接管理
- CommandHandler - 命令处理器
- DataPacket - 数据包
V4L2 模块
- V4L2 模块总览
- CameraController - V4L2 摄像头控制器
- Frame - V4L2 帧数据结构
- FormatTool - V4L2 格式工具
- Exception - V4L2 异常类
V4L2Param 模块
- V4L2Param 模块总览
- ParamControl - 参数控制
- ParamLogger - 参数日志
- ParamProcessor - 参数处理器
RGA 模块
- RGA 模块总览
- RgaConverter - RGA 转换器
- RgaProcessor - RGA 处理器
- FormatTool - RGA 格式工具
MPP 模块
- MPP 模块总览
- EncoderContext - 编码器上下文
- EncoderCore - 编码器核心
- JpegEncoder - JPEG 编码器
- StreamWriter - 流写入器
- MppResourceGuard - MPP 资源守护
- FileTools - 文件工具
- FormatTool - 格式工具
Sys 模块
- Sys 模块总览
- CpuMonitor - CPU 监控器
- MemoryMonitor - 内存监控器
- Base - 基础类
Mouse 模块
- Mouse 模块总览
- Watcher - 鼠标监视器
Utils 模块
- Utils 模块总览
- AsyncThreadPool - 异步线程池
- ConcurrentQueue - 并发队列
- FdWrapper - 文件描述符包装器
- FenceWatcher - 围栏监视器
- FixedSizePool - 固定大小对象池
- Logger - 日志记录器
- ObjectsPool - 对象池
- OrderedQueue - 有序队列
- ProgressBar - 进度条
- SafeQueue - 安全队列
- SharedBufferState - 共享缓冲区状态
- SimpleVariant - 简单变体类型
- ThreadPauser - 线程暂停器
- ThreadUtils - 线程工具
- Types - 类型定义
- UdevMonitor - Udev 监视器