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

网站开发可以入无形资产吗衡阳网站建设公司哪家好

网站开发可以入无形资产吗,衡阳网站建设公司哪家好,扬州整站seo,WordPress博客设置最新文章介绍 spdlog 是一个高性能、超快速、零配置的 C 日志库,它旨在提供简洁的 API 和丰富的功能,同时保持高性能的日志记录。它支持多种输出目标、格式化选项、线程安 全以及异步日志记录。以下是对 spdlog 的详细介绍和使用方法。 github 链接&#x…

介绍

spdlog 是一个高性能、超快速、零配置的 C++ 日志库,它旨在提供简洁的 API 和丰富的功能,同时保持高性能的日志记录。它支持多种输出目标、格式化选项、线程安 全以及异步日志记录。以下是对 spdlog 的详细介绍和使用方法。
github 链接: https://github.com/gabime/spdlog
特点
  • 高性能spdlog 专为速度而设计,即使在高负载情况下也能保持良好的性能。
  • 零配置:无需复杂的配置,只需包含头文件即可在项目中使用。
  • 异步日志:支持异步日志记录,减少对主线程的影响。
  • 格式化:支持自定义日志消息的格式化,包括时间戳、线程 ID、日志级别等。
  • 多平台:跨平台兼容,支持 WindowsLinuxmacOS 等操作系统。
  • 丰富的 API:提供丰富的日志级别和操作符重载,方便记录各种类型的日志。

安装

在Ubuntu系统下可以使用以下命令进行安装

sudo apt-get install libspdlog-dev

安装好后,就会在 /usr/include 目录下生成 spdlog 文件夹,在该文件夹下就包含了 spdlog.h 头文件。

同时可以通过以下命令查看 gtest 动态库的位置。

whereis libspdlog.so

使用

包含头文件

C++ 源文件中包含 spdlog 的头文件:
#include <spdlog/spdlog.h>

日志输出等级枚举

namespace level {enum level_enum : int {trace = SPDLOG_LEVEL_TRACE,debug = SPDLOG_LEVEL_DEBUG,info = SPDLOG_LEVEL_INFO,warn = SPDLOG_LEVEL_WARN,err = SPDLOG_LEVEL_ERROR,critical = SPDLOG_LEVEL_CRITICAL,off = SPDLOG_LEVEL_OFF,n_levels};
}

日志输出格式自定义

可以自定义日志消息的格式:
logger->set_pattern("%Y-%m-%d %H:%M:%S [%t] [%-7l] %v");
  • %Y - 年(Year)。
  • %m - 月(Month)。
  • %d - 日(Day)。
  • %H - 小时(24-hour format)。
  • %M - 分钟(Minute)。
  • %S - 秒(Second)。
  • %t - 线程 IDThread ID)。
  • %n - 日志器名称(Logger name)。
  • %l - 日志级别名称(Level name),如 INFO, DEBUG, ERROR 等。
  • %v - 日志内容(message)。

日志记录器类

创建一个基本的日志记录器,并设置日志级别和输出模式:
namespace spdlog
{class logger{logger(std::string name);logger(std::string name, sink_ptr single_sink);logger(std::string name, sinks_init_list sinks);void set_level(level::level_enum log_level);void set_formatter(std::unique_ptr<formatter> f);template <typename... Args>void trace(fmt::format_string<Args...> fmt, Args &&...args);template <typename... Args>void debug(fmt::format_string<Args...> fmt, Args &&...args);template <typename... Args>void info(fmt::format_string<Args...> fmt, Args &&...args);template <typename... Args>void warn(fmt::format_string<Args...> fmt, Args &&...args);template <typename... Args>void error(fmt::format_string<Args...> fmt, Args &&...args);template <typename... Args>void critical(fmt::format_string<Args...> fmt, Args &&...args);void flush(); // 刷新日志// 策略刷新--触发指定等级日志的时候立即刷新日志的输出void flush_on(level::level_enum log_level);};
}

异步日志记录类

为了异步记录日志,可以使用 spdlog::async_logger
class async_logger final : public spdlog::logger
{async_logger(std::string logger_name, spdlog::sinks_init_list sinks_list,std::weak_ptr<spdlog::details::thread_pool> tp,async_overflow_policy overflow_policy = async_overflow_policy::block);async_logger(std::string logger_name, spdlog::sink_ptr single_sink,std::weak_ptr<spdlog::details::thread_pool> tp,async_overflow_policy overflow_policy = async_overflow_policy::block);// 异步日志输出需要异步工作线程的支持,这里是线程池类class SPDLOG_API thread_pool{thread_pool(size_t q_max_items, size_t threads_n,std::function<void()> on_thread_start,std::function<void()> on_thread_stop);thread_pool(size_t q_max_items, size_t threads_n,std::function<void()> on_thread_start);thread_pool(size_t q_max_items, size_t threads_n);};
};
std::shared_ptr<spdlog::details::thread_pool> thread_pool()
{return spdlog::details::registry::instance().get_tp();
}
// 默认线程池的初始化接口
inline void init_thread_pool(size_t q_size, size_t thread_count);
auto async_logger = spdlog::async_logger_mt("async_logger","logs/async_log.txt");
async_logger->info("This is an asynchronous info message");

日志记录器工厂类

using async_factory = async_factory_impl<async_overflow_policy::block>;
template <typename Sink, typename... SinkArgs>
inline std::shared_ptr<spdlog::logger> create_async(std::string logger_name, SinkArgs &&...sink_args);// 创建一个彩色输出到标准输出的日志记录器,默认工厂创建同步日志记录器
template <typename Factory = spdlog::synchronous_factory>
std::shared_ptr<logger> stdout_color_mt(const std::string &logger_name, color_mode mode = color_mode::automatic);// 标准错误
template <typename Factory = spdlog::synchronous_factory>
std::shared_ptr<logger> stderr_color_mt(const std::string &logger_name, color_mode mode = color_mode::automatic);// 指定文件
template <typename Factory = spdlog::synchronous_factory>
std::shared_ptr<logger> basic_logger_mt(const std::string &logger_name, const filename_t &filename,bool truncate = false, const file_event_handlers &event_handlers = {});
// 循环文件
template <typename Factory = spdlog::synchronous_factory>
std::shared_ptr<logger> rotating_logger_mt(const std::string &logger_name, const filename_t &filename,size_t max_file_size, size_t max_files, bool rotate_on_open = false);

日志落地类

namespace spdlog
{namespace sinks{class SPDLOG_API sink{public:virtual ~sink() = default;virtual void log(const details::log_msg &msg) = 0;virtual void flush() = 0;virtual void set_pattern(const std::string &pattern) = 0;virtual void set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter) = 0;void set_level(level::level_enum log_level);};using stderr_color_sink_mt;using stderr_sink_mt;// 滚动日志文件-超过一定大小则自动重新创建新的日志文件sink_ptr rotating_file_sink(filename_t base_filename, std::size_t max_size, std::size_t max_files,bool rotate_on_open = false, const file_event_handlers &event_handlers = {});using rotating_file_sink_mt = rotating_file_sink<std::mutex>;// 普通的文件落地sink_ptr basic_file_sink(const filename_t &filename, bool truncate = false,const file_event_handlers &event_handlers = {});using basic_file_sink_mt = basic_file_sink<std::mutex>;using kafka_sink_mt = kafka_sink<std::mutex>;using mongo_sink_mt = mongo_sink<std::mutex>;using tcp_sink_mt = tcp_sink<std::mutex>;using udp_sink_mt = udp_sink<std::mutex>;//*_st:单线程版本,不用加锁,效率更高。//*_mt:多线程版本,用于多线程程序是线程安全的。}
}

全局接口

// 输出等级设置接口
void set_level(level::level_enum log_level);
// 日志刷新策略-每隔 N 秒刷新一次
void flush_every(std::chrono::seconds interval);
// 日志刷新策略-触发指定等级立即刷新
void flush_on(level::level_enum log_level);

记录日志

使用日志记录器记录不同级别的日志:
logger->trace("This is a trace message");
logger->debug("This is a debug message");
logger->info("This is an info message");
logger->warn("This is a warning message");
logger->error("This is an error message");
logger->critical("This is a critical message");

使用样例

sync.cc

#include <iostream>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/sinks/basic_file_sink.h>int main()
{// 设置全局的刷新策略,每秒刷新一次spdlog::flush_every(std::chrono::seconds(1));// 设置日志的刷新等级,当遇到debug等级以上的日志立马刷新到磁盘spdlog::flush_on(spdlog::level::level_enum::debug);// 创建同步日志器(标准输出/文件输出),工厂接口默认的就是同步日志器auto logger = spdlog::stdout_color_mt("stdout_logger");//auto logger =spdlog::basic_logger_mt("file_logger","log.txt");// 可以单独设置日志器的刷新策略和输出等级logger->flush_on(spdlog::level::level_enum::debug);logger->set_level(spdlog::level::level_enum::debug);// 设置日志器的输出格式logger->set_pattern("[%n][%H:%M:%S][%t][%-8l]%v");// 进行简单的日志输出logger->trace("hello {}", "world");logger->debug("hello {}", 12345);logger->info("hello {}", "spdlog");logger->warn("hello {}", "spdlog");logger->error("hello {}", "spdlog");logger->critical("hello {}", "spdlog");return 0;
}

async.cc

#include <iostream>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/sinks/basic_file_sink.h>
#include <spdlog/async.h>int main()
{// 设置全局的刷新策略,每秒刷新一次spdlog::flush_every(std::chrono::seconds(1));// 设置日志的刷新等级,当遇到debug等级以上的日志立马刷新到磁盘spdlog::flush_on(spdlog::level::level_enum::debug);// 初始化异步日志输出的线程配置spdlog::init_thread_pool(1000, 3);// 创建同步日志器(标准输出/文件输出),工厂接口默认的就是同步日志器auto logger = spdlog::stdout_color_mt<spdlog::async_factory>("stdout_logger");// auto logger =spdlog::basic_logger_mt<spdlog::async_factory>("file_logger","log.txt");// 可以单独设置日志器的刷新策略和输出等级logger->flush_on(spdlog::level::level_enum::debug);logger->set_level(spdlog::level::level_enum::debug);// 设置日志器的输出格式logger->set_pattern("[%n][%H:%M:%S][%t][%-8l]%v");// 进行简单的日志输出logger->trace("hello {}", "world");logger->debug("hello {}", 12345);logger->info("hello {}", "spdlog");logger->warn("hello {}", "spdlog");logger->error("hello {}", "spdlog");logger->critical("hello {}", "spdlog");std::cout << "日志输出演示完毕!!" << std::endl;return 0;
}

makefile

.PHONY:all
all:sync async
sync:sync.ccg++ -o $@ $^ -std=c++17 -lspdlog -lfmt
async:async.ccg++ -o $@ $^ -std=c++17 -lspdlog -lfmt.PHONY:clean
clean:rm -f sync async

二次封装

logger.hpp

#include <iostream>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/sinks/basic_file_sink.h>
#include <spdlog/async.h>std::shared_ptr<spdlog::logger> g_default_logger;
//mode:运行模式,true为发布模式,false为调试模式
void init_logger(bool mode,const std::string& file,int32_t level)
{if(mode==false){//调试模式,创建标准输出日志器,输出等级为最低g_default_logger=spdlog::stdout_color_mt("default_logger");g_default_logger->set_level(spdlog::level::level_enum::trace);g_default_logger->flush_on(spdlog::level::level_enum::trace);}else{//发布模式,创建文件输出日志器g_default_logger=spdlog::basic_logger_mt("default_logger",file);g_default_logger->set_level((spdlog::level::level_enum)level);g_default_logger->flush_on((spdlog::level::level_enum)level);}g_default_logger->set_pattern("[%n][%H:%M:%S][%t][%-8l]%v");
}#define LOG_TRACE(format,...) { g_default_logger->trace(std::string("[{}:{}]")+format,__FILE__,__LINE__,##__VA_ARGS__); }
#define LOG_DEBUG(format,...) { g_default_logger->debug(std::string("[{}:{}]")+format,__FILE__,__LINE__,##__VA_ARGS__); }
#define LOG_INFO(format,...) { g_default_logger->info(std::string("[{}:{}]")+format,__FILE__,__LINE__,##__VA_ARGS__); }
#define LOG_WARN(format,...) { g_default_logger->warn(std::string("[{}:{}]")+format,__FILE__,__LINE__,##__VA_ARGS__); }
#define LOG_ERROR(format,...) { g_default_logger->error(std::string("[{}:{}]")+format,__FILE__,__LINE__,##__VA_ARGS__); }
#define LOG_CRITICAL(format,...) { g_default_logger->critical(std::string("[{}:{}]")+format,__FILE__,__LINE__,##__VA_ARGS__); }


文章转载自:

http://oVqlDiEc.prznc.cn
http://j0C2h87r.prznc.cn
http://o1DfqzZ6.prznc.cn
http://iBulriWp.prznc.cn
http://CSB5HUat.prznc.cn
http://v9MjXaNG.prznc.cn
http://aczKksPN.prznc.cn
http://tI2KHSZl.prznc.cn
http://UVyQQFVC.prznc.cn
http://by8m3l9I.prznc.cn
http://CdRuSpCo.prznc.cn
http://5CSauWws.prznc.cn
http://AEVxUPFv.prznc.cn
http://2lsPNiIp.prznc.cn
http://GMHQrhJp.prznc.cn
http://3OKY8eAb.prznc.cn
http://qs68uhSV.prznc.cn
http://B3sNyPIl.prznc.cn
http://M1uzxiuV.prznc.cn
http://hIt8vG8a.prznc.cn
http://PyeD8SJc.prznc.cn
http://HGdTozrG.prznc.cn
http://51pZzePP.prznc.cn
http://747GxkZa.prznc.cn
http://NnDch8Dn.prznc.cn
http://N3f0sC1U.prznc.cn
http://jXLL5oy8.prznc.cn
http://GRbIM0tL.prznc.cn
http://9DykGF7i.prznc.cn
http://yeTBJFEt.prznc.cn
http://www.dtcms.com/wzjs/626113.html

相关文章:

  • 江海区建设局网站做移动端网站设计
  • 纯flash网站欣赏北京菜谱设计制作
  • 百度网站流量统计shopex 如何看 网站后台
  • 洛阳便宜网站建设价格网页设计产品介绍
  • 大连网站建设工作室网页游戏代理加盟
  • 写文案要看的网站定制化开发
  • 网站建设服务合同书标准版微信做单网站有哪些
  • 网站建设及网络推广设立公司流程以及需要的资料
  • 优化关键词可以选择哪个工具seo sem培训
  • 优秀网站介绍wordpress get_row
  • 国内网站空间购买相城区公司网站建设
  • 织梦网站修改教程视频教程江苏seo百度推广
  • 桓台网站设计做招聘求职网站
  • 网站投票系统怎么做一个人看的视频在线观看动漫
  • 国内设计师个人网站建筑公司大全
  • 网站建设需要购买什么黄埔建网站公司
  • 建设一个网站需要什么技术人员评论优化
  • wap网站什么意思WordPress自己写主题
  • 开发公司组织机构图外汇网站怎么做优化
  • 公司门户网站的意义宝安电子厂做高端网站
  • 中山网站制作套餐如何进行网页设计和网站制作
  • 网站首页关键词优化织梦网站模板更换
  • 男人和女人做不可描述的事情的网站百色高端网站建设
  • 网站备案初审加强学校网站建设的要求
  • 营销型网站具备的二大能力可以做直播卖产品的网站
  • 各大网站网址白塔网站建设
  • 嘉峪关建设路小学网站word 添加 wordpress
  • 怎么做网站 ppt学校网站设计方案模板
  • 审计实务网站建设论文网站建设是什么语言
  • 网站设计两边为什么要留白做外贸仿牌网站