• 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] == '#') || buffer.find("TASK-PID") != std::string::npos);
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     std::string StrTrim(const std::string &input) const;
123     void ParserData(DataSegment &seg);
124     void ParseThread();
125     bool FilterData(DataSegment &seg);
126     void FilterThread();
127 #endif
128 
129 private:
130     TraceFileType fileType_ = TRACE_FILETYPE_BY_TRACE;
131     TraceDataCache *traceDataCache_;
132 #ifdef ENABLE_BYTRACE
133     std::unique_ptr<BytraceEventParser> bytraceEventParser_;
134     const std::regex bytraceMatcher_ = std::regex(R"(-(\d+)\s+\(?\s*(\d+|-+)?\)?\s?\[(\d+)\]\s*)"
135                                                   R"([a-zA-Z0-9.]{0,5}\s+(\d+\.\d+):\s+(\S+):)");
136     bool isBytrace_ = true;
137 #endif
138 #ifdef ENABLE_HILOG
139     std::unique_ptr<PtreaderHilogParser> hilogParser_;
140 #endif
141 #ifdef ENABLE_HISYSEVENT
142     std::unique_ptr<PtreaderHiSysEventParser> hiSysEventParser_;
143 #endif
144     bool isParsingOver_ = false;
145     const std::string script_ = R"(</script>)";
146     size_t parsedTraceValidLines_ = 0;
147     size_t parsedTraceInvalidLines_ = 0;
148     size_t traceCommentLines_ = 0;
149     std::mutex dataSegMux_;
150     int32_t parseHead_ = 0;
151     std::atomic<bool> filterThreadStarted_{false};
152     bool parseThreadStarted_ = false;
153     const int32_t maxSegArraySize = 5000;
154     const int32_t maxThread_ = 4; // 4 is the best on ubuntu 113MB/s, max 138MB/s, 6 is best on mac m1 21MB/s,
155     int32_t parserThreadCount_ = 0;
156     bool toExit_ = false;
157     bool exited_ = false;
158     std::unique_ptr<DataSegment[]> dataSegArray_;
159     int32_t rawDataHead_ = 0;
160     int32_t filterHead_ = 0;
161     const int32_t sleepDur_ = 100;
162     bool traceBegan_ = false;
163     bool isFirstLine_ = true;
164     bool isHtmlTrace_ = false;
165     bool isHtmlTraceContent_ = false;
166     int64_t seq_ = 1;
167     uint64_t curFileOffset_ = 0;
168     uint32_t curDataSize_ = 0;
169     int32_t minSplitPos_ = INVALID_INT32;
170     int32_t maxSplitPos_ = INVALID_INT32;
171     std::deque<std::pair<int32_t /* offset */, int32_t /* size */>> mPtreaderSplitData_ = {};
172 };
173 } // namespace TraceStreamer
174 } // namespace SysTuning
175 #endif // _ptreader_parser_H_
176