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 "json.hpp" 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 isBytrace_ = enable; 54 } 55 void WaitForParserEnd(); 56 57 private: 58 enum ErrorCode { ERROR_CODE_EXIT = -2, ERROR_CODE_NODATA = -1 }; 59 int GetNextSegment(); 60 void GetDataSegAttr(DataSegment& seg, const std::smatch& matcheLine) const; 61 62 void FilterThread(); IsNotSpace(char c)63 inline static bool IsNotSpace(char c) 64 { 65 return !std::isspace(c); 66 } IsTraceComment(const std::string & buffer)67 inline static bool IsTraceComment(const std::string& buffer) 68 { 69 return ((buffer[0] == '#') || buffer.find("TASK-PID") != std::string::npos); 70 } 71 72 void ParseTraceDataItem(const std::string& buffer) override; 73 std::string StrTrim(const std::string& input) const; 74 void ParseThread(); 75 void ParserData(DataSegment& seg); 76 bool FilterData(DataSegment& seg); 77 private: 78 using json = nlohmann::json; 79 typedef struct { 80 std::string eventSource; 81 uint64_t timestamp; 82 std::vector<std::string> appName; 83 std::vector<std::string> appVersions; 84 std::vector<std::string> key; 85 std::vector<json> value; 86 } JsonData; 87 void NoArrayDataParse(JsonData jData, std::vector<size_t> noArrayIndex, DataIndex eventSourceIndex); 88 void 89 ArrayDataParse(JsonData jData, std::vector<size_t> arrayIndex, DataIndex eventSourceIndex, size_t maxArraySize); 90 void CommonDataParser(JsonData jData, DataIndex eventSourceIndex); 91 int32_t JGetData(json& jMessage, 92 JsonData& jData, 93 size_t& maxArraySize, 94 std::vector<size_t>& noArrayIndex, 95 std::vector<size_t>& arrayIndex); 96 void ParseJsonData(const std::string& buffer); 97 private: 98 using ArgsMap = std::unordered_map<std::string, std::string>; 99 bool isParsingOver_ = false; 100 std::unique_ptr<BytraceEventParser> eventParser_; 101 const std::regex bytraceMatcher_ = std::regex(R"(-(\d+)\s+\(?\s*(\d+|-+)?\)?\s?\[(\d+)\]\s*)" 102 R"([a-zA-Z0-9.]{0,5}\s+(\d+\.\d+):\s+(\S+):)"); 103 104 const std::string script_ = R"(</script>)"; 105 106 std::vector<std::string> eventsAccordingAppNames = {"POWER_IDE_BATTERY", 107 "POWER_IDE_CPU", 108 "POWER_IDE_LOCATION", 109 "POWER_IDE_GPU", 110 "POWER_IDE_DISPLAY", 111 "POWER_IDE_CAMERA", 112 "POWER_IDE_BLUETOOTH", 113 "POWER_IDE_FLASHLIGHT", 114 "POWER_IDE_AUDIO", 115 "POWER_IDE_WIFISCAN", 116 "BRIGHTNESS_NIT", 117 "SIGNAL_LEVEL", 118 "WIFI_EVENT_RECEIVED", 119 "AUDIO_STREAM_CHANGE", 120 "AUDIO_VOLUME_CHANGE", 121 "WIFI_STATE", 122 "BLUETOOTH_BR_SWITCH_STATE", 123 "LOCATION_SWITCH_STATE", 124 "ENABLE_SENSOR", 125 "DISABLE_SENSOR", 126 "WORK_REMOVE", 127 "WORK_START", 128 "WORK_STOP", 129 "WORK_ADD", 130 "POWER_RUNNINGLOCK", 131 "GNSS_STATE", 132 "ANOMALY_SCREEN_OFF_ENERGY", 133 "ANOMALY_ALARM_WAKEUP", 134 "ANOMALY_KERNEL_WAKELOCK", 135 "ANOMALY_RUNNINGLOCK", 136 "ANORMALY_APP_ENERGY", 137 "ANOMALY_GNSS_ENERGY", 138 "ANOMALY_CPU_HIGH_FREQUENCY", 139 "ANOMALY_CPU_ENERGY", 140 "ANOMALY_WAKEUP"}; 141 142 size_t parsedTraceValidLines_ = 0; 143 size_t parsedTraceInvalidLines_ = 0; 144 size_t traceCommentLines_ = 0; 145 std::mutex dataSegMux_; 146 int parseHead_ = 0; 147 std::atomic<bool> filterThreadStarted_{false}; 148 bool parseThreadStarted_ = false; 149 const int MAX_SEG_ARRAY_SIZE = 5000; 150 const int maxThread_ = 4; // 4 is the best on ubuntu 113MB/s, max 138MB/s, 6 is best on mac m1 21MB/s, 151 int parserThreadCount_ = 0; 152 bool toExit_ = false; 153 bool exited_ = false; 154 std::unique_ptr<DataSegment[]> dataSegArray_; 155 int rawDataHead_ = 0; 156 int filterHead_ = 0; 157 const int sleepDur_ = 100; 158 bool supportThread_ = false; 159 bool isBytrace_ = true; 160 }; 161 } // namespace TraceStreamer 162 } // namespace SysTuning 163 #endif // _BYTRACE_PARSER_H_ 164