• 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 "hi_sysevent_measure_filter.h"
26 #include "log.h"
27 #include "parser_base.h"
28 #include "string_to_numerical.h"
29 #include "trace_data/trace_data_cache.h"
30 #include "trace_streamer_filters.h"
31 
32 namespace SysTuning {
33 namespace TraceStreamer {
34 class BytraceParser : public ParserBase {
35 public:
36     BytraceParser(TraceDataCache* dataCache, const TraceStreamerFilters* filters);
37     ~BytraceParser();
38 
39     void ParseTraceDataSegment(std::unique_ptr<uint8_t[]> bufferStr, size_t size) override;
ParsedTraceValidLines()40     size_t ParsedTraceValidLines() const
41     {
42         return parsedTraceValidLines_;
43     }
ParsedTraceInvalidLines()44     size_t ParsedTraceInvalidLines() const
45     {
46         return parsedTraceInvalidLines_;
47     }
TraceCommentLines()48     size_t TraceCommentLines() const
49     {
50         return traceCommentLines_;
51     }
EnableBytrace(bool enable)52     void EnableBytrace(bool enable)
53     {
54         isBytrace_ = enable;
55     }
56 
57     void WaitForParserEnd();
58 
59 private:
60     int32_t GetNextSegment();
61     void GetDataSegAttr(DataSegment& seg, const std::smatch& matcheLine) const;
62 
63     void FilterThread();
IsNotSpace(char c)64     inline static bool IsNotSpace(char c)
65     {
66         return !std::isspace(c);
67     }
IsTraceComment(const std::string & buffer)68     inline static bool IsTraceComment(const std::string& buffer)
69     {
70         return ((buffer[0] == '#') || buffer.find("TASK-PID") != std::string::npos);
71     }
IsHtmlTrace(const std::string & buffer)72     inline static bool IsHtmlTrace(const std::string& buffer)
73     {
74         std::string lower(buffer);
75         transform(buffer.begin(), buffer.end(), lower.begin(), ::tolower);
76         return ((lower.compare(0, std::string("<!doctype html>").length(), "<!doctype html>") == 0) ||
77                 (lower.compare(0, std::string("<html>").length(), "<html>") == 0));
78     }
IsHtmlTraceBegin(const std::string & buffer)79     inline static bool IsHtmlTraceBegin(const std::string& buffer)
80     {
81         return buffer.find(R"(<script class="trace-data" type="application/text">)") != std::string::npos;
82     }
83 
84     void ParseTraceDataItem(const std::string& buffer) override;
85     std::string StrTrim(const std::string& input) const;
86     void ParseThread();
87     void ParserData(DataSegment& seg);
88     bool FilterData(DataSegment& seg);
89 
90 private:
91     void AppendJsonDataToHiSysEventNewValue(JsonData jData, int32_t jIndex, DataIndex eventSourceIndex);
92     void NoArrayDataParse(JsonData jData, std::vector<size_t> noArrayIndex, DataIndex eventSourceIndex);
93     void ArrayDataParse(JsonData jData,
94                         std::vector<size_t> arrayIndex,
95                         DataIndex eventSourceIndex,
96                         size_t maxArraySize);
97     void CommonDataParser(JsonData jData, DataIndex eventSourceIndex);
98     void ParseJsonData(const std::string& buffer);
99 
100 private:
101     using ArgsMap = std::unordered_map<std::string, std::string>;
102     bool isParsingOver_ = false;
103     std::unique_ptr<BytraceEventParser> eventParser_;
104     const std::regex bytraceMatcher_ = std::regex(R"(-(\d+)\s+\(?\s*(\d+|-+)?\)?\s?\[(\d+)\]\s*)"
105                                                   R"([a-zA-Z0-9.]{0,5}\s+(\d+\.\d+):\s+(\S+):)");
106 
107     const std::string script_ = R"(</script>)";
108     size_t parsedTraceValidLines_ = 0;
109     size_t parsedTraceInvalidLines_ = 0;
110     size_t traceCommentLines_ = 0;
111     std::mutex dataSegMux_;
112     int32_t parseHead_ = 0;
113     std::atomic<bool> filterThreadStarted_{false};
114     bool parseThreadStarted_ = false;
115     const int32_t MAX_SEG_ARRAY_SIZE = 5000;
116     const int32_t maxThread_ = 4; // 4 is the best on ubuntu 113MB/s, max 138MB/s, 6 is best on mac m1 21MB/s,
117     int32_t parserThreadCount_ = 0;
118     bool toExit_ = false;
119     bool exited_ = false;
120     std::unique_ptr<DataSegment[]> dataSegArray_;
121     int32_t rawDataHead_ = 0;
122     int32_t filterHead_ = 0;
123     const int32_t sleepDur_ = 100;
124     bool supportThread_ = false;
125     bool isBytrace_ = true;
126     bool traceBegan_ = false;
127     bool isFirstLine = true;
128     bool isHtmlTrace_ = false;
129     bool isHtmlTraceContent_ = false;
130 };
131 } // namespace TraceStreamer
132 } // namespace SysTuning
133 #endif // _BYTRACE_PARSER_H_
134