Nanolog起步笔记-9-log解压过程-3-寻找meta续
- 当前的目标
- 新的改变
- decompressNextLogStatement
- metadata
- 查看业务面的log语句
- 注释掉 runBenchmark();
- 改过之后,2条记录之后,这里就直接返回了
- 小结
当前的目标
没有办法,还要继续。
当前的目标,是找到解压时, meta 的信息。
注意,先备份一下/tmp/logFile到其它的位置。
因为clean,clean-all时会删除这个文件。
除非sample下和runtime下的两个GNUmakefile都改过。
如果没有备份,可能对分析有点影响。
新的改变
1。 launch.json
改为:decompressUnordered
{
"name": "C++ Launch decompressor",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/sample/decompressor",
"args": ["decompressUnordered","/tmp/logFile"],
"environment": [{ "name": "config", "value": "Debug" }],
"cwd": "${workspaceFolder}/sample",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
因为这样能路过许多不需要关注的代码。
我们目前也不需要sort。
decompressNextLogStatement
bool
Log::Decoder::BufferFragment::decompressNextLogStatement(FILE *outputFd,
uint64_t &logMsgsProcessed,
LogMessage &logArgs,
const Checkpoint &checkpoint,
std::vector<void*>& fmtId2metadata,
long aggregationFilterId,
void (*aggregationFn)(const char*, ...))
{
// Output the context
if (outputFd) {
fprintf(outputFd,"%s.%09.0lf %s:%u %s[%u]: "
, timeString
, nanos
, filename
, metadata->lineNumber
, logLevel
, runtimeId);
fflush(outputFd); //haoyujie
}
如下图:
说明:outputFd=stdout
在这里也卡了一小会,因为terminal中,没有输出。我想了半天,
问了下电脑,才发现自己大脑快down机,只是没有flush…
好吧,我加上了一句。为了调试。
这样我们第一次看到一个log的输出所在的位置。
之后我们可以向前研究,这个结果是如何得到的。
2024-12-10 16:23:46.000853307 main.cc:59 NOTICE[0]:
我们看到,这些信息,都能对应上,
而且只打印了前半部分。
这是后面我们要分析的,
timeString , nanos, filename , metadata->lineNumber , logLevel , runtimeId
这些record头部的信息,值从何得来。
目前我们看到几个问题:
1。 信息只有前半部分,时间
2。文件名中的路径被删除了。只留下main.c。这是前述“压缩”的重要组成部分之一。
3。 runtimeId,这个可能就是线程号。但是要注意的是nanolog的线程id,并不是线程ID。是nanolog自己维护的一个entry id。每开一个线程,就多一个。
metadata
然后我们看到了metadata
// Print out the actual log message, piece by piece
PrintFragment *pf = reinterpret_cast<PrintFragment*>(
reinterpret_cast<char*>(metadata)
+ sizeof(FormatMetadata)
+ metadata->filenameLength);
其实前面,我们已经看到过:
也就是意味着,我们在这里分析时,meta信息,已加载了。
没有关系,一会我们再分析一遍。
metadata->filenameLength=8
正好是main.cc加一个’\0’。
查看业务面的log语句
NANO_LOG(NOTICE, "A string, pointer, number, and float: '%s', %p, %d, %f",
randomString,
&randomString,
512,
3.14159);
可以看到,共4个参数。
其中3个数字,1个字符串。
后面的代码:
metadata->numPrintFragments=4 //argc: 4 parameters
然后,在printSingleArg
执行这之后:
2024-12-10 16:23:46.000853307 main.cc:59 NOTICE[0]: A string, pointer, number, and float: 'Hello World
即已打印出第一个参数。
向前步进:
第二个参数%p
以此类推,直到最后一个参数完成。
团成员到主循环,准备解压下一条
## 然后,发现这里前面我的一个误解
2024-12-10 16:23:46.000856704 main.cc:88 NOTICE[0]: Simple log message with 0 parameters
是真的有这个数据。
否则不会指出是哪个文件的哪一行,这里是我疏忽了。
也给了我们进一步简化这个程序的可能性。
注释掉 runBenchmark();
注掉main()中的runBenchmark();,之后,程序的运行轨迹简化了许多。
不过,要注意的是,logFile需要删除重做。如果不删除,文件会被重新打开,从头开始重写。旧的内容还在。
改过之后,2条记录之后,这里就直接返回了
小结
基本准备好一套,可以进一步分析代码。