1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "pbreader_disk_io_parser.h"
16 #include "clock_filter_ex.h"
17 #include "diskio_plugin_result.pbreader.h"
18 #include "process_filter.h"
19 #include "stat_filter.h"
20 namespace SysTuning {
21 namespace TraceStreamer {
PbreaderDiskIOParser(TraceDataCache * dataCache,const TraceStreamerFilters * ctx)22 PbreaderDiskIOParser::PbreaderDiskIOParser(TraceDataCache *dataCache, const TraceStreamerFilters *ctx)
23 : EventParserBase(dataCache, ctx)
24 {
25 }
26
~PbreaderDiskIOParser()27 PbreaderDiskIOParser::~PbreaderDiskIOParser()
28 {
29 TS_LOGI("diskio ts MIN:%llu, MAX:%llu", static_cast<unsigned long long>(GetPluginStartTime()),
30 static_cast<unsigned long long>(GetPluginEndTime()));
31 }
Parse(ProtoReader::BytesView tracePacket,uint64_t ts)32 void PbreaderDiskIOParser::Parse(ProtoReader::BytesView tracePacket, uint64_t ts)
33 {
34 ProtoReader::DiskioData_Reader diskioData(tracePacket.data_, tracePacket.size_);
35 auto stat = diskioData.statsdata();
36 ProtoReader::StatsData_Reader statsData(stat);
37 double rdCountPerSec = 0; // The amount of data read from the device per second kB_read/s
38 double wrCountPerSec = 0; // The amount of data written to the device per second kB_wrtn/s
39 uint64_t rdCount = 0; // Total amount of data read kB_read
40 uint64_t wrCount = 0; // The total amount of data written kB_wrtn
41 for (auto i = statsData.statsinfo(); i; ++i) {
42 auto statsInfo = ProtoReader::IoStatData_Reader(i->ToBytes());
43 rdCountPerSec += statsInfo.rd_per_sec();
44 wrCountPerSec += statsInfo.wr_per_sec();
45 rdCount += statsInfo.rd_kb();
46 wrCount += statsInfo.wr_kb();
47 }
48
49 streamFilters_->statFilter_->IncreaseStat(TRACE_DISKIO, STAT_EVENT_RECEIVED);
50 diskIOData_.push_back(TsDiskIOData{ts, diskioData.rd_sectors_kb(), diskioData.wr_sectors_kb(),
51 diskioData.prev_rd_sectors_kb(), diskioData.prev_wr_sectors_kb(), rdCountPerSec,
52 wrCountPerSec, rdCount, wrCount});
53 }
Finish()54 void PbreaderDiskIOParser::Finish()
55 {
56 auto cmp = [](const TsDiskIOData &a, const TsDiskIOData &b) { return a.ts < b.ts; };
57 std::stable_sort(diskIOData_.begin(), diskIOData_.end(), cmp);
58 bool first = true;
59 uint64_t lastTs = 0;
60 for (auto itor = diskIOData_.begin(); itor != diskIOData_.end(); itor++) {
61 DiskIoRow row;
62 row.ts = streamFilters_->clockFilter_->ToPrimaryTraceTime(TS_CLOCK_REALTIME, itor->ts);
63 UpdatePluginTimeRange(TS_CLOCK_REALTIME, row.ts, row.ts);
64 if (first) {
65 lastTs = row.ts;
66 first = false;
67 continue;
68 }
69 row.dur = row.ts - lastTs;
70 auto durS = 1.0 * row.dur / SEC_TO_NS;
71 row.rd = itor->rdSectorsKb;
72 row.wr = itor->wrSectorsKb;
73 row.rdPerSec = 1.0 * (itor->rdSectorsKb - itor->prevRdSectorsKb) / durS;
74 row.wrPerSec = 1.0 * (itor->wrSectorsKb - itor->prevWrSectorsKb) / durS;
75 row.rdCountPerSec = itor->rdCountPerSec;
76 row.wrCountPerSec = itor->wrCountPerSec;
77 row.rdCount = itor->rdCount;
78 row.wrCount = itor->wrCount;
79 traceDataCache_->GetDiskIOData()->AppendNewData(row);
80 lastTs = row.ts;
81 }
82 diskIOData_.clear();
83 traceDataCache_->MixTraceTime(GetPluginStartTime(), GetPluginEndTime());
84 }
85 } // namespace TraceStreamer
86 } // namespace SysTuning
87