202 lines
10 KiB
Markdown
202 lines
10 KiB
Markdown
|
|
#### 简介
|
|||
|
|
MESA_handle_logger_new是基于开源C++日志库[easylogging++](https://github.com/muflihun/easyloggingpp)封装的新的日志库。具有以下特性:
|
|||
|
|
|
|||
|
|
* 线程安全
|
|||
|
|
* 强大的配置功能
|
|||
|
|
* 保留旧接口不变,完全兼容旧程序
|
|||
|
|
|
|||
|
|
#### 安装方法
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
git clone https://git.mesalab.cn/leo/MESA_handle_logger_new
|
|||
|
|
cd MESA_handle_logger_new
|
|||
|
|
//install到MESA_handle_logger_new/lib/下
|
|||
|
|
make && make install
|
|||
|
|
//指定运行时链接的日志库为新的.so的目录
|
|||
|
|
export LD_LIBRARY_PATH="xxxx"
|
|||
|
|
```
|
|||
|
|
#### 对外接口
|
|||
|
|
* 获取日志句柄
|
|||
|
|
* 为了兼容旧程序,我们保留了旧的接口,同时提供了一个新的方法用来获取句柄
|
|||
|
|
* MESA_create_runtime_log_handle( )和MESA_create_runtime_log_handle_new( )中会使用一份默认的日志配置。具体内容见src/MESA_handle_logger.c中的set_default_conf( )函数
|
|||
|
|
|
|||
|
|
```c++
|
|||
|
|
/* functionality: 旧接口,用来获取日志句柄
|
|||
|
|
params:
|
|||
|
|
file_path: 日志文件保存路径, 长度不能超过256
|
|||
|
|
level: 日志文件级别,>=该级别的日志才会输出,level = {RLOG_LV_DEBUG, RLOG_LV_INFO, RLOG_LV_FATAL }
|
|||
|
|
returns:
|
|||
|
|
void*: 返回一个日志句柄
|
|||
|
|
*/
|
|||
|
|
void *MESA_create_runtime_log_handle(const char *file_path, int level);
|
|||
|
|
|
|||
|
|
|
|||
|
|
/* functionality: 新接口,用来获取日志句柄
|
|||
|
|
desc: 新接口不用显示指定日志文件路径和日志级别,可以在配置文件配置或者通过MESA_set_runtime_log_handle_opt指定
|
|||
|
|
对于新程序,我们推荐使用这种方法
|
|||
|
|
params:
|
|||
|
|
logger_id: 一个logger_id唯一标识一个日志句柄
|
|||
|
|
returns:
|
|||
|
|
void*: 返回一个日志句柄
|
|||
|
|
*/
|
|||
|
|
void* MESA_create_runtime_log_handle_new(const char* logger_id);
|
|||
|
|
```
|
|||
|
|
* 配置日志属性
|
|||
|
|
* 我们提供了两种方法用来配置日志属性
|
|||
|
|
* 读取配置文件
|
|||
|
|
* 在代码中显式配置某个属性
|
|||
|
|
|
|||
|
|
```c++
|
|||
|
|
/* functionality: 读取日志配置文件,我们推荐使用这种方法
|
|||
|
|
params:
|
|||
|
|
handle: 日志句柄
|
|||
|
|
conf_file_path: 配置文件路径
|
|||
|
|
returns:
|
|||
|
|
0: 成功
|
|||
|
|
-1: 失败
|
|||
|
|
*/
|
|||
|
|
int MESA_read_runtime_log_handle_conf(void* handle, const char* conf_file_path);
|
|||
|
|
|
|||
|
|
|
|||
|
|
/* functionality: 设置某个日志属性
|
|||
|
|
desc: 可配置的属性值见"可配置日志属性"
|
|||
|
|
params:
|
|||
|
|
handle: 日志句柄
|
|||
|
|
level: 设置的日志级别,level = {RLOG_LV_DEBUG, RLOG_LV_INFO, RLOG_LV_FATAL }
|
|||
|
|
key: 配置的属性
|
|||
|
|
value: 配置的属性值
|
|||
|
|
returns:
|
|||
|
|
0: 成功
|
|||
|
|
-1: 失败
|
|||
|
|
*/
|
|||
|
|
int MESA_set_runtime_log_handle_opt(void* handle, int level, const char* key, const char* value);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
* 写日志
|
|||
|
|
* 写日志接口保持和原来一致
|
|||
|
|
|
|||
|
|
```c++
|
|||
|
|
/* functionality: 写日志
|
|||
|
|
params:
|
|||
|
|
handle: 日志句柄
|
|||
|
|
level: 设置的日志级别,level = {RLOG_LV_DEBUG, RLOG_LV_INFO, RLOG_LV_FATAL }
|
|||
|
|
module: 日志所属模块
|
|||
|
|
fmt: 格式化字符串,单条日志长度不能超过4096
|
|||
|
|
returns: none
|
|||
|
|
*/
|
|||
|
|
void MESA_handle_runtime_log(void *handle, int level, const char *module, const char *fmt, ...);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
* 释放句柄
|
|||
|
|
* 释放句柄保持和原来一致
|
|||
|
|
|
|||
|
|
```c++
|
|||
|
|
/* functionality: 释放日志句柄
|
|||
|
|
params:
|
|||
|
|
handle: 日志句柄
|
|||
|
|
returns: none
|
|||
|
|
*/
|
|||
|
|
void MESA_destroy_runtime_log_handle(void *handle);
|
|||
|
|
```
|
|||
|
|
#### 可配置日志属性
|
|||
|
|
|
|||
|
|
| Configuration Name | Description | Value |
|
|||
|
|
| --- | --- | --- |
|
|||
|
|
| `enabled` | Determines whether or not corresponding level for logger is enabled | {“true”, “false”} |
|
|||
|
|
| `to_file` | Whether or not to write corresponding log to log file | {“true”, “false”} |
|
|||
|
|
| `to_standard_output` | Whether or not to write logs to standard output e.g, terminal or command prompt | {“true”, “false”} |
|
|||
|
|
| `format` | Determines format/pattern of logging for corresponding level and logger. | 如: ”[%level%datetime{%Y-%M-%d %H:%m:%s}]: %msg“ |
|
|||
|
|
| `file_name` | Determines log file (full path) to write logs to for corresponding level and logger | 如: “./log2/debug_log_%datetime{%Y-%M-%d}“ |
|
|||
|
|
| `max_log_file_size` | If log file size of corresponding level is >= specified size, log file will be truncated. | 如: “2097152” |
|
|||
|
|
| `sub_second_precision` | Specifies subsecond precision (previously called 'milliseconds width')|{“1”, “2”, “3”, “4”, “5”, “6”,}|
|
|||
|
|
|`performance_tracking` |determines whether or not performance tracking is enabled|{“true”, “false”}|
|
|||
|
|
| `log_flush_threshold` | Specifies number of log entries to hold until we flush pending log data|如: “100” |
|
|||
|
|
|
|||
|
|
#### 日志格式说明符
|
|||
|
|
| Specifier | Replaced By |
|
|||
|
|
|-----------------|---------------------------------------------------------------------------------------------|
|
|||
|
|
| `%logger` | Logger ID |
|
|||
|
|
| `%thread` | Thread ID - Uses std::thread if available, otherwise GetCurrentThreadId() on windows |
|
|||
|
|
| `%level` | Severity level (Info, Debug, Error, Warning, Fatal, Verbose, Trace) |
|
|||
|
|
| `%levshort` | Severity level (Short version i.e, I for Info and respectively D, E, W, F, V, T) |
|
|||
|
|
| `%vlevel` | Verbosity level (Applicable to verbose logging) |
|
|||
|
|
| `%datetime` | Date and/or time - Pattern is customizable - see Date/Time Format Specifiers below |
|
|||
|
|
| `%user` | User currently running application |
|
|||
|
|
| `%host` | Computer name application is running on |
|
|||
|
|
| `%file` | File name of source file (Full path) - This feature is subject to availability of `__FILE__` macro of compiler |
|
|||
|
|
| `%fbase` | File name of source file (Only base name) | | `%line` | Source line number - This feature is subject to availability of `__LINE__` macro of compile |
|
|||
|
|
| `%func` | Logging function |
|
|||
|
|
| `%loc` | Source filename and line number of logging (separated by colon) |
|
|||
|
|
| `%msg` | Actual log message | | `%` | Escape character (e.g, %%level will write %level) |
|
|||
|
|
|
|||
|
|
#### 日志配置文件格式
|
|||
|
|
* 这里仅仅以FATAL级别的配置为例,完整配置参考sample/new/sample.conf
|
|||
|
|
* %level, %datetime是日志格式说明符, 参考“日志格式说明符”
|
|||
|
|
* GLOBAL是全局配置,作用于所有Level。其相当于一个开关。
|
|||
|
|
* 若GLOBAL中配置了属性A:
|
|||
|
|
* Level(DEBUG,INFO,FATAL)中配置了属性A:Level使用自己配置的属性A
|
|||
|
|
* Level(DEBUG,INFO,FATAL)中没有配置属性A:Level使用GLOBAL中配置的属性A
|
|||
|
|
* 若GLOBAL中没有配置属性A:
|
|||
|
|
* 无论Level(DEBUG,INFO,FATAL)中是否配置属性A,属性A均不生效
|
|||
|
|
|
|||
|
|
```c++
|
|||
|
|
* GLOBAL:
|
|||
|
|
FORMAT = "[%level|%datetime{%Y-%M-%d %H:%M:%s}]: %msg"
|
|||
|
|
FILENAME = "myeasylog.log"
|
|||
|
|
ENABLED = true
|
|||
|
|
TO_FILE = true
|
|||
|
|
TO_STANDARD_OUTPUT = true
|
|||
|
|
## SUBSECOND_PRECISION = 6
|
|||
|
|
## PERFORMANCE_TRACKING = true
|
|||
|
|
## MAX_LOG_FILE_SIZE = 2097152
|
|||
|
|
## LOG_FLUSH_THRESHOLD = 100
|
|||
|
|
|
|||
|
|
* FATAL:
|
|||
|
|
FORMAT = "[%level|%datetime{%Y-%M-%d %H:%m:%s}]: %msg" ##日志内容格式
|
|||
|
|
FILENAME = "./log1/fatal_log_%datetime{%Y-%M-%d}" ##日志保存路径
|
|||
|
|
ENABLED = true
|
|||
|
|
TO_FILE = true
|
|||
|
|
TO_STANDARD_OUTPUT = true
|
|||
|
|
##SUBSECOND_PRECISION = 6 ## 暂时用不到
|
|||
|
|
##PERFORMANCE_TRACKING = true ## 暂时用不到
|
|||
|
|
##MAX_LOG_FILE_SIZE = 2097152 ## 文件最大值,超过该值后日志文件会truncated,这里是2MB
|
|||
|
|
##LOG_FLUSH_THRESHOLD = 100 ## Flush after every 100 logs, 暂时用不到
|
|||
|
|
```
|
|||
|
|
#### 示例程序
|
|||
|
|
* 旧程序
|
|||
|
|
|
|||
|
|
```c++
|
|||
|
|
void* handle = MESA_create_runtime_log_handle("./log/sample_log", RLOG_LV_DEBUG);
|
|||
|
|
MESA_handle_runtime_log(handle, RLOG_LV_DEBUG, "module", "test debug log:%s", "xxxxx");
|
|||
|
|
MESA_destroy_runtime_log_handle(handle);
|
|||
|
|
```
|
|||
|
|
* 新程序
|
|||
|
|
|
|||
|
|
```c++
|
|||
|
|
##通过读取配置文件设置日志属性
|
|||
|
|
void* handle1 = MESA_create_runtime_log_handle_new("logger_id1");
|
|||
|
|
int rtn = MESA_read_runtime_log_handle_conf(handle, "./sample.conf");
|
|||
|
|
MESA_handle_runtime_log(handle, RLOG_LV_DEBUG, "module_test_read_conf", "test debug log:%s", "xxxxx");
|
|||
|
|
MESA_destroy_runtime_log_handle(handle1);
|
|||
|
|
|
|||
|
|
##通过代码中显式设置某个日志属性
|
|||
|
|
void* handle2 = MESA_create_runtime_log_handle("logger_id2");
|
|||
|
|
MESA_set_runtime_log_handle_opt(handle, RLOG_LV_DEBUG, "enabled", "true");
|
|||
|
|
MESA_set_runtime_log_handle_opt(handle, RLOG_LV_DEBUG, "to_file", "true");
|
|||
|
|
MESA_set_runtime_log_handle_opt(handle, RLOG_LV_DEBUG, "to_standard_output", "true");
|
|||
|
|
MESA_set_runtime_log_handle_opt(handle, RLOG_LV_DEBUG, "format", "[%level|%datetime{%Y-%M-%d %H:%m:%s}]: %msg");
|
|||
|
|
MESA_set_runtime_log_handle_opt(handle, RLOG_LV_DEBUG, "file_name", "./log2/debug_log_%datetime{%Y-%M-%d}");
|
|||
|
|
MESA_set_runtime_log_handle_opt(handle, RLOG_LV_DEBUG, "sub_second_precision", "6");
|
|||
|
|
MESA_set_runtime_log_handle_opt(handle, RLOG_LV_DEBUG, "performance_tracking", "true");
|
|||
|
|
MESA_set_runtime_log_handle_opt(handle, RLOG_LV_DEBUG, "max_log_file_size", "2097152");
|
|||
|
|
MESA_set_runtime_log_handle_opt(handle, RLOG_LV_DEBUG, "log_flush_threshold", "100");
|
|||
|
|
```
|
|||
|
|
#### F.A.Q
|
|||
|
|
* 对于旧的程序,如果想在不修改代码的情况下也想使用配置文件进行日志配置,可不可以呢?
|
|||
|
|
* 可以,在旧接口MESA_create_runtime_log_handle( )中,我们会读取 **MESA_HANDLE_LOGGER_CONF_PATH**这个环境变量。然后根据环境变量中的路径读取配置文件进行配置。
|
|||
|
|
* 所以你只需要编写配置文件,然后export MESA_HANDLE_LOGGER_CONF_PATH="xxxxx"就可以使用配置文件进行配置了。
|
|||
|
|
* 其中xxxx为你的配置文件所在的路径
|
|||
|
|
|
|||
|
|
|
|||
|
|
|