NanoLog起步笔记-3-尝试解析log

nonolog起步笔记-3-尝试解析log

  • 第一次解析
    • sample中的nano二进制log在哪里
      • compressedLog
      • ./decompressor decompress /tmp/logFile
  • compressedLog是什么鬼
    • 下断分析

第一次解析

sample中的nano二进制log在哪里

如下图
在这里插入图片描述手工执行的结果如下,不看代码,还真不知道,被放到/tmp/logFile了

root@edit:/data/nano/NanoLog/sample# ./sampleApplication
The total time spent invoking NANO_LOG with no parameters 1000 times took 0.00 seconds (30.89 ns/message average)
Flushing the log statements to disk took an additional 0.02 secs

Wrote 1002 events (0.00 MB) in 0.018 seconds (0.000 seconds spent compressing)
There were 3 file flushes and the final sync time was 0.000005 sec
Compression Thread was active for 0.000 out of 0.017 seconds (1.67 %)
On average, that's
        0.19 MB/s or 5338.92 ns/byte w/ processing
        0.19 MB/s or 5327.12 ns/byte disk throughput (min)
        0.00 MB per flush with 3.3 bytes/event
        17775.10 ns/event in total
        39.31 ns/event compressing
The compression ratio was 4.82-4.82x (16090 bytes in, 3336 bytes out, 0 pad bytes)
==== NanoLog Configuration ====
StagingBuffer size: 1 MB
Output Buffer size: 67 MB
Release Threshold : 0 MB
Idle Poll Interval: 1 µs
IO Poll Interval  : 1 µs

compressedLog

特别是根目录,自动放了一个文件,叫compressedLog
我一直以为是这个文档,解了半天,没解开,看了代码才知道。
我们开始试一下吧:

./decompressor decompress /tmp/logFile

...
2024-12-09 15:10:33.000820122 main.cc:88 NOTICE[0]: Simple log message with 0 parameters
2024-12-09 15:10:33.000820143 main.cc:88 NOTICE[0]: Simple log message with 0 parameters

# Decompression Complete after printing 1002 log messages
root@edit:/data/nano/NanoLog/sample# ./decompressor decompress /tmp/logFile

好的,这样就得到我们想要的效果。

compressedLog是什么鬼

即然我们看到了,不如来研究一下,为什么会生成这样的一空文件
在代码中找compressedLog,
然后找DEFAULT_LOG_FILE,很快就定位了这个位置:
在这里插入图片描述

下断分析

注意,这里的断点,很可能不停,如果出现在这样的情况,一定要手工重编runtime目录的内容,直到./sample/libNanoLog.a 与runtime下的md5相同了。当然,注意两边都要改为O0。

然后我们将call stack向上一级,就能看到:
原因在这里:
这里定义了一个全局变量,所以,在main进入前,就在磁盘上生成了这个空文件。
RuntimeLogger RuntimeLogger::nanoLogSingleton;
在这里插入图片描述这里是可以考虑改进一下。
我稍解释一下,为什么这个问题,有点困难:
因为google的nanolog,作者希望,这个nanolog体系,用户是不需要显示初始化的。
所以,服务端的服务线程,在Runtimelogger的构造函数就已经创建。
创建的时候,就意味着,需要可以操作异步IO,这里是必须有句柄的。
而sample示例中的setlogFile,要晚一会对能登场,因为那是在main()进入后的事了。

我们来看一下相关的代码:
setlogFile最后会走到这里:
然后,会重启server端服务线程!先关闭,然后启动。


// Documentation in NanoLog.h
void
RuntimeLogger::setLogFile_internal(const char *filename) {
    // Check if it exists and is readable/writeable
    if (access(filename, F_OK) == 0 && access(filename, R_OK | W_OK) != 0) {
        std::string err = "Unable to read/write from new log file: ";
        err.append(filename);
        throw std::ios_base::failure(err);
    }

    // Try to open the file
    int newFd = open(filename, NanoLogConfig::FILE_PARAMS, 0666);
    if (newFd < 0) {
        std::string err = "Unable to open file new log file: '";
        err.append(filename);
        err.append("': ");
        err.append(strerror(errno));
        throw std::ios_base::failure(err);
    }

    // Everything seems okay, stop the background thread and change files
    sync();

    // Stop the compression thread completely
    {
        std::lock_guard<std::mutex> lock(nanoLogSingleton.condMutex);
        compressionThreadShouldExit = true;
        workAdded.notify_all();
    }

    if (compressionThread.joinable())
        compressionThread.join();

    if (outputFd > 0)
        close(outputFd);
    outputFd = newFd;

    // Relaunch thread
    nextInvocationIndexToBePersisted = 0; // Reset the dictionary
    compressionThreadShouldExit = false;
#ifndef BENCHMARK_DISCARD_ENTRIES_AT_STAGINGBUFFER
    compressionThread = std::thread(&RuntimeLogger::compressionThreadMain, this);
#endif
}

所以,如果稳妥一点的做法,
是自己写一个初始化函数,我们的项目中就是这样做的。
注释掉构造函数中的线程启动这一句,
只在setlogfile中启动。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/933896.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Sqoop脚本编写(Mysql---->>hdfs)

目录 语法手册编写方式脚本文件类型文件编写.jar路径指定 执行效果执行方式效果 语法手册 参考博客 编写方式 脚本文件类型 只要是可读的文件即可&#xff08;.txt或者.sh等其他类型&#xff0c;不带文件后缀也可以&#xff0c;但二进制文件最好不要&#xff09; 文件编写…

一、测试工具LoadRunner Professional脚本编写-录制前设置

设置基于URL的脚本 原因:基于HTML的脚本会导致login接口不能正确录制 设置UTF-8 原因:不勾选此项会导致脚本中文变为乱码

day05-开发接口-学习记录和学习计划

1. 查询用户的课程学习记录 1.1 代码实现 Controller层&#xff1a; package com.tianji.learning.controller;import com.tianji.api.dto.leanring.LearningLessonDTO; import com.tianji.learning.service.ILearningLessonService; import com.tianji.learning.service.IL…

2022 年“泰迪杯”数据分析技能赛A 题竞赛作品的自动评判

2022 年“泰迪杯”数据分析技能赛A 题竞赛作品的自动评判 完整代码请私聊 博主 一、背景 在各类学科竞赛中&#xff0c;常常要求参赛者提交 Excel 或/和 PDF 格式的竞赛作品。 本赛题以某届数据分析竞赛作品的评阅为背景&#xff0c;要求参赛者根据给定的评分准则和标准答案&a…

AI Agent框架如何选择?LangGraph vs CrewAI vs OpenAI Swarm

介绍 由 LLMs经历了起起落落。从 2023 年 AutoGPT 和 BabyAGI 的病毒式演示到今天更精致的框架&#xff0c;AI Agent的概念——LLMs自主执行端到端任务的 LLM——既引起了人们的想象力&#xff0c;也引起了怀疑。 为什么重新引起人们的兴趣&#xff1f;LLMs 在过去 9 个月中进…

【OpenCV】平滑图像

二维卷积(图像滤波) 与一维信号一样&#xff0c;图像也可以通过各种低通滤波器&#xff08;LPF&#xff09;、高通滤波器&#xff08;HPF&#xff09;等进行过滤。LPF 有助于消除噪音、模糊图像等。HPF 滤波器有助于在图像中找到边缘。 opencv 提供了函数 **cv.filter2D()**&…

调试android 指纹遇到的坑

Android8以后版本 一、指纹服务不能自动 指纹服务fingerprintd(biometrics fingerprintservice)&#xff0c;可以手动起来&#xff0c;但是在init.rc中无法启动。 解决办法&#xff1a; 1.抓取开机时kernel log &#xff0c;确认我们的启动指纹服务的init.rc 文件有被init.c…

深度学习笔记之BERT(五)TinyBERT

深度学习笔记之TinyBERT 引言回顾&#xff1a;DistilBERT模型TinyBERT模型结构TinyBERT模型策略Transformer层蒸馏嵌入层蒸馏预测层蒸馏 TinyBERT模型的训练效果展示 引言 上一节介绍了 DistilBERT \text{DistilBERT} DistilBERT模型&#xff0c;本节将继续介绍优化性更强的知…

30.串联所有单词的子串 python

串联所有单词的子串 题目题目描述示例 1&#xff1a;示例 2&#xff1a;示例 3&#xff1a;提示&#xff1a;题目链接 题解解题思路python实现代码解释&#xff1a;提交结果 题目 题目描述 给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。 s 中的…

【LeetCode】498.对角线遍历

无论何时何地&#xff0c;我都认为对于一道编程题&#xff0c;思考解法的时间用于是实际动手解决问题的2倍&#xff01;如果敲键盘编码需要5min&#xff0c;那么思考解法的过程至少就需要10分钟。 1. 题目 2. 思想 其实这就是一道模拟题&#xff0c;难度中等。做这种题的关键就…

uniapp中父组件传参到子组件页面渲染不生效问题处理实战记录

上篇文件介绍了,父组件数据更新正常但是页面渲染不生效的问题,详情可以看下:uniapp中父组件数组更新后与页面渲染数组不一致实战记录 本文在此基础上由于新增需求衍生出新的问题.本文只记录一下解决思路. 下面说下新增需求方便理解场景: 商品信息设置中添加抽奖概率设置…

Flutter提示错误:无效的源发行版17

错误描述 Flutter从3.10.1 升级到3.19.4&#xff0c;在3.10.1的时候一切运行正常&#xff0c;但是当我将Flutter版本升级到3.19.4后&#xff0c;出现了下方的错误 FAILURE: Build failed with an exception.* What went wrong: Execution failed for task :device_info_plus:…

etcd的dbsize引起的集群故障

故障现象 k8s集群不能访问&#xff0c;具体表现kubectl命令不能使用。 思路 检查apiserver服务状态&#xff0c;检查etcd集群状态中errors列中存在一个alarm:NOSPACE的告警 解决&分析 具体表现 恢复使用第一&#xff0c;先尝试解除告警看能否恢复 etcdctl --endpoin…

Redis性能优化18招

Redis性能优化的18招 目录 前言选择合适的数据结构避免使用过大的key和value[使用Redis Pipeline](#使用Redis Pipeline)控制连接数量合理使用过期策略使用Redis集群充分利用内存优化使用Lua脚本监控与调优避免热点key使用压缩使用Geo位置功能控制数据的持久化尽量减少事务使…

Docker 安装 Yapi

Docker 安装系列 Docker已安装。 1、场景Yapi使用的MongoDB用户信息 1.1 创建自定义 Docker 网络 首先&#xff0c;创建一个自定义的 Docker 网络&#xff0c;以便 MongoDB 和 YApi 容器可以相互通信 [rootflexusx-328569 data]# docker network create yapi-networ…

深度学习(2)前向传播与反向传播

这一次我们重点讲解前向传播与反向传播&#xff0c;对这里还是有点糊涂 前向传播&#xff08;Forward Propagation&#xff09;和反向传播&#xff08;Backward Propagation&#xff09;是深度学习中神经网络训练的核心过程。它们分别负责计算神经网络的输出以及更新神经网络的…

Mock神器:Easy-Mock 私有化部署及使用介绍

在现代前后端分离的开发模式中&#xff0c;后端接口的数据模拟是一个常见且必要的需求。尤其是在后端接口尚未开发完成时&#xff0c;前端开发需要依赖模拟数据进行开发与测试。Easy-Mock 是一个非常流行的开源工具&#xff08;虽然它已经停止更新好长时间了&#xff09;&#…

个人IP建设:简易指南

许多个体创业者面临的一个关键挑战是如何为其企业创造稳定的需求。 作为个体创业者&#xff0c;您无法使用营销团队&#xff0c;因此许多人通过推荐和他们的网络来产生需求。因此&#xff0c;扩大您的网络是发展您的业务和产生持续需求的最佳策略。 这就是个人IP和品牌发挥作…

二一(GIT4)、echarts(地图)、黑马就业数据平台(学生页-增 删 改)

1. echarts 地图 echarts社区&#xff1a;makeapie echarts社区图表可视化案例 社区模板代码地址&#xff1a;自定义 tooltip-轮播 - category-work,series-map地图,tooltip提示框,visualMap视觉映射 - makeapie echarts社区图表可视化案例 // todo: 籍贯分布 地图 function…

iPhone 17 Air基本确认,3个大动作

近段时间&#xff0c;果粉圈都在讨论一个尚未发布的新品&#xff1a;iPhone 17 Air&#xff0c;苹果又要来整新活了。 从供应链消息来看&#xff0c;iPhone 17 Air本质上是Plus的替代品&#xff0c;主要是在维持“大屏”这一卖点的同时&#xff0c;增加了“轻薄”属性&#xff…