Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $YECBGYFECGEAFWHA as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2

Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $BBWFDDBHHYHDXXAB as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2
c++中如何实现一个简单的日志库_C++日志系统设计与实现_创想鸟

c++中如何实现一个简单的日志库_C++日志系统设计与实现

一个轻量高效的C++日志库需支持多级别、线程安全及多输出目标。1. 定义DEBUG/INFO/WARN/ERROR/FATAL五种级别;2. 设计单例Logger类,封装格式化输出与文件/控制台双写入;3. 使用__VA_ARGS__宏自动传入文件名行号,简化调用;4. log函数中通过mutex加锁,按级别过滤并格式化消息写入多目标,确保线程安全。

c++中如何实现一个简单的日志库_c++日志系统设计与实现

在C++项目中,一个轻量且高效的日志库能极大提升开发效率和调试能力。实现一个简单的日志系统并不复杂,关键在于设计清晰的接口、支持多级别输出、灵活的输出目标(控制台、文件等),以及线程安全的基础保障。

定义日志级别

日志级别用于区分消息的重要程度,常见的有:

DEBUG:调试信息,开发阶段使用INFO:普通运行信息WARN:警告,可能存在问题ERROR:错误,程序无法正常执行某功能FATAL:严重错误,可能导致程序终止

可以用枚举来表示:

enum class LogLevel {    DEBUG,    INFO,    WARN,    ERROR,    FATAL};

设计日志记录器类

核心是封装一个单例的Logger类,提供简洁的调用接口。它应支持格式化输出,并允许同时输出到控制台和文件。

立即学习“C++免费学习笔记(深入)”;

基本结构如下:

class Logger {public:    static Logger& instance() {        static Logger logger;        return logger;    }
void set_level(LogLevel level) { log_level_ = level; }void set_file_output(const std::string& filename);void log(LogLevel level, const char* file, int line, const char* format, ...);

private:LogLevel loglevel = LogLevel::DEBUG;std::FILE* filehandle = nullptr;std::mutex mutex_; // 保证线程安全};

通过静态instance方法获取唯一实例,避免全局变量污染。log函数使用可变参数处理格式化字符串,类似printf。

封装宏简化调用

直接调用log函数需要手动传入文件名和行号,使用宏可以自动完成:

#define LOG_DEBUG(fmt, ...)     Logger::instance().log(LogLevel::DEBUG, __FILE__, __LINE__, fmt, ##__VA_ARGS__)#define LOG_INFO(fmt, ...)      Logger::instance().log(LogLevel::INFO, __FILE__, __LINE__, fmt, ##__VA_ARGS__)#define LOG_WARN(fmt, ...)      Logger::instance().log(LogLevel::WARN, __FILE__, __LINE__, fmt, ##__VA_ARGS__)#define LOG_ERROR(fmt, ...)     Logger::instance().log(LogLevel::ERROR, __FILE__, __LINE__, fmt, ##__VA_ARGS__)#define LOG_FATAL(fmt, ...)     Logger::instance().log(LogLevel::FATAL, __FILE__, __LINE__, fmt, ##__VA_ARGS__)

这样在代码中就可以像这样使用:

LOG_INFO("User %s logged in.", username);LOG_ERROR("Failed to open file: %s", filename);

实现日志输出逻辑

在log函数中,先判断当前级别是否满足输出条件,再格式化消息并加锁写入:

void Logger::log(LogLevel level, const char* file, int line, const char* format, ...) {    if (level < log_level_) return;
char time_buf[64];auto now = std::time(nullptr);std::strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", std::localtime(&now));char msg_buf[1024];va_list args;va_start(args, format);vsnprintf(msg_buf, sizeof(msg_buf), format, args);va_end(args);std::lock_guard lock(mutex_);// 输出到控制台const char* level_str;switch (level) {    case LogLevel::DEBUG: level_str = "DEBUG"; break;    case LogLevel::INFO:  level_str = "INFO";  break;    case LogLevel::WARN:  level_str = "WARN";  break;    case LogLevel::ERROR: level_str = "ERROR"; break;    case LogLevel::FATAL: level_str = "FATAL"; break;}printf("[%s] %s:%d %sn", time_buf, file, line, msg_buf);// 同时输出到文件(如果开启)if (file_handle_) {    fprintf(file_handle_, "[%s] %s %s:%d %sn", time_buf, level_str, file, line, msg_buf);    fflush(file_handle_);}

}

set_file_output函数用于打开日志文件:

void Logger::set_file_output(const std::string& filename) {    if (file_handle_) {        std::fclose(file_handle_);    }    file_handle_ = std::fopen(filename.c_str(), "a");}

基本上就这些。这个简易日志库已具备实用功能:分级输出、文件位置追踪、时间戳、线程安全、文件持久化。后续可扩展异步写入、滚动日志、颜色输出等功能,但对大多数小项目来说,这个版本已经够用。

以上就是c++++中如何实现一个简单的日志库_C++日志系统设计与实现的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1476169.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
C++减少动态类型检查与RTTI开销
上一篇 2025年12月19日 00:01:03
C++如何使用std::atomic实现引用计数
下一篇 2025年12月19日 00:01:21

相关推荐

发表回复

登录后才能评论
关注微信