• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
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 
16 #include "trace_streamer_selector.h"
17 #include <algorithm>
18 #include <chrono>
19 #include <functional>
20 #include <regex>
21 #include "args_filter.h"
22 #include "binder_filter.h"
23 #include "clock_filter.h"
24 #include "cpu_filter.h"
25 #include "file.h"
26 #include "filter_filter.h"
27 #include "hi_sysevent_measure_filter.h"
28 #include "irq_filter.h"
29 #include "measure_filter.h"
30 #include "parser/bytrace_parser/bytrace_parser.h"
31 #include "parser/htrace_parser/htrace_parser.h"
32 #if WITH_PERF
33 #include "perf_data_filter.h"
34 #endif
35 #include "process_filter.h"
36 #include "slice_filter.h"
37 #include "stat_filter.h"
38 #include "string_help.h"
39 #include "symbols_filter.h"
40 #include "system_event_measure_filter.h"
41 
42 using namespace SysTuning::base;
43 namespace SysTuning {
44 namespace TraceStreamer {
45 namespace {
GuessFileType(const uint8_t * data,size_t size)46 TraceFileType GuessFileType(const uint8_t* data, size_t size)
47 {
48     if (size == 0) {
49         return TRACE_FILETYPE_UN_KNOW;
50     }
51     std::string start(reinterpret_cast<const char*>(data), std::min<size_t>(size, 20));
52     if (start.find("# tracer") != std::string::npos) {
53         return TRACE_FILETYPE_BY_TRACE;
54     }
55     if (start.find("# TRACE") != std::string::npos) {
56         return TRACE_FILETYPE_BY_TRACE;
57     }
58     if (start.find("# SYSEVENT") != std::string::npos) {
59         return TRACE_FILETYPE_SYSEVENT;
60     }
61     if (start.find("# sysevent") != std::string::npos) {
62         return TRACE_FILETYPE_SYSEVENT;
63     }
64     if ((start.compare(0, std::string("<!DOCTYPE html>").length(), "<!DOCTYPE html>") == 0) ||
65         (start.compare(0, std::string("<html>").length(), "<html>") == 0)) {
66         return TRACE_FILETYPE_BY_TRACE;
67     }
68     if (start.compare(0, std::string("\x0a").length(), "\x0a") == 0) {
69         return TRACE_FILETYPE_UN_KNOW;
70     }
71     if (start.compare(0, std::string("OHOSPROF").length(), "OHOSPROF") == 0) {
72         return TRACE_FILETYPE_H_TRACE;
73     }
74     const std::regex bytraceMatcher = std::regex(R"(-(\d+)\s+\(?\s*(\d+|-+)?\)?\s?\[(\d+)\]\s*)"
75                                             R"([a-zA-Z0-9.]{0,5}\s+(\d+\.\d+):\s+(\S+):)");
76     std::smatch matcheLine;
77     std::string bytraceMode(reinterpret_cast<const char*>(data), size);
78     if (std::regex_search(bytraceMode, matcheLine, bytraceMatcher)) {
79         return TRACE_FILETYPE_BY_TRACE;
80     }
81     return TRACE_FILETYPE_UN_KNOW;
82 }
83 } // namespace
84 
TraceStreamerSelector()85 TraceStreamerSelector::TraceStreamerSelector()
86     : fileType_(TRACE_FILETYPE_UN_KNOW), bytraceParser_(nullptr), htraceParser_(nullptr)
87 {
88     InitFilter();
89 }
~TraceStreamerSelector()90 TraceStreamerSelector::~TraceStreamerSelector() {}
91 
InitFilter()92 void TraceStreamerSelector::InitFilter()
93 {
94     streamFilters_ = std::make_unique<TraceStreamerFilters>();
95     traceDataCache_ = std::make_unique<TraceDataCache>();
96     streamFilters_->cpuFilter_ = std::make_unique<CpuFilter>(traceDataCache_.get(), streamFilters_.get());
97     streamFilters_->sliceFilter_ = std::make_unique<SliceFilter>(traceDataCache_.get(), streamFilters_.get());
98 
99     streamFilters_->processFilter_ = std::make_unique<ProcessFilter>(traceDataCache_.get(), streamFilters_.get());
100     streamFilters_->clockFilter_ = std::make_unique<ClockFilter>(traceDataCache_.get(), streamFilters_.get());
101     streamFilters_->filterFilter_ = std::make_unique<FilterFilter>(traceDataCache_.get(), streamFilters_.get());
102 
103     streamFilters_->threadMeasureFilter_ =
104         std::make_unique<MeasureFilter>(traceDataCache_.get(), streamFilters_.get(), E_THREADMEASURE_FILTER);
105     streamFilters_->threadFilter_ =
106         std::make_unique<MeasureFilter>(traceDataCache_.get(), streamFilters_.get(), E_THREAD_FILTER);
107     streamFilters_->cpuMeasureFilter_ =
108         std::make_unique<MeasureFilter>(traceDataCache_.get(), streamFilters_.get(), E_CPU_MEASURE_FILTER);
109     streamFilters_->processMeasureFilter_ =
110         std::make_unique<MeasureFilter>(traceDataCache_.get(), streamFilters_.get(), E_PROCESS_MEASURE_FILTER);
111     streamFilters_->processFilterFilter_ =
112         std::make_unique<MeasureFilter>(traceDataCache_.get(), streamFilters_.get(), E_PROCESS_FILTER_FILTER);
113     streamFilters_->symbolsFilter_ = std::make_unique<SymbolsFilter>(traceDataCache_.get(), streamFilters_.get());
114     streamFilters_->statFilter_ = std::make_unique<StatFilter>(traceDataCache_.get(), streamFilters_.get());
115     streamFilters_->binderFilter_ = std::make_unique<BinderFilter>(traceDataCache_.get(), streamFilters_.get());
116     streamFilters_->argsFilter_ = std::make_unique<ArgsFilter>(traceDataCache_.get(), streamFilters_.get());
117     streamFilters_->irqFilter_ = std::make_unique<IrqFilter>(traceDataCache_.get(), streamFilters_.get());
118     streamFilters_->clockRateFilter_ =
119         std::make_unique<MeasureFilter>(traceDataCache_.get(), streamFilters_.get(), E_CLOCK_RATE_FILTER);
120     streamFilters_->clockEnableFilter_ =
121         std::make_unique<MeasureFilter>(traceDataCache_.get(), streamFilters_.get(), E_CLOCK_ENABLE_FILTER);
122     streamFilters_->clockDisableFilter_ =
123         std::make_unique<MeasureFilter>(traceDataCache_.get(), streamFilters_.get(), E_CLOCK_DISABLE_FILTER);
124     streamFilters_->clkRateFilter_ =
125         std::make_unique<MeasureFilter>(traceDataCache_.get(), streamFilters_.get(), E_CLK_RATE_FILTER);
126     streamFilters_->clkEnableFilter_ =
127         std::make_unique<MeasureFilter>(traceDataCache_.get(), streamFilters_.get(), E_CLK_ENABLE_FILTER);
128     streamFilters_->clkDisableFilter_ =
129         std::make_unique<MeasureFilter>(traceDataCache_.get(), streamFilters_.get(), E_CLK_DISABLE_FILTER);
130     streamFilters_->sysEventMemMeasureFilter_ =
131         std::make_unique<SystemEventMeasureFilter>(traceDataCache_.get(), streamFilters_.get(), E_SYS_MEMORY_FILTER);
132     streamFilters_->sysEventVMemMeasureFilter_ = std::make_unique<SystemEventMeasureFilter>(
133         traceDataCache_.get(), streamFilters_.get(), E_SYS_VIRTUAL_MEMORY_FILTER);
134 #if WITH_PERF
135     streamFilters_->perfDataFilter_ = std::make_unique<PerfDataFilter>(traceDataCache_.get(), streamFilters_.get());
136 #endif
137     streamFilters_->sysEventSourceFilter_ = std::make_unique<SystemEventMeasureFilter>(
138         traceDataCache_.get(), streamFilters_.get(), E_SYS_EVENT_SOURCE_FILTER);
139     streamFilters_->hiSysEventMeasureFilter_ =
140         std::make_unique<HiSysEventMeasureFilter>(traceDataCache_.get(), streamFilters_.get());
141 }
142 
WaitForParserEnd()143 void TraceStreamerSelector::WaitForParserEnd()
144 {
145     if (fileType_ == TRACE_FILETYPE_H_TRACE) {
146         htraceParser_->WaitForParserEnd();
147     }
148     if (fileType_ == TRACE_FILETYPE_BY_TRACE) {
149         bytraceParser_->WaitForParserEnd();
150     }
151     traceDataCache_->UpdateTraceRange();
152 }
153 
GetMetaData()154 MetaData* TraceStreamerSelector::GetMetaData()
155 {
156     return traceDataCache_->GetMetaData();
157 }
158 
SetDataType(TraceFileType type)159 void TraceStreamerSelector::SetDataType(TraceFileType type)
160 {
161     fileType_ = type;
162     if (fileType_ == TRACE_FILETYPE_H_TRACE) {
163         htraceParser_ = std::make_unique<HtraceParser>(traceDataCache_.get(), streamFilters_.get());
164     } else if (fileType_ == TRACE_FILETYPE_BY_TRACE) {
165         bytraceParser_ = std::make_unique<BytraceParser>(traceDataCache_.get(), streamFilters_.get());
166     }
167 }
ParseTraceDataSegment(std::unique_ptr<uint8_t[]> data,size_t size)168 bool TraceStreamerSelector::ParseTraceDataSegment(std::unique_ptr<uint8_t[]> data, size_t size)
169 {
170     if (size == 0) {
171         return true;
172     }
173     if (fileType_ == TRACE_FILETYPE_UN_KNOW) {
174         fileType_ = GuessFileType(data.get(), size);
175         if (fileType_ == TRACE_FILETYPE_H_TRACE) {
176             htraceParser_ = std::make_unique<HtraceParser>(traceDataCache_.get(), streamFilters_.get());
177         } else if (fileType_ == TRACE_FILETYPE_BY_TRACE || fileType_ == TRACE_FILETYPE_SYSEVENT) {
178             bytraceParser_ = std::make_unique<BytraceParser>(traceDataCache_.get(), streamFilters_.get());
179             bytraceParser_->EnableBytrace(fileType_ == TRACE_FILETYPE_BY_TRACE);
180         }
181         if (fileType_ == TRACE_FILETYPE_UN_KNOW) {
182             SetAnalysisResult(TRACE_PARSER_FILE_TYPE_ERROR);
183             TS_LOGI(
184                 "File type is not supported!,\nthe head content is:%s\n ---waring!!!---\n"
185                 "File type is not supported!,\n",
186                 data.get());
187             return false;
188         }
189     }
190     if (fileType_ == TRACE_FILETYPE_H_TRACE) {
191         htraceParser_->ParseTraceDataSegment(std::move(data), size);
192     } else if (fileType_ == TRACE_FILETYPE_BY_TRACE || fileType_ == TRACE_FILETYPE_SYSEVENT) {
193         bytraceParser_->ParseTraceDataSegment(std::move(data), size);
194     }
195     SetAnalysisResult(TRACE_PARSER_NORMAL);
196     return true;
197 }
EnableMetaTable(bool enabled)198 void TraceStreamerSelector::EnableMetaTable(bool enabled)
199 {
200     traceDataCache_->EnableMetaTable(enabled);
201 }
202 
SetCleanMode(bool cleanMode)203 void TraceStreamerSelector::SetCleanMode(bool cleanMode)
204 {
205     g_cleanMode = true;
206 }
ExportDatabase(const std::string & outputName) const207 int TraceStreamerSelector::ExportDatabase(const std::string& outputName) const
208 {
209     traceDataCache_->UpdateTraceRange();
210     return traceDataCache_->ExportDatabase(outputName);
211 }
Clear()212 void TraceStreamerSelector::Clear()
213 {
214     traceDataCache_->Prepare();
215     traceDataCache_->Clear();
216 }
SearchData()217 int TraceStreamerSelector::SearchData()
218 {
219     return traceDataCache_->SearchData();
220 }
OperateDatabase(const std::string & sql)221 int TraceStreamerSelector::OperateDatabase(const std::string& sql)
222 {
223     return traceDataCache_->OperateDatabase(sql);
224 }
SearchDatabase(const std::string & sql,TraceDataDB::ResultCallBack resultCallBack)225 int TraceStreamerSelector::SearchDatabase(const std::string& sql,
226     TraceDataDB::ResultCallBack resultCallBack)
227 {
228     return traceDataCache_->SearchDatabase(sql, resultCallBack);
229 }
SearchDatabase(const std::string & sql,uint8_t * out,int outLen)230 int TraceStreamerSelector::SearchDatabase(const std::string& sql, uint8_t* out, int outLen)
231 {
232     return traceDataCache_->SearchDatabase(sql, out, outLen);
233 }
UpdateTraceRangeTime(uint8_t * data,int len)234 int TraceStreamerSelector::UpdateTraceRangeTime(uint8_t* data, int len)
235 {
236     std::string traceRangeStr;
237     memcpy(&traceRangeStr, data, len);
238     int pos;
239     int size = traceRangeStr.size();
240     std::vector<string> vTraceRangeStr;
241     for (int i = 0; i < size; i++) {
242         pos = traceRangeStr.find(";", i);
243         if (pos == std::string::npos) {
244             break;
245         }
246         if (pos < size) {
247             std::string s = traceRangeStr.substr(i, pos - i);
248             vTraceRangeStr.push_back(s);
249             i = pos;
250         }
251     }
252     uint64_t minTs = std::stoull(vTraceRangeStr.at(0));
253     uint64_t maxTs = std::stoull(vTraceRangeStr.at(1));
254     traceDataCache_->UpdateTraceTime(minTs);
255     traceDataCache_->UpdateTraceTime(maxTs);
256     return 0;
257 }
SetCancel(bool cancel)258 void TraceStreamerSelector::SetCancel(bool cancel)
259 {
260     traceDataCache_->SetCancel(cancel);
261 }
262 } // namespace TraceStreamer
263 } // namespace SysTuning
264