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