21xrx.com
2025-03-26 23:48:16 Wednesday
文章检索 我的文章 写文章
【教程】使用C++实现简单的日志记录器(logger)
2023-06-29 15:04:27 深夜i     16     0
C++ 日志记录器 实现 简单 教程

在软件开发中,我们经常需要记录程序运行时的信息,以便于调试、分析和排查问题。这时候,日志记录器(logger)就显得非常重要。本篇文章将介绍使用C++实现一个简单的日志记录器,帮助大家更好地理解和应用日志记录功能。

1. 需求分析

一个基本的日志记录器需要支持以下功能:

- 可以指定日志文件名和存储路径;

- 支持不同级别的日志;

- 支持输出日志时间和文件名、函数名、行号等额外信息;

- 支持添加自定义信息到日志中。

2. 设计实现

首先我们可以定义日志级别的枚举类型:

enum LogLevel
  LOG_LEVEL_INFO;

然后定义一个日志记录器类,包含以下私有成员:

class Logger {
public:
  Logger();
  Logger(const std::string& fileName, const std::string& path);
  virtual ~Logger();
  void setLogLevel(LogLevel level);
  void setLogFilePath(const std::string& path);
  void debug(const std::string& message);
  void info(const std::string& message);
  void warn(const std::string& message);
  void error(const std::string& message);
  void fatal(const std::string& message);
  template<typename... Args>
  void debugFmt(const std::string& format, Args... args);
  template<typename... Args>
  void infoFmt(const std::string& format, Args... args);
  template<typename... Args>
  void warnFmt(const std::string& format, Args... args);
  template<typename... Args>
  void errorFmt(const std::string& format, Args... args);
  template<typename... Args>
  void fatalFmt(const std::string& format, Args... args);
private:
  LogLevel m_logLevel;
  std::string m_logFile;
  std::ofstream m_outputStream;
  void output(LogLevel level, const std::string& message);
  std::string format(DateTime dateTime, const std::string& fileName, const std::string& function, int line);
};

其中,setLogLevel和setLogFilePath用来设置日志级别和日志文件路径,debug/info/warn/error/fatal等函数用来记录不同级别的日志,debugFmt/infoFmt/warnFmt/errorFmt/fatalFmt等函数用来支持格式化日志输出。

在实现中,我们可以使用第三方库spdlog来辅助记录日志,通过以下代码初始化日志记录器:

spdlog::set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] [%n] [%s:%#] %v");
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
console_sink->set_level(spdlog::level::trace);
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("log.txt", true);
file_sink->set_level(spdlog::level::trace);
std::vector<spdlog::sink_ptr> sinksconsole_sink;
auto logger = std::make_shared<spdlog::logger>("mylogger", std::begin(sinks), std::end(sinks));
spdlog::register_logger(logger);

3. 使用示例

使用示例代码如下:

int main() {
  Logger logger("log.txt", "./");
  logger.info("Start running.");
  logger.setLogLevel(LOG_LEVEL_DEBUG);
  logger.debug("Debug message.");
  logger.warn("Warning message.");
  logger.error("Error message.");
  logger.fatal("Fatal message.");
  logger.debugFmt("Debug message with argument: {}.", 123);
  logger.infoFmt("Info message with argument: {}.", "String");
  logger.warnFmt("Warning message with arguments: {} , {}", true, 3.14);
  logger.errorFmt("Error message with argument: {0:.2f} .", 1.2345);
  logger.fatalFmt("Fatal message with argument: {:#X} .", 0x1234);
  return 0;
}

执行后,将记录如下日志:

[2022-03-04 10:31:02.411904] [info] [mylogger] [logger.cpp:70] Start running.
[2022-03-04 10:31:02.428109] [debug] [mylogger] [logger.cpp:77] Debug message.
[2022-03-04 10:31:02.436558] [warn] [mylogger] [logger.cpp:79] Warning message.
[2022-03-04 10:31:02.454475] [error] [mylogger] [logger.cpp:81] Error message.
[2022-03-04 10:31:02.463152] [critical] [mylogger] [logger.cpp:83] Fatal message.
[2022-03-04 10:31:02.470203] [debug] [mylogger] [logger.cpp:85] Debug message with argument: 123.
[2022-03-04 10:31:02.478104] [info] [mylogger] [logger.cpp:87] Info message with argument: String.
[2022-03-04 10:31:02.486101] [warn] [mylogger] [logger.cpp:89] Warning message with arguments: true , 3.14.
[2022-03-04 10:31:02.494345] [error] [mylogger] [logger.cpp:91] Error message with argument: 1.23 .
[2022-03-04 10:31:02.502571] [critical] [mylogger] [logger.cpp:93] Fatal message with argument: 0x1234 .

4. 结语

本篇文章介绍了如何使用C++实现一个简单的日志记录器,希望能帮助大家更好地理解和应用日志记录功能。需要注意的是,实际上现有的第三方日志库已经非常成熟和全面,所以建议大家在实际开发中使用这些库进行日志记录。

  
  

评论区

请求出错了