当前位置: 首页 > news >正文

日志系统4 日志类型的设计

一、核心功能概述

Logger 类主要承担以下职责:

  • 管理全局日志级别,控制不同重要程度的日志是否输出
  • 提供日志消息的创建接口,对接 LogMessage 类
  • 管理日志输出和刷新策略,支持自定义输出目标
  • 处理特殊级别日志(如 FATAL)的特殊逻辑

二、关键实现解析

1. 静态成员初始化

// 初始化输出和刷新回调函数为默认实现
wangt::Logger::Outputfunc wangt::Logger::output_ = defaultOutput;
wangt::Logger::Flushfunc wangt::Logger::flush_ = defaultFlush;// 初始化全局日志级别
wangt::LOG_LEVEL wangt::Logger::s_level_ = initLogLevel();
  • 静态成员在类外初始化,确保全局唯一实例
  • 默认输出到标准输出 (stdout),默认刷新函数为 fflush (stdout)
  • 日志级别通过 initLogLevel () 函数初始化

2. 日志级别初始化逻辑

wangt::LOG_LEVEL wangt::initLogLevel()
{if (::getenv("WANGTLOG_TRACE"))return wangt::LOG_LEVEL::TRACE;else if (::getenv("WANGTLOG_DEBUG"))return wangt::LOG_LEVEL::DEBUG;elsereturn wangt::LOG_LEVEL::INFO;
}
  • 优先从环境变量获取日志级别配置
  • 支持通过环境变量 "WANGTLOG_TRACE" 和 "WANGTLOG_DEBUG" 动态设置
  • 默认日志级别为 INFO,平衡信息量和性能

3. 构造函数与析构函数

// 构造函数:初始化日志消息对象
wangt::Logger::Logger(const wangt::LOG_LEVEL &le, const string &filename, const string &funcname, const int line) : impl_(le, filename, funcname, line)
{
}// 析构函数:完成日志输出
wangt::Logger::~Logger()
{impl_ << '\n';  // 为日志添加换行符output_(impl_.toString());  // 输出完整日志flush_();       // 刷新缓冲区// 处理FATAL级别的日志:输出错误信息并终止程序if (impl_.getlevel() == LOG_LEVEL::FATAL){flush_();fprintf(stderr, "Process exit \n");abort();  // 异常终止程序}
}
  • 析构函数是日志输出的关键触发点,利用对象生命周期自动完成日志输出
  • 为每条日志自动添加换行符,保证格式一致性
  • 对 FATAL 级别日志进行特殊处理,输出错误信息并调用 abort () 终止程序

4. 日志输出与刷新控制

// 设置自定义输出函数
void wangt::Logger::setOutput(Outputfunc out)
{output_ = out;
}// 设置自定义刷新函数
void wangt::Logger::setFlush(Flushfunc flush)
{flush_ = flush;
}// 默认输出实现:输出到标准输出
void defaultOutput(const string &msg)
{size_t n = fwrite(msg.c_str(), 1, msg.size(), stdout);
}// 默认刷新实现:刷新标准输出缓冲区
void defaultFlush()
{fflush(stdout);
}
  • 通过 setOutput () 和 setFlush () 支持自定义输出策略
  • 默认输出到控制台 (stdout),可根据需要改为输出到文件、网络等
  • 使用 fwrite 而非 cout,避免 C++ IO 流的性能开销

5. 日志级别控制

// 设置全局日志级别
void wangt::Logger::setLogLevel(LOG_LEVEL level)
{s_level_ = level;
}// 获取当前全局日志级别
wangt::LOG_LEVEL wangt::Logger::GetLogLevel()
{return s_level_;
}
  • 提供接口动态调整日志级别,无需重启程序
  • 可根据运行环境 (开发 / 测试 / 生产) 灵活设置

6. 日志流接口

wangt::LogMessage &wangt::Logger::stream()
{return impl_;
}
  • 返回内部的 LogMessage 对象引用,允许通过 << 运算符添加日志内容
  • 实现了类似流操作的接口,使用便捷直观

三、设计亮点

  1. 巧用析构函数:利用对象生命周期自动触发日志输出,无需手动调用输出函数,简化使用并避免遗漏

  2. 策略模式应用:通过 std::function 定义输出和刷新策略,实现了日志生成与输出的解耦

  3. 环境变量配置:支持通过环境变量动态设置日志级别,便于在不同环境中快速切换

  4. 分级处理:对 FATAL 级别日志进行特殊处理,确保严重错误能被及时发现

  5. 默认实现:提供合理的默认输出和刷新策略,开箱即用,同时支持自定义扩展

四、使用流程

  1. (可选)通过 setOutput () 和 setFlush () 设置自定义输出和刷新策略
  2. (可选)通过 setLogLevel () 设置全局日志级别
  3. 使用日志宏 (通常基于 Logger 类实现) 输出日志信息
  4. 系统会自动根据日志级别过滤、格式化并输出日志

五、总结

Logger 类通过精心设计的接口和实现,为日志系统提供了灵活、高效的核心控制能力。它既提供了开箱即用的默认行为,又保留了足够的扩展性,允许用户根据实际需求定制日志输出策略。

该实现的核心优势在于:

  • 接口简洁易用,通过流操作符添加日志内容
  • 职责清晰,专注于日志的控制和调度
  • 扩展性好,支持自定义输出目标和格式
  • 可靠性高,对严重错误有特殊处理机制

这一设计为构建完整、高效、可靠的日志系统奠定了坚实基础。

源码头文件

#ifndef LOGGER_HPP
#define LOGGER_HPP
#include"LogMessage.hpp"
#include<functional>
namespace wangt{class Logger{public:using Outputfunc=std::function<void(const std::string &msg)>;using Flushfunc=std::function<void()>;static Outputfunc output_;static Flushfunc flush_;private:wangt::LogMessage impl_;//日志消息对象static wangt::LOG_LEVEL s_level_;public:static void setOutput(Outputfunc out);static void setFlush(Flushfunc flush);Logger(const wangt::LOG_LEVEL&le,const string &filename,const string &funcname,const int line);~Logger();wangt::LogMessage&stream();static void setLogLevel(LOG_LEVEL level);static LOG_LEVEL GetLogLevel();};wangt::LOG_LEVEL initLogLevel();
}
#endif

源码cpp文件

#include "Logger.hpp"
#include <iostream>
using namespace std;void wangt::Logger::setOutput(Outputfunc out)
{output_ = out;
}void wangt::Logger::setFlush(Flushfunc flush)
{flush_ = flush;
}wangt::Logger::Logger(const wangt::LOG_LEVEL &le, const string &filename, const string &funcname, const int line) : impl_(le, filename, funcname, line)
{
}wangt::Logger::~Logger()
{impl_ << '\n';output_(impl_.toString());flush_();if (impl_.getlevel() == LOG_LEVEL::FATAL){flush_();fprintf(stderr, "Process exit \n");abort(); //}
}wangt::LogMessage &wangt::Logger::stream()
{return impl_;
}void wangt::Logger::setLogLevel(LOG_LEVEL level)
{s_level_ = level;
}wangt::LOG_LEVEL wangt::Logger::GetLogLevel()
{return s_level_;
}wangt::LOG_LEVEL wangt::initLogLevel()
{if (::getenv("WANGT""LOG_TRACE")){return wangt::LOG_LEVEL::TRACE;}else if (::getenv("WANGT""LOG_DEBUG")){return wangt::LOG_LEVEL::DEBUG;}else{return wangt::LOG_LEVEL::INFO;}
}void defaultOutput(const string &msg)
{size_t n = fwrite(msg.c_str(), 1, msg.size(), stdout);
}void defaultFlush()
{fflush(stdout);
}wangt::Logger::Outputfunc wangt::Logger::output_ = defaultOutput;
wangt::Logger::Flushfunc wangt::Logger::flush_ = defaultFlush;wangt::LOG_LEVEL wangt::Logger::s_level_ = initLogLevel();

http://www.dtcms.com/a/487372.html

相关文章:

  • 深度学习:从图片数据到模型训练(十分类)
  • PCB mark点
  • 大兴网站开发网站建设咨询100%能上热门的文案
  • 网站建设douyanet杭州专业建设网站哪里好
  • Mysql杂志(三十二)——redo日志、undo日志
  • 2017做那些网站致富网博士自助建站系统
  • 上海做公司网站的公司室内设计网站模板
  • 化州 网站建设如何自己建营销网站
  • Kafka-2 Docker 部署单节点环境(SpringBoot验证)
  • 从0开始了解kafka《第二篇 kafka的安装、管理和配置》
  • 02 SQL数据检索入门 - SELECT语句详解
  • 从分词器构建到强化学习:nanochat开源项目下载与部署全流程教程,教你一步步训练ChatGPT语言模型
  • 长安镇仿做网站注册网站好的平台
  • 加强公司内部网站建设正邦设计公司
  • 巩义网站建设价格怎么注册个人工作室
  • 四川网站建设益友网站地图怎么用
  • 制作一个响应式网站开发工具景观设计公司名称
  • 网站设计网站开发优化欢迎你的加入
  • MySql 基本操作指令大全
  • 军用网站建设ui设计一个月挣多少钱
  • 海宁市住房和城乡建设网站网站源码程序修改
  • 做足球预测的网站小程序开发教程视频
  • 消息队列相关知识总结
  • Kafka集群Broker一点通
  • 怎样看网站建设制作方松北区建设局网站
  • 锂电电芯卷绕提质增效!光子精密边缘传感器+颜色传感器组合方案
  • 堆的 shift down 操作详解
  • QT(day1)
  • 天津做网站的公司怎么样google手机官网
  • 门户网站建设滞后微信小程序功能开发