当前位置: 首页 > news >正文

Boost之log日志使用

不讲理论,直接上在程序中可用代码:
一、引入Boost模块

开发环境:Visual Studio 2017
Boost库版本:1.68.0
安装方式:Nuget
安装命令:

#只安装下面几个即可
Install-package boost -version 1.68.0
Install-package boost_filesystem-vc141 -version 1.68.0
Install-package boost_log_setup-vc141 -version 1.68.0
Install-package boost_log-vc141 -version 1.68.0#这里是其他模块,可不安装
Install-package boost_atomic-vc141 -version 1.68.0
Install-package boost_chrono-vc141 -version 1.68.0
Install-package boost_date_time-vc141 -version 1.68.0
Install-package boost_system-vc141 -version 1.68.0
Install-package boost_thread-vc141 -version 1.68.0
Install-package boost_locale-vc141 -version 1.68.0

调用Nuget控制台:

 

二、引入下面两个hpp文件
boost_logger.hpp

#pragma once#include <string>
#include <fstream>
#include <iostream>
#include <boost/filesystem.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/core/null_deleter.hpp>
#include <boost/log/core.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/sinks/async_frontend.hpp>
#include <boost/log/sinks/text_ostream_backend.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/attributes/current_thread_id.hpp>
#include <boost/log/attributes/current_process_name.hpp>
#include <boost/log/attributes/attribute.hpp>
#include <boost/log/attributes/attribute_cast.hpp>
#include <boost/log/attributes/attribute_value.hpp>
#include <boost/log/sinks/async_frontend.hpp>// Related headersQDebug
#include <boost/log/sinks/unbounded_fifo_queue.hpp>
#include <boost/log/sinks/unbounded_ordering_queue.hpp>
#include <boost/log/sinks/bounded_fifo_queue.hpp>
#include <boost/log/sinks/bounded_ordering_queue.hpp>
#include <boost/log/sinks/drop_on_overflow.hpp>
#include <boost/log/sinks/block_on_overflow.hpp>//这里是logger的头文件,后面根据实际路径引入
#include "logger.hpp"//引入各种命名空间
namespace logging = boost::log;
namespace src = boost::log::sources;
namespace expr = boost::log::expressions;
namespace sinks = boost::log::sinks;
namespace keywords = boost::log::keywords;
namespace attrs = boost::log::attributes;
//建立日志源,支持严重属性
thread_local static boost::log::sources::severity_logger<log_level> lg;#define BOOST_LOG_Q_SIZE 1000//创建输出槽:synchronous_sink是同步前端,允许多个线程同时写日志,后端无需考虑多线程问题
typedef sinks::asynchronous_sink<sinks::text_file_backend, sinks::bounded_fifo_queue<BOOST_LOG_Q_SIZE, sinks::block_on_overflow>> sink_t;
static std::ostream &operator<<(std::ostream &strm, log_level level)
{static const char *strings[] ={"debug","info","warn","error","critical"};if (static_cast<std::size_t>(level) < sizeof(strings) / sizeof(*strings))strm << strings[level];elsestrm << static_cast<int>(level);return strm;
}
class boost_logger : public logger_iface
{
public:boost_logger(const std::string& dir) : m_level(log_level::error_level), dir(dir){}~boost_logger(){}/*** 日志初始化*/void init() override{//判断日志文件所在路径是否存在if (boost::filesystem::exists(dir) == false){boost::filesystem::create_directories(dir);}//添加公共属性logging::add_common_attributes();//获取日志库核心core = logging::core::get();//创建后端,并设值日志文件相关控制属性boost::shared_ptr<sinks::text_file_backend> backend = boost::make_shared<sinks::text_file_backend>(keywords::open_mode = std::ios::app, // 采用追加模式keywords::file_name = dir + "/%Y%m%d_%N.log", //归档日志文件名keywords::rotation_size = 10 * 1024 * 1024, //超过此大小自动建立新文件keywords::time_based_rotation = sinks::file::rotation_at_time_point(0, 0, 0), //每隔指定时间重建新文件keywords::min_free_space = 100 * 1024 * 1024  //最低磁盘空间限制);if (!_sink){_sink.reset(new sink_t(backend));//向日志源添加槽core->add_sink(_sink);}//添加线程ID公共属性core->add_global_attribute("ThreadID", attrs::current_thread_id());//添加进程公共属性core->add_global_attribute("Process", attrs::current_process_name());//设置过滤器_sink->set_filter(expr::attr<log_level>("Severity") >= m_level);// 如果不写这个,它不会实时的把日志写下去,而是等待缓冲区满了,或者程序正常退出时写下// 这样做的好处是减少IO操作,提高效率_sink->locked_backend()->auto_flush(true); // 使日志实时更新//这些都可在配置文件中配置_sink->set_formatter(expr::stream<< "["<< expr::attr<std::string>("Process") << ":" << expr::attr<attrs::current_thread_id::value_type>("ThreadID") << ":"<< expr::attr<unsigned int>("LineID") << "]["<< expr::format_date_time<boost::posix_time::ptime>("TimeStamp", "%Y-%m-%d %H:%M:%S.%f") << "]["<< expr::attr<log_level>("Severity") << "] "<< expr::smessage);}/*** 停止记录日志*/void stop() override{warn_log("boost logger stopping");_sink->flush();_sink->stop();core->remove_sink(_sink);}/*** 设置日志级别*/void set_log_level(log_level level) override{m_level = level;if (_sink){_sink->set_filter(expr::attr<log_level>("Severity") >= m_level);}}log_level get_log_level() override{return m_level;}void debug_log(const std::string &msg) override{BOOST_LOG_SEV(lg, debug_level) << msg << std::endl;}void info_log(const std::string &msg) override{BOOST_LOG_SEV(lg, info_level) << blue << msg << normal << std::endl;}void warn_log(const std::string &msg) override{BOOST_LOG_SEV(lg, warn_level) << yellow << msg << normal << std::endl;}void error_log(const std::string &msg) override{BOOST_LOG_SEV(lg, error_level) << red << msg << normal << std::endl;}void critical_log(const std::string &msg) override{BOOST_LOG_SEV(lg, critical_level) << red << msg << normal << std::endl;}private:log_level m_level;boost::shared_ptr<logging::core> core;boost::shared_ptr<sink_t> _sink;//日志文件路径const std::string& dir;
};

logger.hpp

#pragma once
#define BOOST_ALL_DYN_LINK#include <string>   // std::string
#include <iostream> // std::cout
#include <fstream>
#include <sstream> // std::ostringstream
#include <memory>typedef std::basic_ostringstream<char> tostringstream;
static const char black[] = {0x1b, '[', '1', ';', '3', '0', 'm', 0};
static const char red[] = {0x1b, '[', '1', ';', '3', '1', 'm', 0};
static const char yellow[] = {0x1b, '[', '1', ';', '3', '3', 'm', 0};
static const char blue[] = {0x1b, '[', '1', ';', '3', '4', 'm', 0};
static const char normal[] = {0x1b, '[', '0', ';', '3', '9', 'm', 0};
#define ACTIVE_LOGGER_INSTANCE (*activeLogger::getLoggerAddr())
// note: this will replace the logger instace. If this is not the first time to set the logger instance.
// Please make sure to delete/free the old instance.
#define INIT_LOGGER(loggerImpPtr)              \{                                           \ACTIVE_LOGGER_INSTANCE = loggerImpPtr;    \ACTIVE_LOGGER_INSTANCE->init();           \}
#define CHECK_LOG_LEVEL(logLevel) (ACTIVE_LOGGER_INSTANCE ? ((ACTIVE_LOGGER_INSTANCE->get_log_level() <= log_level::logLevel##_level) ? true : false) : false)
#define SET_LOG_LEVEL(logLevel)                                                   \{                                                                              \if (ACTIVE_LOGGER_INSTANCE)                                                  \(ACTIVE_LOGGER_INSTANCE->set_log_level(log_level::logLevel##_level));      \}
#define DESTROY_LOGGER                      \{                                        \if (ACTIVE_LOGGER_INSTANCE)            \{                                      \ACTIVE_LOGGER_INSTANCE->stop();      \delete ACTIVE_LOGGER_INSTANCE;       \}                                      \}enum log_level
{debug_level = 0,info_level,warn_level,error_level,critical_level
};class logger_iface
{
public:logger_iface(void) = default;virtual ~logger_iface(void) = default;logger_iface(const logger_iface &) = default;logger_iface &operator=(const logger_iface &) = default;public:virtual void init() = 0;virtual void stop() = 0;virtual void set_log_level(log_level level) = 0;virtual log_level get_log_level() = 0;virtual void debug_log(const std::string &msg) = 0;virtual void info_log(const std::string &msg) = 0;virtual void warn_log(const std::string &msg) = 0;virtual void error_log(const std::string &msg) = 0;virtual void critical_log(const std::string &msg) = 0;
};class activeLogger
{
public:static logger_iface **getLoggerAddr(){static logger_iface *activeLogger;return &activeLogger;}
};#define __LOGGING_ENABLED#ifdef __LOGGING_ENABLED
#define __LOG(level, msg)                                                       \\{                                                                            \tostringstream var;                                                        \var << "[" << __FILE__ << ":" << __LINE__ << ":" << __func__ << "] \n"     \<< msg;                                                                  \if (ACTIVE_LOGGER_INSTANCE)                                                \ACTIVE_LOGGER_INSTANCE->level##_log(var.str());                          \}
#else
#define __LOG(level, msg)
#endif /* __LOGGING_ENABLED */

三、使用样例

#include "logger/boost_logger.hpp"
#include "logger/simpleLogger.hpp"void testCustomLogger() {//初始化日志对象:日志路径后期从配置文件读取const std::string logDir = "E:\\log";INIT_LOGGER(new boost_logger(logDir));//设置过滤级别(可以读取配置文件)SET_LOG_LEVEL(debug);//输出各级别日志,(void *)ACTIVE_LOGGER_INSTANCE:代表激活的日志实例(可不写)__LOG(critical, "hello logger!"<< "this is critical log" << (void *)ACTIVE_LOGGER_INSTANCE);__LOG(debug, "hello logger!!!!!!!!!!!!!!!"<< "this is debug log");
}

相关文章:

Boost之log日志使用

不讲理论&#xff0c;直接上在程序中可用代码&#xff1a; 一、引入Boost模块 开发环境&#xff1a;Visual Studio 2017 Boost库版本&#xff1a;1.68.0 安装方式&#xff1a;Nuget 安装命令&#xff1a; #只安装下面几个即可 Install-package boost -version 1.68.0 Install…...

多功能jquery图片预览放大镜插件

xZoom是一款多功能的jquery图片预览放大镜插件。它支持多种图片放大模式&#xff0c;可以和Fancy Box或Magnific Pop-up等插件结合使用&#xff0c;功能非常强大。 在线预览 下载 使用方法 在页面中引入jquery和xzoom.css以及xzoom.js文件。 <link rel"stylesheet&…...

CSS系列(39)-- Shapes详解

前端技术探索系列&#xff1a;CSS Shapes详解 ✨ 致读者&#xff1a;探索形状布局的艺术 &#x1f44b; 前端开发者们&#xff0c; 今天我们将深入探讨 CSS Shapes&#xff0c;这个强大的形状布局特性。 基础形状 &#x1f680; 圆形与椭圆 /* 基础圆形 */ .circle {widt…...

AI 神经网络在智能家居场景中的应用

在科技持续进步的当下&#xff0c;智能家居领域正经历着深刻变革&#xff0c;AI 神经网络技术的融入成为推动这一变革的关键力量&#xff0c;为家居生活带来了诸多显著变化与提升&#xff0c;本文将几种常见的AI算法应用做了一下总结&#xff0c;希望对物联网从业者有所帮助。 …...

Rocky DEM tutorial7_Conical Dryer_锥形干燥器

tutorial 7_Conical Dryer_锥形干燥器 文章目录 tutorial 7_Conical Dryer_锥形干燥器0. 目的1. 模型介绍2. 模型设置2.1设置physics2.2 导入几何2.3 设置motion2.4 Boundary边界设置2.5 设置材料2.6设置材料间相互作用2.7 创建粒子2.8 设置颗粒进口2.9 求解器设置3. 后处理Enj…...

CSS(二):美化网页元素

目录 字体样式 文本样式 列表样式 背景图片 字体样式 字体相关的 CSS 属性&#xff1a; font-family&#xff1a;设置字体font-size&#xff1a;设置字体大小font-weight&#xff1a;设置字体的粗细&#xff08;如 normal, bold, lighter 等&#xff09;color&#xff1a;…...

平方根无迹卡尔曼滤波(SR-UKF)算法,用于处理三维非线性状态估计问题

本MATLAB 代码实现了平方根无迹卡尔曼滤波&#xff08;SR-UKF&#xff09;算法&#xff0c;用于处理三维非线性状态估计问题 文章目录 运行结果代码概述代码 运行结果 三轴状态曲线对比&#xff1a; 三轴误差曲线对比&#xff1a; 误差统计特性输出&#xff08;命令行截图&…...

【论文笔记】Visual Alignment Pre-training for Sign Language Translation

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: Visual Alignment Pre-tra…...

NLP基础知识 - 向量化

NLP基础知识 - 向量化 目录 NLP基础知识 - 向量化 NLP基础知识 - 向量化目录什么是向量化&#xff1f;为什么需要向量化&#xff1f;常见的向量化方法1. 词袋模型&#xff08;Bag of Words, BoW&#xff09;2. TF-IDF&#xff08;词频-逆文档频率&#xff09;3. 词嵌入&#x…...

JAVA学习笔记_MySQL进阶

文章目录 存储引擎InnoDB引擎MyISAM引擎Memory存储引擎的选择 索引索引数据结构Btree(多路平衡查找树)BTreeHash索引为什么InnoDQB存储引擎采用Btree索引结构 索引分类思考题 索引语法索引性能分析慢查询日志show profiesexplain 索引的使用规则最左前缀法则索引失效SQL提示覆盖…...

ffmpeg: stream_loop报错 Error while filtering: Operation not permitted

问题描述 执行ffmpeg命令的时候&#xff0c;报错&#xff1a;Error while filtering: Operation not permitted 我得命令如下 ffmpeg -framerate 25 -y -i /data/workerspace/mtk/work_home/mtk_202406111543-l9CSU91H1f1b3/tmp/%08d.png -stream_loop -1 -i /data/workerspa…...

Vue.use()和Vue.component()

当很多页面用到同一个组件&#xff0c;又不想每次都在局部注册时&#xff0c;可以在main.js 中全局注册 Vue.component()一次只能注册一个组件 import CcInput from /components/cc-input.vue Vue.component(CcInput);Vue.use()一次可以注册多个组件 对于自定义的组件&#…...

javaweb 04 springmvc

0.1 在上一次的课程中&#xff0c;我们开发了springbootweb的入门程序。 基于SpringBoot的方式开发一个web应用&#xff0c;浏览器发起请求 /hello 后 &#xff0c;给浏览器返回字符串 “Hello World ~”。 其实呢&#xff0c;是我们在浏览器发起请求&#xff0c;请求了我们…...

[Visual studio] 性能探测器

最近发现VS的profile还是很好用的&#xff0c; 可以找到项目代码的瓶颈&#xff0c;比如发现CPU的每一个函数的时间占比&#xff0c;分析代码耗时分布&#xff0c;和火焰图一样的效果 如何使用 1. 打开你的项目&#xff0c;调整成release状态 2. 点击调试->性能探测器 3…...

【漫话机器学习系列】017.大O算法(Big-O Notation)

大 O 表示法&#xff08;Big-O Notation&#xff09; 大 O 表示法是一种用于描述算法复杂性的数学符号&#xff0c;主要用于衡量算法的效率&#xff0c;特别是随着输入规模增大时算法的运行时间或占用空间的增长趋势。 基本概念 时间复杂度 描述算法所需的运行时间如何随输入数…...

IntelliJ IDEA中设置激活的profile

在IntelliJ IDEA中设置激活的profile&#xff0c;可以通过以下步骤进行&#xff1a; 通过Run/Debug Configurations设置 打开Run/Debug Configurations对话框&#xff1a; 在IDEA的顶部菜单栏中&#xff0c;选择“Run”菜单&#xff0c;然后点击“Edit Configurations...”或者…...

Qt 的信号槽机制详解:之信号槽引发的 Segmentation Fault 问题拆析(上)

Qt 的信号槽机制详解&#xff1a;之因信号槽误用引发的 Segmentation Fault 问题拆析&#xff08;上&#xff09; 前言一. 信号与槽的基本概念信号&#xff08;Signal&#xff09;槽&#xff08;Slot&#xff09;连接信号与槽 二. 信号槽机制的实现原理元对象系统&#xff08;M…...

uniapp中实现APP调用本地通知栏通知、震动、本地提示音或者mp3提醒

要在uniapp中实现APP调用本地通知栏通知、震动和本地提示音或者mp3提醒&#xff0c;你可以使用uni-app提供的原生API和插件来实现。 通知栏通知&#xff1a; 你可以使用uni-app的原生API uni.showToast() 或者 uni.showModal() 来实现通知栏通知的功能。可以在需要发送通知的地…...

ADB 上传文件并使用脚本监控上传百分比

有个需求&#xff0c;需要测试 emmc的外部连续写入性能&#xff0c;使用 ADB 上传一个巨大的文件。并且在上传到一定值时进行干预。 因此但是 adb push 命令本身会 block 运行并且不返回进度&#xff0c;因此需要一个额外的监控脚本。 上传脚本&#xff1a; echo off setloc…...

【数据库】PostgreSQL(持续更新)

目录 K8S 部署基本使用高级特性 K8S 部署 # pg.yaml --- apiVersion: v1 kind: PersistentVolume metadata:name: tv-postgres-pvnamespace: locallabels:storage: tv-postgres-pv spec:accessModes:- ReadWriteOncecapacity:storage: 50Gi # 按需修改&#xff0c;需要保持与…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成

厌倦手动写WordPress文章&#xff1f;AI自动生成&#xff0c;效率提升10倍&#xff01; 支持多语言、自动配图、定时发布&#xff0c;让内容创作更轻松&#xff01; AI内容生成 → 不想每天写文章&#xff1f;AI一键生成高质量内容&#xff01;多语言支持 → 跨境电商必备&am…...

stm32wle5 lpuart DMA数据不接收

配置波特率9600时&#xff0c;需要使用外部低速晶振...

WEB3全栈开发——面试专业技能点P7前端与链上集成

一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染&#xff08;SSR&#xff09;与静态网站生成&#xff08;SSG&#xff09; 框架&#xff0c;由 Vercel 开发。它简化了构建生产级 React 应用的过程&#xff0c;并内置了很多特性&#xff1a; ✅ 文件系…...

python打卡第47天

昨天代码中注意力热图的部分顺移至今天 知识点回顾&#xff1a; 热力图 作业&#xff1a;对比不同卷积层热图可视化的结果 def visualize_attention_map(model, test_loader, device, class_names, num_samples3):"""可视化模型的注意力热力图&#xff0c;展示模…...

LUA+Reids实现库存秒杀预扣减 记录流水 以及自己的思考

目录 lua脚本 记录流水 记录流水的作用 流水什么时候删除 我们在做库存扣减的时候&#xff0c;显示基于Lua脚本和Redis实现的预扣减 这样可以在秒杀扣减的时候保证操作的原子性和高效性 lua脚本 // ... 已有代码 ...Overridepublic InventoryResponse decrease(Inventor…...

Qt学习及使用_第1部分_认识Qt---Qt开发基本流程

前言 学以致用,通过QT框架的学习,一边实践,一边探索编程的方方面面. 参考书:<Qt 6 C开发指南>(以下称"本书") 标识说明:概念用粗体倾斜.重点内容用(加粗黑体)---重点内容(红字)---重点内容(加粗红字), 本书原话内容用深蓝色标识,比较重要的内容用加粗倾…...