更多精彩内容 |
---|
个人内容分类汇总 |
C++日志框架 |
日志库在软件开发中扮演着重要的角色,有以下几个主要原因:
故障排查和调试:日志是开发人员用来追踪代码的执行路径、查找错误和故障的重要工具。通过在关键位置记录日志信息,开发人员可以在系统出现问题时,根据日志中的信息进行故障排查和调试。
性能分析和优化:通过在关键代码段记录时间戳、函数调用次数等信息,可以使用日志来分析系统的性能瓶颈并进行优化。通过分析日志,开发人员可以找到执行时间较长的代码片段,进而进行针对性的优化。
跟踪用户行为和数据分析:日志记录可以捕捉用户的行为,例如用户操作的步骤、请求的参数、返回的结果等。这些信息对于分析用户行为和进行数据分析非常有用。日志记录还可以用于监测系统的使用情况,识别热门功能和潜在的问题。
安全和合规性:日志可以帮助开发人员检测潜在的安全漏洞和异常操作。通过记录关键操作的日志,可以追踪到系统中可能存在的安全问题,并及时采取相应的措施。
系统监控和运维:通过记录系统状态、异常事件和警报信息,日志可以帮助运维人员实时监控系统的运行情况。在系统遇到故障或问题时,运维人员可以通过分析日志来快速定位问题和采取相应的措施。
使用通用日志框架有以下几个主要原因:
- 统一日志输出格式:通用日志框架可以帮助开发人员规范化日志输出的格式。它定义了一套通用的日志级别(如调试、信息、警告、错误等)和日志标准格式,使得不同的开发人员在不同的模块或组件中产生的日志信息能够保持一致。这样做有助于日志的可读性和可维护性。
- 灵活的日志输出配置:通用日志框架通常提供了灵活的日志输出配置选项。通过配置,开发人员可以选择将日志输出到不同的目标,如控制台、文件、数据库、远程服务器等。还可以配置日志的级别和详细程度,以便在不同环境下灵活地控制日志的输出量。这对于开发、测试和生产环境下的日志管理都是非常有用的。
- 多线程和并发支持:现代软件系统通常是多线程和并发的,使用通用日志框架可以确保在多线程环境下日志的正确输出。通用日志框架通常提供了线程安全的日志输出机制,可以处理多个线程同时写入日志的情况,保证日志的完整性和顺序性。
- 日志过滤和搜索功能:通用日志框架通常还提供了日志过滤和搜索功能,使得开发人员能够根据特定的条件和关键字快速定位和查找日志。这对于快速定位问题和故障排除非常重要。开发人员可以根据时间、日志级别、关键字等进行过滤,以便更好地分析和理解日志信息。
- 第三方集成和生态系统支持:通用日志框架通常会有一个庞大的用户社区和广泛的第三方工具支持。这意味着开发人员可以通过使用通用日志框架,轻松集成其他工具和系统。例如,可以将日志与监控系统、报警系统、日志分析工具等集成,实现自动化的日志处理和分析。
spdlog是一个开源的C++日志库,它提供了高性能和易用性的日志记录功能。它是为了满足现代C++应用程序的需要而创建的,可以在不同的平台上运行。
以下是spdlog的主要特点和功能:
- 高性能:spdlog使用了各种技术来提升性能,包括异步日志记录、缓冲区和多线程支持。这使得spdlog在高负载情况下仍然能够提供出色的性能。
- 易于使用:spdlog提供了简单直观的API,使得日志记录变得非常容易。您可以使用各种方式输出日志,比如控制台、文件、内存缓冲区等。
- 多种日志级别:spdlog支持多种日志级别,包括调试、信息、警告、错误等级别。这使得您可以根据需要对日志进行分类和过滤。
- 多种输出格式:spdlog允许您自定义日志的输出格式。您可以设置日期和时间格式,选择是否显示日志级别,还可以添加自定义文本或标记。
- 多线程安全:spdlog设计为多线程安全的,因此不同线程可以同时进行日志记录,而不会导致竞态条件或数据损坏。
- 跨平台支持:spdlog可以在不同的操作系统上运行,包括Windows、Linux、Mac OS、Android。这使得您可以在不同的开发环境中使用spdlog。
- 各种日志输出方式:按文件大小、按每日输出一个文件、输出到控制台、输出到文件、显示到Qt控件等。
源码
教程
环境
将源码下载到本地
git clone https://github.com/gabime/spdlog.git
创建一个文件夹build,用于存放编译过程中生产的文件,防止过程文件与源码混在一起;
创建一个spdlog文件用于存放编译后的文件,不使用默认安装路径;
打开Cmake,将CMakeLists.txt文件拖入Cmake界面中,并点击【Browse Build】选择构建生成文件夹;
点击【Configrue】,选择需要使用的编译器Visual Studio 15 2017、x64,然后点击【Finish】;
找到【CMAKE_INSTALL_PREFIX】,这是设置编译后的库文件的安装路径,默认是在C盘,需要管理员权限才可以编译,这里我修改为了自己创建的spdlog路径;
修改完成后再点击【Configure】,【Generate】,【Open Project】,就会自动使用Visual Studio打开工程;
选择【Debug】模式,右键选择【ALL_BUILD】,点击【生成】;
然后右键选择【INSTALL】,点击【生成】;
生成完成后再选择【Release】模式,右键选择【ALL_BUILD】,点击【生成】;
然后右键选择【INSTALL】,点击【生成】;
最后打开最开始创建的spdlog文件夹,编译后的库文件如下所示;
创建一个Qt工程;
将spdlog编译后的文件夹复制到Qt工程下;
在pro文件中使用下列代码引入spdlog库和头文件;
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/spdlog/lib/ -lspdlog
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/spdlog/lib/ -lspdlogd
INCLUDEPATH += $$PWD/spdlog/include
DEPENDPATH += $$PWD/spdlog/include
#include "spdlog/spdlog.h"
int main()
{
//Use the default logger (stdout, multi-threaded, colored)
spdlog::info("Hello, {}!", "World");
}
在UI中添加一个QTextEdit和一个QPushButton;
在Widget.cpp中添加下列代码;
#include "widget.h"
#include "ui_widget.h"
#include "spdlog/spdlog.h"
#include "spdlog/sinks/qt_sinks.h"
#include "spdlog/sinks/basic_file_sink.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
auto log_edit = std::make_shared<spdlog::sinks::qt_color_sink_mt>(ui->textEdit, 100); // 将日志显示到QTextEdit,最大显示100行日志
auto log_file = std::make_shared<spdlog::sinks::basic_file_sink_mt>("logs/basic-log.log"); // 将日志输出到logs文件夹下的basic-log.log文件中
std::vector<spdlog::sink_ptr> sinks {log_edit, log_file};
auto combined_logger = std::make_shared<spdlog::logger>("log_out", sinks.begin(), sinks.end()); // 创建日志记录器,参数1为自定义的名称
spdlog::register_logger(combined_logger); // 注册全局日志记录器,在其他地方可用通过名称【log_out】访问同一个日志记录器
spdlog::flush_every(std::chrono::seconds(3)); // 日志输出到文件默认是放到缓冲,不会立即写入文件,这里设置每隔3秒刷新一次缓冲,写入文件
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
auto log = spdlog::get("log_out");
log->trace("trace信息");
log->debug("debug信息");
log->info("info信息");
log->warn("warn信息");
log->error("error信息");
log->critical("critical信息");
}
编译后点击but,日志输出结果如下所示,同时输出到QTextEdit和文件中;
从输出结果可用发现spdlog存在两个bug;