• 17_c/c++开源库 easylogging日志库


    1.简介与安装

    简介:
    EasyLogging的主要特点包括:

    简单易用:EasyLogging的API设计简洁明了,使用起来非常方便。开发者只需包含头文件并初始化库,即可开始记录日志。
    高效性:EasyLogging采用异步日志记录方式,将日志信息的写入操作与程序的主线程分离,从而避免了日志记录对程序性能的影响。
    线程安全:EasyLogging支持多线程环境下的日志记录,内部采用了锁机制来保证线程安全。
    可配置性:EasyLogging提供了丰富的配置选项,允许开发者根据需要自定义日志记录的级别、格式、输出目标等。
    跨平台兼容:EasyLogging支持多种操作系统和编译器,具有良好的跨平台兼容性。

    安装

    sudo apt install libeasyloggingpp-dev

    使用

    编译依赖
    pkg-config --cflags --libs easyloggingpp

    没错,你没有看错, ubuntu20.04上默认安装libeasyloggingpp-dev 没有提示任何 ld链接选项.
    通过github 下载最新的源代码, 编译安装, 也是一样.
    但实际上, ld链接时提示错误:

    g++ -o 1_easylogging_日志.out 1_easylogging_日志.o
    /bin/ld: 1_easylogging_日志.o: in function `main':
    /home/liuj/1_data/3_cpp-practice/21_开源库/17_easylogging日志库/1_easylogging_日志.cc:7: undefined reference to `el::base::Writer::construct(int, char const*, ...)'
    /bin/ld: 1_easylogging_日志.o: in function `__static_initialization_and_destruction_0(int, int)':
    /home/liuj/1_data/3_cpp-practice/21_开源库/17_easylogging日志库/1_easylogging_日志.cc:4: undefined reference to `el::base::Storage::Storage(std::shared_ptr const&)'
    /bin/ld: 1_easylogging_日志.o: in function `el::LogBuilder::LogBuilder()':
    /usr/include/easylogging++.h:2197: undefined reference to `el::base::utils::OS::termSupportsColor()'
    /bin/ld: 1_easylogging_日志.o: in function `el::base::Writer::~Writer()':
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    解决方法1:
    将easylogging++.cc 源代码以头文件方式导入

    #include 
    #include 
    
    • 1
    • 2

    解决方法2:
    将libeasylogging++.cc 编译为动态库 libeasylogging.so, 拷贝到系统lib目录下 /usr/lib
    本文使用的是: 解决方法2
    1. 在scons中检测库/usr/lib/libeasylogging.so 存在,不存在则拷贝
    2. 链接选项: -leasylogging

    2.实例

    1.代码

    1_easylogging_日志.cc

    #include 
    // #include 
    
    INITIALIZE_EASYLOGGINGPP    // 初始化宏,有且只能使用一次
    
    int main(int argc, char* argv[]) {
       LOG(INFO) << "My first info log using default logger";
       return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    my_log.conf

    * GLOBAL:
        ENABLED                 =   true
        TO_FILE                 =   true
        TO_STANDARD_OUTPUT      =   true
        FORMAT                  =   "[%level | %datetime] | %msg"
        FILENAME                =   "log/log_%datetime{%Y%M%d}.log"
        MILLISECONDS_WIDTH      =   3
        PERFORMANCE_TRACKING    =   false
        MAX_LOG_FILE_SIZE       =   2097152 ## 2MB
        LOG_FLUSH_THRESHOLD     =   0
    
    * TRACE:
        FILENAME                =   "log/trace_log_%datetime{%Y%M%d}.log"
    
    * DEBUG:
        FILENAME                =   "log/debug_log_%datetime{%Y%M%d}.log"
    
    * FATAL:
        ENABLED                 =   false
    
    * ERROR:
        FILENAME                =   "log/error_log_%datetime{%Y%M%d}.log"
    
    * WARNING:
        FILENAME                =   "log/warning_log_%datetime{%Y%M%d}.log"
    
    * INFO:
        FILENAME                =   "log/info_log_%datetime{%Y%M%d}.log"
    
    * VERBOSE:
        ENABLED                 =   false
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    2_easylogging_读取配置.cc

    #include "easylogging++.h"
    
    INITIALIZE_EASYLOGGINGPP
    
    int main(int argc, char** argv)
    {
    	el::Configurations conf("my_log.conf");
    	el::Loggers::reconfigureAllLoggers(conf);
    
    	LOG(TRACE)   << "***** trace log  *****";
    	LOG(DEBUG)   << "***** debug log  *****";
    	LOG(ERROR)   << "***** error log  *****";
    	LOG(WARNING) << "***** warning log  *****";
    	LOG(INFO)    << "***** info log  *****";
    
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3_easylogging_条件打印.cc

    #include "easylogging++.h"
    
    INITIALIZE_EASYLOGGINGPP
    
    int main(int argc, char **argv)
    {
    	int i = 0;
    	while (i++ < 100)
    	{
    		//  条件日志
    		LOG_IF((i % 5 == 0), INFO) << " %5 == 0" << i;
    		// 每n次记录一次
    		LOG_EVERY_N(20, INFO) << "LOG_EVERY_N i = " << i;
    		// 当计数达到n次之后,才开始记录日志
    		LOG_AFTER_N(6, INFO) << "LOG_AFTER_N i = " << i;
    		// 当记录次数达到n次之后,就不再记录
    		LOG_N_TIMES(1, INFO) << "LOG_N_TIMES i = " << i;
    	}
    
    	return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    2.scons编译

    SConstruct

    import os
    env = Environment()
    env["PROGSUFFIX"] = ".out"            # 可执行文件后缀.out
    env["CCFLAGS"] = " -g3 -O0 -Wall"     # gdb 调试
    
    def build_share_lib():
        SharedLibrary("easylogging","easylogging++.cc")
        # Install(target="/usr/lib",source=['easylogging.so'])  # --NG
        # Command("/usr/lib/libeasylogging.so","libeasylogging.so","sudo cp -rf libeasylogging.so /usr/lib/")    # --NG
        # Command("./lib/libeasylogging.so","libeasylogging.so","cp -rf libeasylogging.so ./lib/libeasylogging.so")  # --OK
        if not os.path.exists("/usr/lib/libeasylogging.so"):
            os.system("sudo cp -rf libeasylogging.so /usr/lib/libeasylogging.so") # --ok
            print("copy libeasylogging.so /usr/lib ---ok")
            # os.system("sudo install libeasylogging.so /usr/lib") # --ok
    
    ## 模板2
    build_share_lib()
    env["LIBS"] = ["easylogging"]
    env.Program("1_easylogging_日志.cc", LIBS=["easylogging"],LIBPATH='.') # fix:scons无法优先编译 动态库easylogging.so
    env.Program("2_easylogging_读取配置.cc")
    env.Program("3_easylogging_条件打印.cc")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    scons

    scons: Reading SConscript files …
    scons: done reading SConscript files.
    scons: Building targets …
    g++ -o 1_easylogging_日志.o -c -g3 -O0 -Wall 1_easylogging_日志.cc
    g++ -o easylogging++.os -c -fPIC easylogging++.cc
    g++ -o libeasylogging.so -shared easylogging++.os
    g++ -o 1_easylogging_日志.out 1_easylogging_日志.o -L. -leasylogging
    g++ -o 2_easylogging_读取配置.o -c -g3 -O0 -Wall 2_easylogging_读取配置.cc
    g++ -o 2_easylogging_读取配置.out 2_easylogging_读取配置.o -leasylogging
    g++ -o 3_easylogging_条件打印.o -c -g3 -O0 -Wall 3_easylogging_条件打印.cc
    g++ -o 3_easylogging_条件打印.out 3_easylogging_条件打印.o -leasylogging
    scons: done building targets.

    3.运行

    ./1_easylogging_日志.out

    2024-04-24 00:45:55,850 INFO [default] My first info log using default logger

    ./2_easylogging_读取配置.out

    [TRACE | 2024-04-24 00:45:58,466] | ***** trace log  *****
    [DEBUG | 2024-04-24 00:45:58,466] | ***** debug log  *****
    [ERROR | 2024-04-24 00:45:58,466] | ***** error log  *****
    [WARNING | 2024-04-24 00:45:58,466] | ***** warning log  *****
    [INFO | 2024-04-24 00:45:58,466] | ***** info log  *****
    sh: pause: command not found
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    ./3_easylogging_条件打印.out

    2024-04-24 00:46:03,897 INFO [default] LOG_N_TIMES i = 1
    2024-04-24 00:46:03,897 INFO [default]  %5 == 05
    2024-04-24 00:46:03,897 INFO [default] LOG_AFTER_N i = 7
    2024-04-24 00:46:03,897 INFO [default] LOG_AFTER_N i = 8
    2024-04-24 00:46:03,897 INFO [default] LOG_AFTER_N i = 9
    2024-04-24 00:46:03,897 INFO [default]  %5 == 010
    2024-04-24 00:46:03,897 INFO [default] LOG_AFTER_N i = 10
    2024-04-24 00:46:03,897 INFO [default] LOG_AFTER_N i = 11
    2024-04-24 00:46:03,898 INFO [default] LOG_AFTER_N i = 12
    2024-04-24 00:46:03,898 INFO [default] LOG_AFTER_N i = 13
    2024-04-24 00:46:03,898 INFO [default] LOG_AFTER_N i = 14
    2024-04-24 00:46:03,898 INFO [default]  %5 == 015
    2024-04-24 00:46:03,898 INFO [default] LOG_AFTER_N i = 15
    2024-04-24 00:46:03,898 INFO [default] LOG_AFTER_N i = 16
    2024-04-24 00:46:03,898 INFO [default] LOG_AFTER_N i = 17
    2024-04-24 00:46:03,898 INFO [default] LOG_AFTER_N i = 18
    2024-04-24 00:46:03,898 INFO [default] LOG_AFTER_N i = 19
    2024-04-24 00:46:03,898 INFO [default]  %5 == 020
    2024-04-24 00:46:03,898 INFO [default] LOG_EVERY_N i = 20
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    gitee 在线代码


  • 相关阅读:
    windows下修改PyCharm默认terminal & 在Git Bash中使用conda
    uniapp微信小程序使用xr加载模型
    MIKE水动力笔记18_如何将dfsu流场模拟结果的数据导出成txt文件
    Git的基础操作及使用
    基于注解的AOP开发
    服务网格Service Mesh和Istio
    2022/8/13
    MySQL如何创建存储过程
    【PyQt5图形界面编程(4)】:界面开发
    文件基本属性
  • 原文地址:https://blog.csdn.net/u011326325/article/details/138145337