logger示例
官方仓库:logger
配置文件(configuration_logger.yaml
)
依据官方示例项目结构自行编写YAML配置文件:
# 基础信息
base_info:
project_name: Logger # 项目名称
build_mode_tags: ["EXAMPLE", "SIMULATION", "TEST_CAMERA"] # 构建模式标签
aimrt_import_options: # AimRT框架的构建选项
AIMRT_BUILD_TESTS: "OFF" # 是否构建测试代码
AIMRT_BUILD_EXAMPLES: "ON" # 是否构建示例代码
AIMRT_BUILD_DOCUMENT: "OFF" # 是否构建文档
AIMRT_BUILD_RUNTIME: "ON" # 是否构建运行时核心
AIMRT_BUILD_CLI_TOOLS: "OFF" # 是否构建命令行工具
AIMRT_BUILD_WITH_PROTOBUF: "ON" # 是否启用Protobuf支持
AIMRT_USE_LOCAL_PROTOC_COMPILER: "OFF" # 是否使用本地protoc编译器
AIMRT_BUILD_WITH_ROS2: "OFF" # 是否集成ROS2支持
AIMRT_BUILD_NET_PLUGIN: "OFF" # 是否构建网络插件
AIMRT_BUILD_ROS2_PLUGIN: "OFF" # 是否构建ROS2插件
# 模块
modules:
- name: logger_module
- name: logger_bench_module
# pkg
pkgs:
- name: logger_pkg # 包名
modules:
- name: logger_module
- name: logger_bench_module
# 部署
deploy_modes:
- name: local_deploy # 部署模式名称
deploy_ins: # 部署实例
- name: local_ins_logger # 实例名称
pkgs:
- name: logger_pkg # 实例加载的包
module目录
logger
一个最基本的 cpp logger 示例,演示内容包括:
- 如何在 AimRT 中打印 Log 到控制台;
- 如何使用不同的日志级别;
模块定义(logger_module.h
)
#pragma once
#include <atomic>
#include <future>
#include "aimrt_module_cpp_interface/module_base.h"
namespace Logger::logger_module {
using namespace aimrt;
// 日志模块类,继承自AIMRT模块基类
class LoggerModule : public aimrt::ModuleBase {
public:
LoggerModule() = default;
~LoggerModule() override = default;
// 获取模块信息
ModuleInfo Info() const override {
return ModuleInfo{.name = "LoggerModule"};
}
// 初始化模块
bool Initialize(aimrt::CoreRef aimrt_ptr) override;
// 启动模块
bool Start() override;
// 关闭模块
void Shutdown() override;
private:
aimrt::CoreRef core_; // AIMRT核心引用
aimrt::executor::ExecutorRef executor_; // 执行器引用
std::atomic_bool run_flag_ = false; // 运行标志位
std::promise<void> stop_sig_; // 停止信号
};
} // namespace Logger::logger_module
模块实现(logger_module.cc
)
#include "logger_module/logger_module.h"
#include "yaml-cpp/yaml.h"
namespace Logger::logger_module {
using namespace aimrt::logger;
bool LoggerModule::Initialize(aimrt::CoreRef core) {
// 保存AIMRT框架句柄
core_ = core;
// 获取执行器句柄
executor_ = core_.GetExecutorManager().GetExecutor("work_executor");
AIMRT_HL_CHECK_ERROR_THROW(core_.GetLogger(), executor_,
"获取执行器'work_thread_pool'失败");
AIMRT_HL_INFO(core_.GetLogger(), "初始化成功");
return true;
}
bool LoggerModule::Start() {
run_flag_ = true;
executor_.Execute([this]() {
// 为当前作用域创建日志句柄
auto GetLogger = [this]() { return core_.GetLogger(); };
std::string s = "abc";
int n = 0;
while (run_flag_.load()) {
++n;
// 输出各级别日志
AIMRT_TRACE("测试跟踪日志, 字符串 = {}, 计数器 = {}", s, n);
AIMRT_DEBUG("测试调试日志, 字符串 = {}, 计数器 = {}", s, n);
AIMRT_INFO("测试信息日志, 字符串 = {}, 计数器 = {}", s, n);
AIMRT_WARN("测试警告日志, 字符串 = {}, 计数器 = {}", s, n);
AIMRT_ERROR("测试错误日志, 字符串 = {}, 计数器 = {}", s, n);
AIMRT_FATAL("测试致命日志, 字符串 = {}, 计数器 = {}", s, n);
std::this_thread::sleep_for(std::chrono::seconds(1));
}
stop_sig_.set_value();
});
AIMRT_HL_INFO(core_.GetLogger(), "启动成功");
return true;
}
void LoggerModule::Shutdown() {
if (run_flag_) {
run_flag_ = false;
stop_sig_.get_future().wait();
}
AIMRT_HL_INFO(core_.GetLogger(), "关闭成功");
}
} // namespace Logger::logger_module
- 注意,提供的日志宏基于 C++20 Format 语法
实现内容很简单,不在此做具体分析,只需要关注配置文件的部分
对应的启动配置文件
# AIMRT框架主配置
aimrt:
# 日志系统配置
log:
# 核心日志级别,可选值:Trace/Debug/Info/Warn/Error/Fatal/Off
# 设置INFO表示只记录INFO及以上级别的日志
core_lvl: INFO
# 日志后端配置
backends:
# 使用控制台作为日志输出
- type: console
# 执行器配置
executor:
# 执行器列表
executors:
# 定义一个名为work_executor的执行器
- name: work_executor
# 执行器类型为简单线程
type: simple_thread
# 模块配置
module:
# 模块包配置
pkgs:
# 指定模块包路径
- path: ./liblogger_pkg.so
# 启用该包中的LoggerModule模块
enable_modules: [LoggerModule]
# 模块详细配置
modules:
# LoggerModule模块的配置
- name: LoggerModule
# 该模块的日志级别设置为TRACE(最详细)
log_lvl: TRACE
-
core_lvl
设置的是AimRT核心的日志等级;modules
中的log_lvl
控制的是本模块的日志等级 -
backends
:日志输出后端,支持console
(控制台)、rotate_file
(滚动文件)等多种类型
logger rotate file
一个最基本的 cpp logger 示例,演示内容包括:
-
如何使用 rotate_file 类型 Log 后端并了解其配置项;
-
代码与上一个
logger
示例完全相同
对应的启动配置文件
aimrt: # AIMRT框架根配置节点
# 日志系统配置部分
log:
# 核心日志级别配置(框架自身日志输出级别)
# 可选值(区分大小写):
# TRACE - 最详细跟踪信息(开发调试用)
# DEBUG - 调试信息
# INFO - 常规运行信息(推荐生产环境使用)
# WARN - 警告信息
# ERROR - 错误信息
# FATAL - 致命错误
# OFF - 关闭所有日志
core_lvl: INFO # 当前设置为INFO级别
# 日志输出后端配置(支持同时配置多个输出目标)
backends:
# 控制台输出配置(必选)
- type: console # 输出到标准控制台
# 滚动文件输出配置(可选)
- type: rotate_file # 滚动文件类型
options: # 文件输出专属配置
path: ./log # 日志文件存储目录(相对路径)
filename: examples_cpp_logger_rotate_file.log # 日志文件名
max_file_size_m: 4 # 单个文件最大大小(单位MB)
max_file_num: 10 # 最大保留文件数(达到后自动删除最旧文件)
# 执行器(线程池)配置部分
executor:
# 执行器列表(可配置多个执行器)
executors:
# 工作执行器配置
- name: work_executor # 执行器名称(需与代码中引用名称一致)
type: simple_thread # 执行器类型:简单线程模式
# 模块系统配置部分
module:
# 动态模块包配置(可配置多个模块包)
pkgs:
# 第一个模块包配置
- path: ./liblogger_pkg.so # 模块动态库路径(相对/绝对路径)
enable_modules: [LoggerModule] # 需要启用的模块列表(数组格式)
# 模块详细参数配置(可覆盖模块默认参数)
modules:
# Logger模块配置
- name: LoggerModule # 必须与代码中模块类名完全一致
log_lvl: TRACE # 模块专用日志级别(可独立于core_lvl设置)
logger specify executor
一个最基本的 cpp logger 示例,演示内容包括:
- 如何使用指定的执行器作为日志后端的执行线程;
- 代码与示例
logger
相同
对应的启动配置文件
aimrt: # AIMRT框架根配置节点
# 日志系统配置
log:
# 核心日志级别(框架自身日志输出级别)
# 可选值(区分大小写):
# TRACE - 最详细跟踪信息
# DEBUG - 调试信息
# INFO - 常规信息(推荐生产环境使用)
# WARN - 警告信息
# ERROR - 错误信息
# FATAL - 致命错误
# OFF - 关闭日志
core_lvl: INFO # 当前设置为INFO级别
# 日志输出后端配置
backends:
# 控制台日志输出配置
- type: console # 控制台输出类型
options:
log_executor_name: log_executor # 指定专用的日志执行器
# 执行器(线程池)配置
executor:
# 执行器列表(可配置多个)
executors:
# 工作执行器(用于业务逻辑)
- name: work_executor # 执行器名称
type: simple_thread # 简单线程模式
# 专用日志执行器(确保日志输出不阻塞业务线程)
- name: log_executor # 执行器名称需与日志配置一致
type: simple_thread # 简单线程模式
# 模块系统配置
module:
# 动态模块包配置
pkgs:
# 日志模块包配置
- path: ./liblogger_pkg.so # 模块动态库路径
enable_modules: [LoggerModule] # 启用的模块列表
# 模块参数配置
modules:
# 日志模块配置
- name: LoggerModule # 必须与代码中模块名一致
log_lvl: TRACE # 模块日志级别(开发时可用TRACE)
- 这里创建了一个单独的日志执行器,避免日志I/O操作阻塞业务线程
- 要求日志执行器是线程安全的
logger format
一个最基本的 cpp logger 示例,演示内容包括:
- 如何使用自定义的 format 格式输出日志;
- 代码与示例
logger
相同
对应的启动配置文件
aimrt: # AIMRT框架根配置节点
# 日志系统配置
log:
# 核心日志级别(框架自身日志输出级别)
# 可选值(区分大小写):
# TRACE - 最详细跟踪信息
# DEBUG - 调试信息
# INFO - 常规信息(推荐生产环境使用)
# WARN - 警告信息
# ERROR - 错误信息
# FATAL - 致命错误
# OFF - 关闭日志
core_lvl: INFO # 当前设置为INFO级别
# 日志输出后端配置
backends:
# 控制台日志输出配置
- type: console # 控制台输出类型
options:
# 日志格式模板(支持自定义格式)
# 可用占位符说明:
# %c - 日志器名称
# %f - 文件名(短格式)
# %A - 完整文件名
# %l - 行号
# %t - 线程ID
# %n - 模块名称
# %G - 日志分组
# %v - 实际日志内容
# %L - 日志级别
# %D - 日期时间(可带格式修饰,如%D{%Y-%m-%d %H:%M:%S})
pattern: "[%c.%f][%A][%l][%t][%n][%G] %v"
# 执行器(线程池)配置
executor:
# 执行器列表(可配置多个)
executors:
# 工作执行器配置
- name: work_executor # 执行器名称
type: simple_thread # 简单线程模式
# 模块系统配置
module:
# 动态模块包配置
pkgs:
# 日志模块包配置
- path: ./liblogger_pkg.so # 模块动态库路径
enable_modules: [LoggerModule] # 启用的模块列表
# 模块参数配置
modules:
# 日志模块配置
- name: LoggerModule # 必须与代码中模块名一致
log_lvl: TRACE # 模块日志级别(开发时可用TRACE)
- 配置了日志打印格式为[%c.%f][%A][%l][%t][%n][%G] %v,日志输出示例如下:
[2024-10-31 20:35:28.378443][Thursday][Info][126632][LoggerModule][logger_module.cc] Test info log
logger rotate file with sync(0.8.x版本不支持,最新main分支开始支持)
一个最基本的 cpp logger 示例,演示内容包括:
- 如何使用 rotate_file 类型 Log 后端并了解其配置项;
- 如何配置相关配置选项以开启定期落盘机制,保证数据完整性;
对应的启动配置文件
aimrt: # AIMRT框架根配置节点
# 日志系统配置
log:
# 核心日志级别(框架自身日志输出级别)
# 可选值(区分大小写):
# TRACE - 最详细跟踪信息(开发调试用)
# DEBUG - 调试信息
# INFO - 常规运行信息(推荐生产环境使用)
# WARN - 警告信息
# ERROR - 错误信息
# FATAL - 致命错误
# OFF - 关闭所有日志
core_lvl: INFO # 当前设置为INFO级别
# 日志输出后端配置(支持多后端同时输出)
backends:
# 控制台输出配置(实时输出)
- type: console # 标准控制台输出
# 轮转文件输出配置(持久化存储)
- type: rotate_file # 支持日志文件轮转
options:
path: ./log # 日志存储目录(相对路径)
filename: examples_cpp_logger_rotate_file.log # 日志文件名
max_file_size_m: 4 # 单个文件最大4MB
max_file_num: 10 # 最多保留10个历史文件
# 日志同步配置(确保日志完整性)
enable_sync: true # 启用定期同步
sync_interval_ms: 5000 # 每5秒同步到磁盘
sync_executor_name: sync_timer_executor # 使用专用执行器
# 执行器(线程池)配置
executor:
executors:
# 工作执行器(处理业务逻辑)
- name: work_executor
type: simple_thread # 简单线程模式
# 日志同步定时器执行器
- name: sync_timer_executor
type: asio_thread
# 模块系统配置
module:
# 动态模块包配置
pkgs:
- path: ./liblogger_pkg.so # 模块动态库路径
enable_modules: [LoggerModule] # 启用的模块列表
# 模块参数配置
modules:
- name: LoggerModule # 模块名称(需与代码一致)
log_lvl: TRACE # 模块日志级别(开发调试用TRACE)