C++ 日志记录:初学者最佳实践

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

C++ 应用程序中的日志记录:面向初学者的最佳实践



日志记录是记录程序运行期间发生的事件的过程。对于初学 C++ 的开发者来说,掌握正确组织日志记录的技能不仅是“良好礼仪”,更是一项至关重要的技能。它有助于调试代码、追踪生产环境中的错误以及分析系统行为。在本文中,我们将通过具体的代码示例,从最简单的方法到使用现代库,详细讲解 C++ 中日志记录的最佳实践。



为什么仅仅使用 std::cout 是不好的实践?



许多新手一开始会通过 std::cout 或 printf 输出调试信息。这虽然快速简单,但这种方法存在严重的缺点:



  • 缺乏重要性级别。无法将错误消息与信息通知区分开来。
  • 过滤困难。在生产环境中,您不希望看到大量的调试信息,但在调试时又需要它们。
  • 没有日志轮转。日志文件会无限增长,直到填满整个磁盘。
  • 多线程问题。来自不同线程的输出可能会混杂在一起。


因此,应该使用专门的工具。我们来看三种主要方法:从简单到复杂。



1. 面向初学者的简单宏封装



如果您正在编写一个小型学习程序,或者不想引入第三方库,可以创建一个基于宏的简单封装。这已经比直接使用 cout 要好。



#include <iostream>#include <fstream>#include <ctime>#include <string>

enum LogLevel { DEBUG, INFO, WARNING, ERROR};

std::string getCurrentTime() { std::time_t now = std::time(nullptr); char buf[20]; std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", std::localtime(&now)); return std::string(buf);}

#define LOG(level, msg) \ do { \ std::ofstream logFile("app.log", std::ios::app); \ logFile << "[" << getCurrentTime() << "] " \ << "[" << #level << "] " \ << msg << std::endl; \ } while(0)

int main() { LOG(INFO, "程序已启动"); int x = 42; LOG(DEBUG, "变量 x 的值: " << x); // ... LOG(ERROR, "发生了除以零的错误"); return 0;}


优点:简单,不需要外部依赖。

缺点:没有日志轮转,运行速度慢(每条消息都要打开/关闭文件),存在线程问题。



2. 使用 spdlog 库(推荐给初学者)



spdlog 是 C++ 中最流行的日志记录库(在 GitHub 上拥有超过 23,000 颗星)。它速度非常快,使用简单,并且是 header-only(仅头文件)的。



安装:只需从仓库下载文件,或使用 vcpkg/conan。



#include <spdlog/spdlog.h>#include <spdlog/sinks/basic_file_sink.h>#include <spdlog/sinks/stdout_color_sinks.h>

int main() { // 创建一个带彩色输出的控制台日志器 auto console = spdlog::stdout_color_mt("console"); // 创建一个文件日志器 auto file_logger = spdlog::basic_logger_mt("file_logger", "logs/app.log"); // 设置日志级别 spdlog::set_level(spdlog::level::debug); // 记录所有 DEBUG 及以上级别的日志 // 不同级别的消息示例 console->trace("这是一条 trace 消息(最低级别)"); console->debug("调试消息:变量 x = {}", 42); console->info("程序成功启动"); console->warn("警

博客

书籍推荐