21xrx.com
2024-11-22 03:52:18 Friday
登录
文章检索 我的文章 写文章
【教程】使用C++实现简单的日志记录器(logger)
2023-06-29 15:04:27 深夜i     --     --
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++实现一个简单的日志记录器,希望能帮助大家更好地理解和应用日志记录功能。需要注意的是,实际上现有的第三方日志库已经非常成熟和全面,所以建议大家在实际开发中使用这些库进行日志记录。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复