1.easylogging源码学习笔记(6)
2.ROS2日志时间戳转换成时分秒
3.日志代码怎么查看啊
4.如何从零写一个日志库(glog介绍)
5.Nginx日志系统源码分析
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的源码源码amd的机密源码指针
#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,源码源码并在callback->handle(&data)中处理输出。时间时间
由于定义了ELPP_FEATURE_PERFORMANCE_TRACKING,日志日志因此在初始化(INITIALIZE_EASYLOGGINGPP)中实际上是源码源码安装了一个base::DefaultPerformanceTrackingCallback。
在PerformanceTracker类的时间时间handle函数中,callback是日志日志一个PerformanceTrackingCallback类型指针,由于安装的源码源码bty源码是DefaultPerformanceTrackingCallback对象,因此是一个基类指针指向了派生类对象。处理输出的逻辑在DefaultPerformanceTrackingCallback类的handle函数中。
DefaultPerformanceTrackingCallback类的handle函数首先会将数据成员m_data的指针赋值给函数参数,并创建一个base::type::stringstream_t类型的对象ss用于构建输出内容。根据m_data的dataType,输出不同的信息。在输出时,会使用el::base::Writer类构造并输出内容。
ROS2日志时间戳转换成时分秒
ROS2的日志时间无法直接转换成时分秒形式,这在调试过程中确实不太方便。最近在鱼香ROS大大论坛里找到了一种解决方案,感谢大佬的分享,以下是我整理的关键步骤。
1. 基本配置
要将时间戳转换成打印时分秒格式的附近源码时间,需要修改源代码。
注:比如我的本地工作空间是catkin_ws,那么应该将源码放在catkin_ws/src中,与自己的代码一起编译。
2. 下载源码和依赖
2.1 打开文件:rcutils/include/rcutils/time.h,添加代码
2.2 打开文件:rcutils/src/time.c,添加代码
2.3 打开文件:rcutils/src/time.c,添加代码
2.4 打开文件:rcutils/src/logging.c,修改代码
2.5 编译代码
然后source后运行日志打印就可以了,也可以直接替换系统库里的头文件和库,具体如何替换还需要自己探索。
日志代码怎么查看啊
要查看日志代码,无论是别人的还是自己的,步骤各有不同。Theme源码
对于查看别人的日志代码,你只需在当前页面上右击鼠标,选择“查看源代码”选项,页面会显示包含代码的文本区域,这样你就能查看到日志代码的具体内容了。
而如果你想查看自己的日志代码,操作则相对简单一些。只需打开文章编辑界面,找到并勾选“显示源代码”的选项,页面同样会展示代码区域,帮助你了解日志代码的编写。
以上就是查看日志代码的基本方法,无论是查看别人的还是自己的日志,都可通过上述步骤轻松实现。华视源码
如何从零写一个日志库(glog介绍)
探索日志管理的艺术,本文将深入解析glog——谷歌开源的日志库,为你揭示从零开始构建自定义日志解决方案的关键要素。让我们一起从基本需求到高级接口,一窥其内部工作原理。基本需求与核心组件
glog的核心在于LogMessage类,它负责记录日志的时间、位置信息以及根据过滤条件进行输出。0.3.5版本作为起点,提供了诸如LOG、LOG_IF和LOG_TO_SINK等接口,让你能灵活定制输出到默认目标或自定义sink。 获取glog的源代码:/google/glog.git,源码中的src/glog/http://logging.h.in是你探索之旅的起点。关键接口详解
LOG(severity):这是基础接口,将日志发送到默认输出,如LOG_ERROR = LogMessage(FILE, LINE, GLOG_ERROR)。 LOG_IF(severity, condition):条件式过滤,如LOG_IF(severity, !condition) & LOG(severity),只在满足条件时记录。 LOG_TO_SINK(sink, severity):直接将日志导向自定义sink,同时不遗漏默认输出。宏定义的艺术
通过VLOG、LOG_TO_STRING和SYSLOG_IF等宏,你可以根据需求进行灵活的抽样和条件输出。例如,VLOG_IF(INFO, condition)在满足条件时增加日志的可见性,VLOG_EVERY_N则进行抽样记录。深入日志流程
glog的过滤机制依赖于LOG_IF,它根据FLAGS_minloglevel调整记录行为,避免不必要的CPU开销。LogMessage的构造和析构处理日志记录,而Stream函数确保与输出操作的兼容性。 在使用时,如LOG(INFO) << "log test",实际上会先检查条件,然后输出,返回值为void以保持与"<<"操作符的配合。高级定制与性能优化
LogMessageData结构体提供了字节的流式输出能力,通过LogDestination和Logger接口,实现灵活的日志目标管理,如支持异步写入的MyAppLogSink。 尽管glog提供了强大的基础,但其在多线程写入和日志文件类型上的限制需要通过sink接口进行扩展,以适应复杂环境下的日志需求。后续章节预告
接下来的文章将深入讨论FATAL日志和coredump的生成过程,带你了解glog在故障诊断中的关键作用。 总之,glog不仅是一个强大的日志库,更是日志管理策略的灵活载体。掌握它,为你的项目增添强大的故障排查能力。敬请期待《深入解析glog的FATAL与coredump》。Nginx日志系统源码分析
在我眼中,日志系统的工作流程是这样的:当发生异常时,系统会将异常信息写入日志文件,随后程序退出。
Nginx的日志系统采用专门的日志数据结构,并且它将文件描述与错误日志进行分类。在初始化等级数组时,会设置日志文件的配置项,将错误信息格式化。错误码err会被转换成对应的错误描述,然后将异常信息首先输入到缓冲区。
接下来,系统会打开或新建日志文件,并将其插入日志链表。随后,将缓冲区的内容刷入磁盘,并将信息输出到控制台。在这个过程中,Nginx使用了相关的错误宏定义来处理错误字符串。
此外,Nginx会根据不同的方法来获取错误信息,并将其复制到指定的缓冲区中。