spdlog日志库源码:自定义异常类spdlog_ex
自定义异常类spdlog_ex
标准库异常类(std::exception)系列,能满足大多数使用异常的场景,但对系统调用异常及错误信息缺乏支持。spdlog通过继承std::exception,扩展对系统调用的支持,实现自定义异常类spdlog_ex。
spdlog_ex类声明只是在std::exception基础上添加了string类型的msg_成员,提供支持errno的构造函数。
// include/spdlog/common.h
class SPDLOG_API spdlog_ex : public std::exception {
public:explicit spdlog_ex(std::string msg);spdlog_ex(const std::string &msg, int last_errno);const char *what() const SPDLOG_NOEXCEPT override;private:std::string msg_;
};
异常
SPDLOG_INLINE spdlog_ex::spdlog_ex(std::string msg): msg_(std::move(msg)) {}SPDLOG_INLINE spdlog_ex::spdlog_ex(const std::string &msg, int last_errno) {
#ifdef SPDLOG_USE_STD_FORMATmsg_ = std::system_error(std::error_code(last_errno, std::generic_category()), msg).what();
#elsememory_buf_t outbuf;fmt::format_system_error(outbuf, last_errno, msg.c_str());msg_ = fmt::to_string(outbuf);
#endif
对于通用的异常,spdlog_ex只是将用户传入的异常提示信息存放到msg_。
spdlog_ex对errno的支持,主要是将errno转换为对应错误文本信息,存放到msg_字符串中。spdlog使用的是ftm库提供的format_system_error来完成转换工作。
what()函数
SPDLOG_INLINE const char *spdlog_ex::what() const SPDLOG_NOEXCEPT {return msg_.c_str();
}
what()是基类std::exception定义的virtual函数,用户通常通过该接口获取异常信息。spdlog_ex返回存放异常信息的msg_。
异常的使用
spdlog提供了重载函数形式的接口:throw_spdlog_ex。
SPDLOG_INLINE void throw_spdlog_ex(const std::string &msg, int last_errno) {SPDLOG_THROW(spdlog_ex(msg, last_errno));
}SPDLOG_INLINE void throw_spdlog_ex(std::string msg) { SPDLOG_THROW(spdlog_ex(std::move(msg)));
}
抛出异常可以是这样:
// send flush request to the thread pool
SPDLOG_INLINE void spdlog::async_logger::flush_(){SPDLOG_TRY{auto pool_ptr = thread_pool_.lock();if (!pool_ptr) {throw_spdlog_ex("async flush: thread pool doesn't exist anymore");}std::future<void> future = pool_ptr->post_flush(shared_from_this(), overflow_policy_);future.get();}SPDLOG_LOGGER_CATCH(source_loc())
}
throw_spdlog_ex本质上也是throw spdlog_ex(…),这里多了宏定义SPDLOG_THROW。
#ifdef SPDLOG_NO_EXCEPTIONS#define SPDLOG_TRY#define SPDLOG_THROW(ex) \do { \printf("spdlog fatal error: %s\n", ex.what()); \std::abort(); \} while (0)#define SPDLOG_CATCH_STD
#else#define SPDLOG_TRY try#define SPDLOG_THROW(ex) throw(ex)#define SPDLOG_CATCH_STD \catch (const std::exception &) { \}
#endif
实际上是提供了两种模式。抛出异常,不抛出异常。
- 当没有定义宏SPDLOG_NO_EXCEPTIONS时,正常抛出异常对象;
- 当定义了宏SPDLOG_NO_EXCEPTIONS时,抛出异常替换为直接终止程序(abort)
因此,在spdlog中,捕获异常的代码块try-catch,看起来会是这样:
SPDLOG_INLINE thread_pool::~thread_pool()
{// 析构函数不要抛出异常, 但释放线程池资源资源可能发生异常, 因此内部捕获并处理SPDLOG_TRY{for (size_t i = 0; i < threads_.size(); i++) {// 有几个子线程,就要post几个terminate的async_msg。post_async_msg_(async_msg(async_msg_type::terminate), async_overflow_policy::block);}for (auto & t : threads_) {t.join();}}SPDLOG_CATCH_STD
}
可以使用自定义捕获(catch)代码块,替换SPDLOG_CATCH_STD。
SPDLOG_INLINE void spdlog::async_logger::backend_flush_()
{for (auto &sink : sinks_){SPDLOG_TRY{sink->flush();}SPDLOG_LOGGER_CATCH(source_loc())}
}
#ifndef SPDLOG_NO_EXCEPTIONS#define SPDLOG_LOGGER_CATCH(location) \catch (const std::exception &ex) { \if (location.filename) { \err_handler_(fmt_lib::format(SPDLOG_FMT_STRING("{} [{}({})]"), ex.what(), \location.filename, location.line)); \} else { \err_handler_(ex.what()); \} \} \catch (...) { \err_handler_("Rethrowing unknown exception in logger"); \throw; \}
#else#define SPDLOG_LOGGER_CATCH(location)
#endif
catch (const std::exception &ex):捕获所有从 std::exception 派生的异常。
if (location.filename):如果提供了源代码位置信息(文件名),则格式化错误消息,包括异常的 what() 信息和源代码位置。
err_handler_:这是一个错误处理函数或对象,用于处理和记录错误消息。
catch (…):捕获所有其他类型的异常。
err_handler_(“Rethrowing unknown exception in logger”):记录一个未知异常的错误消息。
throw:重新抛出捕获的异常。
如果禁用了异常处理(通过定义 SPDLOG_NO_EXCEPTIONS),这个宏展开为空。
相关文章:
spdlog日志库源码:自定义异常类spdlog_ex
自定义异常类spdlog_ex 标准库异常类(std::exception)系列,能满足大多数使用异常的场景,但对系统调用异常及错误信息缺乏支持。spdlog通过继承std::exception,扩展对系统调用的支持,实现自定义异常类spdlo…...
3.每日LeetCode-数组类,爬楼梯(Go,Java,Python)
目录 题目 解法 Go Java Python 代码地址:leetcode: 每日leetcode刷题 题目 题号70. 爬楼梯 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 示例 1: 输入ÿ…...
单节点11.2.0.3参数文件恢复到RAC11.2.0.4启动失败
问题描述 通过pfile生成spfile失败,提示DATA磁盘不存在 SQL> create spfileDATA/DXJ/spfiledxj.ora from pfile/home/oracle/initdxj20240529.ora; create spfileDATA/DXJ/spfiledxj.ora from pfile/home/oracle/initdxj20240529.ora * ERROR at line 1: ORA-1…...

Windows电脑高颜值桌面便利贴,便签怎么设置
在这个看颜值的时代,我们不仅在衣着打扮上追求时尚与美观,就连电脑桌面也不愿放过。一张唯美的壁纸,几款别致的小工具,总能让我们的工作空间焕发出不一样的光彩。如果你也热衷于打造高颜值的电脑桌面,那么,…...
代码随想录35期Day54-Java
Day54题目 LeetCode392判断子序列 核心思想:公共子序列长度达到需要判断的字符串的长度,说明是子序列 class Solution {public boolean isSubsequence(String s, String t) {if("".equals(s)) return true;int[][] dp new int[s.length()1][t.length()1];for(int…...
Ubuntu使用sudo命令
在Ubuntu系统中,使用管理员权限通常涉及到使用sudo命令。这是因为Ubuntu默认情况下不直接允许root用户登录,而是通过sudo命令来执行需要管理员权限的任务。以下是一些常见的使用管理员权限的方法: 1. 使用sudo命令 运行单个命令 如果只需要…...

三方语言中调用, Go Energy GUI编译的dll动态链接库CEF
如何在其它编程语言中调用energy编译的dll动态链接库,以使用CEF 或 LCL库 Energy是Go语言基于LCL CEF开发的跨平台GUI框架, 具有很容易使用CEF 和 LCL控件库 interface 便利 示例链接 正文 为方便起见使用 python 调用 go energy 编译的dll 准备 系统&#x…...

Go微服务: Grpc服务注册在Consul的示例(非Go-Micro)
概述 现在,我们使用consul客户端的api来把GRPC服务实现注册到consul上,非Go-Micro的形式其实,consul官方提供了对应的接口调用来实现,golang中的consul/api包对其进行了封装我们使用consul/api来进行展示 目录结构 gitee.com/g…...

Java+Swing+Mysql实现飞机订票系统
一、系统介绍 1.开发环境 操作系统:Win10 开发工具 :Eclipse2021 JDK版本:jdk1.8 数据库:Mysql8.0 2.技术选型 JavaSwingMysql 3.功能模块 4.数据库设计 1.用户表(users) 字段名称 类型 记录内容…...
2024 rk
1.mysql、redis分布式锁 case: 商品秒杀 1)使用 MySQL 作为分布式锁来实现商品秒杀功能可能存在以下几个缺点; 使用 MySQL 作为分布式锁来实现商品秒杀功能可能存在以下几个缺点: 单点故障:如果使用单个 MySQL 实例作为分布式锁的存储介质…...
Java实现多张图片合并保存到pdf中
Java实现多张图片合并保存到pdf中 1、依赖–maven <dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.24</version></dependency>2、上代码 package com.hxlinks.hxiot.contro…...

揭秘智慧校园:可视化技术引领教育新篇章
随着科技的飞速发展,我们的生活方式正在经历一场前所未有的变革。而在这场变革中,学校作为培养未来人才的重要基地,也在不断地探索与创新。 一、什么是校园可视化? 校园可视化,就是通过先进的信息技术,将学…...

基础9 探索图形化编程的奥秘:从物联网到工业自动化
办公室内,明媚的阳光透过窗户洒落,为每张办公桌披上了一层金色的光辉。同事们各自忙碌着,键盘敲击声、文件翻页声和低声讨论交织在一起,营造出一种忙碌而有序的氛围。空气中氤氲着淡淡的咖啡香气和纸张的清新味道,令人…...
RPC-----RCF
RPC RPC(Remote Procedure Call Protocol)——远程过程调用协议。 RCF...
StarRocks中,这些配置项是表属性的一部分
CREATE TABLE warehouse.ads_order_all_df ( so_id varchar(200) NULL COMMENT "销售订单主表标识", so_code varchar(200) NULL COMMENT "销售订单主表表号" ) ENGINEOLAP DUPLICATE KEY(so_id) COMMENT "OLAP" DISTRIBUTED BY HASH(dt) …...
Activity->Activity生命周期
<四大组件 android:name"xxx"android:exported"true" // 该组边能够被其他组件启动android:enabled"true" // 该组件能工与用户交互 </四大组件>Activity常用生命周期 启动Activity 2024-05-29 03:53:57.401 21372-21372 yang …...

乐鑫ESP串口驱动安装,安装cp210x驱动
windows11安装cp210x驱动: 1:第一步官网下载驱动: 官网地址如下: CP210x USB to UART Bridge VCP Drivers - Silicon Labs 第二步:解压文件夹并安装如图所示: 3:第三步安装成功后会给你个提示…...

Django缓存
由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcache中,若某个时…...
Python 元组
(1)元组中只包含一个元素时,需要在元素后面添加逗号: tup1 (50,); (2)元组中的元素值是不允许修改的,但我们可以对元组进行连接组合: tup1 (12, 34.56); tup2 (abc, xyz);# 以…...

JAVA面试题大全(十八)
1、说一下 jvm 的主要组成部分?及其作用? 类加载器(ClassLoader)运行时数据区(Runtime Data Area)执行引擎(Execution Engine)本地库接口(Native Interface)…...

关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...

selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...

claude3.7高阶玩法,生成系统架构图,国内直接使用
文章目录 零、前言一、操作指南操作指导 二、提示词模板三、实战图书管理系统通过4o模型生成系统描述通过claude3.7生成系统架构图svg代码转换成图片 在线考试系统通过4o模型生成系统描述通过claude3.7生成系统架构图svg代码转换成图片 四、感受 零、前言 现在很多AI大模型可以…...
Three.js进阶之粒子系统(一)
一些特定模糊现象,经常使用粒子系统模拟,如火焰、爆炸等。Three.js提供了多种粒子系统,下面介绍粒子系统 一、Sprite粒子系统 使用场景:下雨、下雪、烟花 ce使用代码: var materialnew THRESS.SpriteMaterial();//…...

奈飞工厂官网,国内Netflix影视在线看|中文网页电脑版入口
奈飞工厂是一个专注于提供免费Netflix影视资源的在线播放平台,致力于为国内用户提供的Netflix热门影视内容。该平台的资源与Netflix官网基本同步,涵盖电影、电视剧、动漫和综艺等多个领域。奈飞工厂的界面简洁流畅,资源分类清晰,方…...
用 DeepSeek 高效完成数据分析与挖掘
一、DeepSeek 是什么? DeepSeek 是由深度求索推出的智能助手(当前版本 DeepSeek-R1),具备强大的自然语言理解、代码生成与数据分析能力。它支持 128K超长上下文,可处理复杂数据文档,并直接生成可运行的 Python 数据分析代码,是数据工作者的“AI副驾驶”。 二、DeepSeek…...