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