皮皮网

【电力vr源码】【源码精灵2019】【安逸付源码】logger 源码

2024-11-21 00:33:27 来源:js页游源码

1.spdlog源码解读(三)
2.easylogging源码学习笔记(6)
3.Gin源码分析 - 中间件(3)- Logger
4.常见log日志的源码使用方法详细解析

logger 源码

spdlog源码解读(三)

       重构代码以提升效率与可维护性是软件开发中的重要实践。针对日志记录功能,源码原代码存在重复实现与参数传递问题,源码本文将对日志记录功能进行优化,源码通过创建Logger类与Registry类实现日志管理的源码单例模式,以及引入sink机制来封装输出目的源码电力vr源码地,实现多输出日志打印。源码

       首先,源码引入单例模式通过Registry类管理日志记录器实例,源码确保全局只有一个实例,源码简化代码结构并提升管理效率。源码其次,源码针对同步与异步需求,源码源码精灵2019创建Logger类与继承于它的源码AsyncLogger类,分别满足不同场景下的源码日志记录需求。

       为实现灵活的日志输出,本文提出创建基类base_sink,并定义两个子类,分别用于将日志文本写入文件与进行彩色输出。通过此设计,spdlog能够通过多态特性实现不同输出端的日志打印,简化日志配置与实现。

       在完成上述优化后,代码将更加简洁、易于维护,安逸付源码并支持多种日志输出方式。具体实现细节已在GitHub仓库中详细展示,供读者参考与深入理解。

easylogging源码学习笔记(6)

       `LOG` 是默认日志、CLOG自定义日志、LOG_IF条件日志

       特殊日志

       LOG_EVERY_N、LOG_AFTER_N、LOG_N_TIMES

       for (int i = 1; i <= ; ++i) {

       LOG_EVERY_N(2, INFO) << "Logged every second iter";

       }// 5 logs written; 2, 4, 6, 7,

       for (int i = 1; i <= ; ++i) {

       LOG_AFTER_N(2, INFO) << "Log after 2 hits; " << i;

       }// 8 logs written; 3, 4, 5, 6, 7, 8, 9,

       for (int i = 1; i <= ; ++i) {

       LOG_N_TIMES(3, INFO) << "Log only 3 times; " << i;

       }// 3 logs writter; 1, 2, 3

       条件日志和特殊日志可以搭配使用

       * `VLOG_IF(condition, verbose-level)`

       * `CVLOG_IF(condition, verbose-level, loggerID)`

       * `VLOG_EVERY_N(n, verbose-level)`

       * `CVLOG_EVERY_N(n, verbose-level, loggerID)`

       * `VLOG_AFTER_N(n, verbose-level)`

       * `CVLOG_AFTER_N(n, verbose-level, loggerID)`

       * `VLOG_N_TIMES(n, verbose-level)`

       * `CVLOG_N_TIMES(n, verbose-level, loggerID)`

       日志详细等级判定

       if (VLOG_IS_ON(2)) {

       // Verbosity level 2 is on for this file

       }

       性能追踪

       * `TIMED_FUNC(obj-name)`

       * `TIMED_SCOPE(obj-name, block-name)`

       * `TIMED_BLOCK(obj-name, block-name)`

       这些宏实际上都是关于el::base::type::PerformanceTrackerPtr,一个指向el::base::PerformanceTracker的指针

       #if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)

       PerformanceTracker::PerformanceTracker(const std::string& blockName,

       base::TimestampUnit timestampUnit,

       const std::string& loggerId,

       bool scopedLog, Level level) :

       m_blockName(blockName), m_timestampUnit(timestampUnit), m_loggerId(loggerId), m_scopedLog(scopedLog),

       m_level(level), m_hasChecked(false), m_lastCheckpointId(std::string()), m_enabled(false) {

       #if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED

       // We store it locally so that if user happen to change configuration by the end of scope

       // or before calling checkpoint, we still depend on state of configuration at time of construction

       el::Logger* loggerPtr = ELPP->registeredLoggers()->get(loggerId, false);

       m_enabled = loggerPtr != nullptr && loggerPtr->m_typedConfigurations->performanceTracking(m_level);

       if (m_enabled) {

       base::utils::DateTime::gettimeofday(&m_startTime);

       }

       #endif // !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED

       }

       在构造函数中获取一个时间,

       PerformanceTracker::~PerformanceTracker(void) {

       #if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED

       if (m_enabled) {

       base::threading::ScopedLock scopedLock(lock());

       if (m_scopedLog) {

       base::utils::DateTime::gettimeofday(&m_endTime);

       base::type::string_t formattedTime = getFormattedTimeTaken();

       PerformanceTrackingData data(PerformanceTrackingData::DataType::Complete);

       data.init(this);

       data.m_formattedTimeTaken = formattedTime;

       PerformanceTrackingCallback* callback = nullptr;

       for (const std::pair& h

       : ELPP->m_performanceTrackingCallbacks) {

       callback = h.second.get();

       if (callback != nullptr && callback->enabled()) {

       callback->handle(&data);

       }

       }

       }

       }

       #endif // !defined(ELPP_DISABLE_PERFORMANCE_TRACKING)

       }

       在析构函数中获取一个时间,处理时间data,使用PerformanceTrackingCallback类型指针callback,githud的源码并在callback->handle(&data)中处理输出。

       由于定义了ELPP_FEATURE_PERFORMANCE_TRACKING,因此在初始化(INITIALIZE_EASYLOGGINGPP)中实际上是安装了一个base::DefaultPerformanceTrackingCallback。

       在PerformanceTracker类的handle函数中,callback是一个PerformanceTrackingCallback类型指针,由于安装的是DefaultPerformanceTrackingCallback对象,因此是一个基类指针指向了派生类对象。处理输出的逻辑在DefaultPerformanceTrackingCallback类的handle函数中。

       DefaultPerformanceTrackingCallback类的handle函数首先会将数据成员m_data的指针赋值给函数参数,并创建一个base::type::stringstream_t类型的对象ss用于构建输出内容。根据m_data的dataType,输出不同的optional指标源码信息。在输出时,会使用el::base::Writer类构造并输出内容。

Gin源码分析 - 中间件(3)- Logger

       本文深入剖析Gin框架内置中间件Logger,详细阐述其四种创建形式。基本形式以默认配置输出日志至标准输出。自定义格式器形式允许用户调整日志输出格式。指定输出流形式则灵活地将日志输出至特定写入器,同时可忽略指定路径的日志。复杂配置形式提供高度定制化,是创建中间件的高级手段。深入探讨LoggerConfig结构体,解析其三个关键属性:日志格式、输出器和忽略路径。LogFormatter方法实现日志的格式化,包含辅助函数进行颜色调整,如根据HTTP响应码和请求类型设置显示颜色。defaultLogFormatter方法提供默认的日志格式化操作。详细解析LoggerWithConfig方法,该方法获取配置参数并判断输出环境,随后将忽略路径保存为映射,记录过滤的路径。计算处理时间和构建日志字符串,输出至指定写入器。

常见log日志的使用方法详细解析

       日志在程序开发中起着至关重要的作用,它能帮助我们调试错误并记录关键信息。常见的日志框架包括Java自带的原生日志、log4j以及Slf4j等。

       日志级别是控制输出信息的关键,通常分为:OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE和ALL,级别越高,信息越详细。Java.util.Logger,如在源代码中使用`Logger`,可以通过设置级别来调整输出,例如,`logger.setLevel(Level.ALL)`会显示所有级别的信息,而`logger.setLevel(Level.WARNING)`则只会显示严重和警告级别的信息。

       log4j则通常在XML配置文件中配置,比如导入依赖和配置``元素。通过这种方式,可以精细地控制每个日志条目的格式和输出位置。log4j2的配置文件如`log4j2.xml`,提供了丰富的自定义选项。

       Slf4j作为当前主流的日志框架,支持参数化输出,只需在类头引入`import org.slf4j.Logger`和`LoggerFactory.getLogger`,并在代码中调用相关方法。在引入依赖时,可能出现`SLF4J: Failed to load class`的问题,解决方法通常是检查类路径和slf4j的绑定。Slf4j的输出信息中包含类路径信息,便于追踪问题来源。

       总结来说,log日志的使用方法因框架而异,但核心在于控制输出级别和配置细节,以满足不同开发阶段的需求。通过灵活运用这些工具,可以提高程序的可维护性和可读性。