• 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 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