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<el::LogBuilder> 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:
将easylogging++.cc 源代码以头文件方式导入

#include <easylogging++.h>
#include <easylogging++.cc>

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

2.实例

1.代码

1_easylogging_日志.cc

#include <easylogging++.h>
// #include <easylogging++.cc>INITIALIZE_EASYLOGGINGPP    // 初始化宏,有且只能使用一次int main(int argc, char* argv[]) {LOG(INFO) << "My first info log using default logger";return 0;
}

my_log.conf

* GLOBAL:ENABLED                 =   trueTO_FILE                 =   trueTO_STANDARD_OUTPUT      =   trueFORMAT                  =   "[%level | %datetime] | %msg"FILENAME                =   "log/log_%datetime{%Y%M%d}.log"MILLISECONDS_WIDTH      =   3PERFORMANCE_TRACKING    =   falseMAX_LOG_FILE_SIZE       =   2097152 ## 2MBLOG_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

2_easylogging_读取配置.cc

#include "easylogging++.h"INITIALIZE_EASYLOGGINGPPint 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;
}

3_easylogging_条件打印.cc

#include "easylogging++.h"INITIALIZE_EASYLOGGINGPPint 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;
}

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")  # --OKif not os.path.exists("/usr/lib/libeasylogging.so"):os.system("sudo cp -rf libeasylogging.so /usr/lib/libeasylogging.so") # --okprint("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")

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

./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

gitee 在线代码


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/2925.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSS3新增特性(二)

四、2D 转换 • 属性名&#xff1a;transform &#xff08;可用于制作2D转换&#xff0c;也可用于制作3D转转换&#xff1b;2D转换是平面上的转换&#xff0c;3D转换是在三维立体空间的转换&#xff09; • 作用&#xff1a;对元素进行水平或垂直方向的移动、缩放、旋转、拉长…

stable diffusion QA

Q&#xff1a;有关于扩散模型的一个点不太懂&#xff0c;就是损失为何是去噪Unt的输出跟随机噪声的均方差&#xff1f;假如是图像修复任务&#xff0c;那为何不是去噪结果与真实图像进行损失计算呢&#xff1f; A&#xff1a;扩散模型simple loss将U-Net的输出与随机噪声计算M…

原生小程序自定义vantUI中van-collapse手风琴组件的标题

可以根据官网的提示&#xff1a; Vant Weapp - 轻量、可靠的小程序 UI 组件库 自己做的&#xff1a; <van-collapse accordion value"{{ activeName }}" bind:change"onChange"><van-collapse-item name"{{index}}"><!-- 这是自…

二. 搭建Nginx 直播流程服务器

目录 1. 前言 2. 安装 Nginx 依赖 3.下载源码 4. 编译安装 5.配置 rtmp 服务 6.验证配置 1. 前言 服务器由 NGINX+RTMP 构成。 NGINX 是 HTTP 服务器, RTMP 是附加模块。 其中 NGINX 我选择的是用 源码编译方式 进行安装,因为这种方式可以自定义安装指定的…

React 之 内置方法setState改变state(一)

简述 this.setState 方法是React组件类&#xff08;React.Component 的子类&#xff09;的一个内置方法。当你在创建一个React组件类时&#xff0c;你继承自 React.Component&#xff0c;因此你的组件类会自动获得this.setState 方法。this.setState 用于更新组件的state。当st…

DevOps(八)Jenkins的Maven和Git插件

一、Maven简介 Maven是一个构建生命周期管理和理解工具&#xff0c;用于Java项目。它提供了标准化的构建流程&#xff0c;并简化了从项目编译到文档生成等各种构建方面的管理。 Maven是由Apache软件基金会开发和维护的一个流行的项目管理工具。它的设计目的是简化Java项目的构…

Linux驱动开发:深入理解I2C时序

目录标题 I2C简介I2C时序关键点Linux内核中的I2C时序处理I2C适配器I2C算法I2C核心 代码示例&#xff1a;I2C设备访问调试I2C时序问题 在Linux驱动开发中&#xff0c;理解和正确处理I2C时序对于确保I2C设备正常工作至关重要。本文将详细介绍I2C通信协议的时序特征&#xff0c;并…

Mongo 实现简单全文检索

创建文本索引&#xff1a; 选择一个或多个要进行全文检索的字段。使用createIndex()方法在这些字段上创建文本索引db.collection.createIndex({ fieldName: "text" }) 执行全文检索查询&#xff1a; 使用$text操作符执行全文检索查询。使用$search指定要搜索的关键…

应用在防蓝光显示器中的LED防蓝光灯珠

相比抗蓝光眼镜、防蓝光覆膜、软体降低蓝光强度这些“软”净蓝手段&#xff0c;通过对LED的发光磷粉进行LED背光进行技术革新&#xff0c;可实现硬件“净蓝”。其能够将90%以上的有害蓝光转换为450nm以上的长波低能光线&#xff0c;从硬件的角度解决了蓝光危害眼睛的问题&#…

05_c/c++开源库 spdlog日志库

1.简介与安装 spdlog 是一个用于 C 的高性能、易用的日志库。它提供了丰富的日志功能&#xff0c;包括多种日志级别、格式化输出、异步日志、自定义日志接收器等。spdlog 是一个轻量级的库&#xff0c;性能优越&#xff0c;非常适合用于需要高性能日志记录的场景。 特点 高性…

mmdetection3.1.0 bug(已解决)

mmdetection版本3.1.0 想这训练rpn网络&#xff0c;但是训练后val的时候出现了问题&#xff0c;根据Traceback&#xff0c;找到bug。 报错信息&#xff1a;ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dim…

❤️新版Linux零基础快速入门到精通——第一部分❤️

❤️新版Linux零基础快速入门到精通——第一部分❤️ 非科班的我&#xff01;Ta&#xff01;还是来了~~~1. 来认识一下Linux吧!1.1 操作系统概述1.1.1 操作系统概述1.1.2 操作系统的发展史1.1.2.1 Unix1.1.2.2 Minix1.1.2.3 Linux 1.1.3 操作系统的发展 1.2 Linux初识1.2.1 Lin…

ROS目标跟随(路径规划、雷达、slam、定位)

ROS目标跟随&#xff08;路径规划、雷达、地图、定位&#xff09; 最终效果展示一、总体launch文件1、打开已有地图2、组合小车的各个部分2.1惯性矩阵设置2.2小车底盘2.3摄像头2.4雷达2.5为机器人模型添加传动装置以及控制器2.6为机器人模型添加雷达配置2.7为机器人模型添加摄像…

【MySQL】数据库操作指南:数据类型篇

&#x1f331;博客主页&#xff1a;青竹雾色间 &#x1f331;系列专栏&#xff1a;MySQL探险日记 &#x1f618;博客制作不易欢迎各位&#x1f44d;点赞⭐收藏➕关注 ✨人生如寄&#xff0c;多忧何为 ✨ 文章目录 1. 数值类型1.1 tinyint 类型1.2 bit 类型1.3 小数类型1.3.1 f…

nacos配置mysql(windows)

nacos默认是使用的内置数据库derby ,可通过配置修改成mysql,修改成mysql之后&#xff0c;之前配置在derby的数据会丢失 本文使用mysql版本为8.0.22 nacos版本为2.3.1 在mysql里面先创建一个数据库test(名称自定义&#xff0c;和后面配置文件里面的一样就好了) 在上面创建的数据…

Milvus 在哈啰的应用与落地

向量数据库还有哪些可能性&#xff1f; 本期的【User Tech】直播告诉你答案&#xff01;明晚的直播&#xff0c;我们邀请了来自哈啰的资深研发工程师王永辉&#xff0c;他将为我们详细讲解 Milvus 在本地出行及生活服务平台的应用及未来发展的诸多可能性&#xff0c;敬请期待&a…

笔记:Python选择结构 编程题

文章目录 前言一、选择结构是什么&#xff1f;二、编程题总结 前言 在编程中&#xff0c;选择结构是一种重要的控制流程&#xff0c;它允许我们根据条件的满足与否选择性地执行不同的代码块。在 Python 中&#xff0c;常见的选择结构有 if、elif 和 else 语句。 if 语句允许我…

odoo 云部署

1、从镜像中安装&#xff1a;postgres docker run --name db -e POSTGRES_PASSWORD529500 -p 5432:5432 -d postgres:latest 2、从镜像中安装&#xff1a;unlimitedbiking/odoo16-enterprise docker run -v /download/addons:/mnt/extra-addons -p 8069:8069 --name odoo16 -…

如何在Windows服务做性能测试(CPU、磁盘、内存)

目录 前言1. 基本知识2. 参数说明 前言 由于需要做一些接口测试&#xff0c;测试是否有真的优化 1. 基本知识 该基本知识主要用来用到Performance Monitor&#xff0c;以下着重介绍下这方面的知识 性能监视器&#xff08;Performance Monitor&#xff09;&#xff1a;Windo…

C++ 核心编程 - 内存分区模型

文章目录 1.1 程序运行前1.2 程序运行后1.3 new 操作符 C 程序在执行时&#xff0c;将内存大致划分为 4个区域&#xff1a; 代码区&#xff1a;存放函数体的二进制代码&#xff0c;由操作系统进行管理&#xff1b;全局区&#xff1a;存放全局变量和静态变量以及常量&#xff1…