Nanolog起步笔记-9-log解压过程(3)寻找meta续

Nanolog起步笔记-9-log解压过程-3-寻找meta续

当前的目标

没有办法,还要继续。

当前的目标,是找到解压时, meta 的信息。

注意,先备份一下/tmp/logFile到其它的位置。

因为clean,clean-all时会删除这个文件。

除非sample下和runtime下的两个GNUmakefile都改过。

如果没有备份,可能对分析有点影响。

新的改变

1。 launch.json

改为:decompressUnordered

json 复制代码
        {
           "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

cpp 复制代码
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

cpp 复制代码
        // 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语句

cpp 复制代码
    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条记录之后,这里就直接返回了

小结

基本准备好一套,可以进一步分析代码。