• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #ifndef PTREADER_PARSER_H
17 #define PTREADER_PARSER_H
18 
19 #include <condition_variable>
20 #include <mutex>
21 #include <regex>
22 #include <thread>
23 
24 #ifdef ENABLE_BYTRACE
25 #include "bytrace_event_parser.h"
26 #endif
27 #include "common_types.h"
28 #ifdef ENABLE_HILOG
29 #include "ptreader_hilog_parser.h"
30 #endif
31 #ifdef ENABLE_HISYSEVENT
32 #include "ptreader_hisysevent_parser.h"
33 #endif
34 #include "parser_base.h"
35 #include "string_to_numerical.h"
36 #include "trace_data_cache.h"
37 #include "trace_streamer_filters.h"
38 
39 namespace SysTuning {
40 namespace TraceStreamer {
41 constexpr int32_t DETERMINE_CONTINUE = 2;
42 constexpr int32_t DETERMINE_RETURN = 3;
43 class PtreaderParser : public ParserBase {
44 public:
45     PtreaderParser(TraceDataCache *dataCache,
46                    const TraceStreamerFilters *filters,
47                    TraceFileType fileType = TRACE_FILETYPE_BY_TRACE);
48     ~PtreaderParser();
49 
50     template <typename Iterator>
51     int32_t WhileDetermine(Iterator &determine, Iterator &packagesBegin, bool &isParsingOver_, bool isFinish);
52     int32_t GotoDetermine(std::string &bufferLine, bool &haveSplitSeg);
53 
54     void ParseTraceDataSegment(std::unique_ptr<uint8_t[]> bufferStr, size_t size, bool isFinish = false) override;
ParsedTraceValidLines()55     size_t ParsedTraceValidLines() const
56     {
57         return parsedTraceValidLines_;
58     }
ParsedTraceInvalidLines()59     size_t ParsedTraceInvalidLines() const
60     {
61         return parsedTraceInvalidLines_;
62     }
TraceCommentLines()63     size_t TraceCommentLines() const
64     {
65         return traceCommentLines_;
66     }
67 #ifdef ENABLE_BYTRACE
EnableBytrace(bool enable)68     void EnableBytrace(bool enable)
69     {
70         isBytrace_ = enable;
71     }
72 #endif
MinSplitPos()73     int32_t MinSplitPos()
74     {
75         return minSplitPos_;
76     }
MaxSplitPos()77     int32_t MaxSplitPos()
78     {
79         return maxSplitPos_;
80     }
GetPtreaderSplitData()81     const auto &GetPtreaderSplitData()
82     {
83         return mPtreaderSplitData_;
84     }
ClearPtreaderSplitData()85     void ClearPtreaderSplitData()
86     {
87         mPtreaderSplitData_.clear();
88         curFileOffset_ = 0;
89         curDataSize_ = 0;
90         minSplitPos_ = INVALID_INT32;
91         maxSplitPos_ = INVALID_INT32;
92         isParsingOver_ = false;
93     }
94 
95     void WaitForParserEnd();
96 
97 private:
98     bool UpdateSplitPos();
99     void ParseTraceDataItem(const std::string &buffer) override;
100 #ifdef ENABLE_BYTRACE
101     int32_t GetNextSegment();
102     void GetDataSegAttr(DataSegment &seg, const std::smatch &matcheLine) const;
IsNotSpace(char c)103     inline static bool IsNotSpace(char c)
104     {
105         return !std::isspace(c);
106     }
IsTraceComment(const std::string & buffer)107     inline static bool IsTraceComment(const std::string &buffer)
108     {
109         return buffer[0] == '#';
110     }
IsHtmlTrace(const std::string & buffer)111     inline static bool IsHtmlTrace(const std::string &buffer)
112     {
113         std::string lower(buffer);
114         transform(buffer.begin(), buffer.end(), lower.begin(), ::tolower);
115         return ((lower.compare(0, std::string("<!doctype html>").length(), "<!doctype html>") == 0) ||
116                 (lower.compare(0, std::string("<html>").length(), "<html>") == 0));
117     }
IsHtmlTraceBegin(const std::string & buffer)118     inline static bool IsHtmlTraceBegin(const std::string &buffer)
119     {
120         return buffer.find(R"(<script class="trace-data" type="application/text">)") != std::string::npos;
121     }
122     void ParserData(DataSegment &seg);
123     void ParseThread();
124     bool FilterData(DataSegment &seg);
125     void FilterThread();
126 #endif
127 
128 private:
129     TraceFileType fileType_ = TRACE_FILETYPE_BY_TRACE;
130     TraceDataCache *traceDataCache_;
131 #ifdef ENABLE_BYTRACE
132     std::unique_ptr<BytraceEventParser> bytraceEventParser_;
133     const std::regex bytraceMatcher_ = std::regex(R"(-(\d+)\s+\(?\s*(\d+|-+)?\)?\s?\[(\d+)\]\s*)"
134                                                   R"([a-zA-Z0-9.]{0,5}\s+(\d+\.\d+):\s+(\S+):)");
135     bool isBytrace_ = true;
136 #endif
137 #ifdef ENABLE_HILOG
138     std::unique_ptr<PtreaderHilogParser> hilogParser_;
139 #endif
140 #ifdef ENABLE_HISYSEVENT
141     std::unique_ptr<PtreaderHiSysEventParser> hiSysEventParser_;
142 #endif
143     bool isParsingOver_ = false;
144     const std::string script_ = R"(</script>)";
145     size_t parsedTraceValidLines_ = 0;
146     size_t parsedTraceInvalidLines_ = 0;
147     size_t traceCommentLines_ = 0;
148     std::mutex dataSegMux_;
149     int32_t parseHead_ = 0;
150     std::atomic<bool> filterThreadStarted_{false};
151     bool parseThreadStarted_ = false;
152     const int32_t maxSegArraySize = 5000;
153     const int32_t maxThread_ = 4; // 4 is the best on ubuntu 113MB/s, max 138MB/s, 6 is best on mac m1 21MB/s,
154     int32_t parserThreadCount_ = 0;
155     bool toExit_ = false;
156     bool exited_ = false;
157     std::unique_ptr<DataSegment[]> dataSegArray_;
158     int32_t rawDataHead_ = 0;
159     int32_t filterHead_ = 0;
160     const int32_t sleepDur_ = 100;
161     bool traceBegan_ = false;
162     bool isFirstLine_ = true;
163     bool isHtmlTrace_ = false;
164     bool isHtmlTraceContent_ = false;
165     int64_t seq_ = 1;
166     uint64_t curFileOffset_ = 0;
167     uint32_t curDataSize_ = 0;
168     int32_t minSplitPos_ = INVALID_INT32;
169     int32_t maxSplitPos_ = INVALID_INT32;
170     std::deque<std::pair<int32_t /* offset */, int32_t /* size */>> mPtreaderSplitData_ = {};
171 };
172 } // namespace TraceStreamer
173 } // namespace SysTuning
174 #endif // _ptreader_parser_H_
175