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 PANDA_DPROF_CONVERTER_FEATURES_HOTNESS_COUNTERS_H_ 17 #define PANDA_DPROF_CONVERTER_FEATURES_HOTNESS_COUNTERS_H_ 18 19 #include "macros.h" 20 #include "features_manager.h" 21 #include "dprof/storage.h" 22 #include "utils/logger.h" 23 #include "serializer/serializer.h" 24 25 #include <list> 26 27 namespace panda::dprof { 28 static const char HCOUNTERS_FEATURE_NAME[] = "hotness_counters.v1"; 29 30 class HCountersFunctor : public FeaturesManager::Functor { 31 struct HCountersInfo { 32 struct MethodInfo { 33 std::string name; 34 uint32_t value; 35 }; 36 std::string app_name; 37 uint64_t hash; 38 uint32_t pid; 39 std::list<MethodInfo> methods_list; 40 }; 41 42 public: HCountersFunctor(std::ostream & out)43 explicit HCountersFunctor(std::ostream &out) : out_(out) {} 44 ~HCountersFunctor() = default; 45 operator()46 bool operator()(const AppData &appData, const std::vector<uint8_t> &data) override 47 { 48 std::unordered_map<std::string, uint32_t> methodInfoMap; 49 if (!serializer::BufferToType(data.data(), data.size(), methodInfoMap)) { 50 LOG(ERROR, DPROF) << "Cannot deserialize methodInfoMap"; 51 return false; 52 } 53 54 std::list<HCountersInfo::MethodInfo> methodsList; 55 for (auto &it : methodInfoMap) { 56 methodsList.emplace_back(HCountersInfo::MethodInfo {std::move(it.first), it.second}); 57 } 58 59 hcounters_info_list_.emplace_back( 60 HCountersInfo {appData.GetName(), appData.GetHash(), appData.GetPid(), std::move(methodsList)}); 61 62 return true; 63 } 64 ShowInfo(const std::string & format)65 bool ShowInfo(const std::string &format) 66 { 67 if (hcounters_info_list_.empty()) { 68 return false; 69 } 70 71 if (format == "text") { 72 ShowText(); 73 } else if (format == "json") { 74 ShowJson(); 75 } else { 76 LOG(ERROR, DPROF) << "Unknown format: " << format << std::endl; 77 return false; 78 } 79 return true; 80 } 81 82 private: ShowText()83 void ShowText() 84 { 85 out_ << "Feature: " << HCOUNTERS_FEATURE_NAME << std::endl; 86 for (auto &hcounters_info : hcounters_info_list_) { 87 out_ << " app: name=" << hcounters_info.app_name << " pid=" << hcounters_info.pid 88 << " hash=" << hcounters_info.hash << std::endl; 89 90 for (auto &method_info : hcounters_info.methods_list) { 91 out_ << " " << method_info.name << ":" << method_info.value << std::endl; 92 } 93 } 94 } 95 ShowJson()96 void ShowJson() 97 { 98 out_ << "{" << std::endl; 99 out_ << " \"" << HCOUNTERS_FEATURE_NAME << "\": [" << std::endl; 100 for (auto &hcounters_info : hcounters_info_list_) { 101 out_ << " {" << std::endl; 102 out_ << " \"app_name\": \"" << hcounters_info.app_name << "\"," << std::endl; 103 out_ << " \"pid\": \"" << hcounters_info.pid << "\"," << std::endl; 104 out_ << " \"hash\": \"" << hcounters_info.hash << "\"," << std::endl; 105 out_ << " \"counters\": [" << std::endl; 106 for (auto &method_info : hcounters_info.methods_list) { 107 out_ << " {" << std::endl; 108 out_ << " \"name\": \"" << method_info.name << "\"," << std::endl; 109 out_ << " \"value\": \"" << method_info.value << "\"" << std::endl; 110 out_ << " }"; 111 if (&method_info != &hcounters_info.methods_list.back()) { 112 out_ << ","; 113 } 114 out_ << std::endl; 115 } 116 out_ << " ]" << std::endl; 117 out_ << " }"; 118 if (&hcounters_info != &hcounters_info_list_.back()) { 119 out_ << ","; 120 } 121 out_ << std::endl; 122 } 123 out_ << " ]" << std::endl; 124 out_ << "}" << std::endl; 125 } 126 127 std::list<HCountersInfo> hcounters_info_list_; 128 std::ostream &out_; 129 130 NO_COPY_SEMANTIC(HCountersFunctor); 131 NO_MOVE_SEMANTIC(HCountersFunctor); 132 }; 133 } // namespace panda::dprof 134 135 #endif // PANDA_DPROF_CONVERTER_FEATURES_HOTNESS_COUNTERS_H_ 136