/root/doris/be/src/util/perf_counters.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | // This file is copied from |
18 | | // https://github.com/apache/impala/blob/branch-2.9.0/be/src/util/perf-counters.h |
19 | | // and modified by Doris |
20 | | |
21 | | #pragma once |
22 | | |
23 | | #include <gen_cpp/Metrics_types.h> |
24 | | #include <stdint.h> |
25 | | |
26 | | #include <iostream> |
27 | | #include <string> |
28 | | #include <vector> |
29 | | |
30 | | // This is a utility class that aggregates counters from the kernel. These counters |
31 | | // come from different sources. |
32 | | // - perf counter syscall (/usr/include/linux/perf_event.h") |
33 | | // - /proc/self/io: io stats |
34 | | // - /proc/self/status: memory stats |
35 | | // The complexity here is that all these sources have data in a different and not |
36 | | // easy to get at format. |
37 | | // |
38 | | // A typical usage pattern would be: |
39 | | // PerfCounters counters; |
40 | | // counters.add_default_counters(); |
41 | | // counters.snapshot("After Init"); |
42 | | // <do your work> |
43 | | // counters.snapshot("After Work"); |
44 | | // counters.PrettyPrint(cout); |
45 | | // |
46 | | // TODO: Expect PerfCounters to be refactored to ProcessState. |
47 | | |
48 | | namespace doris { |
49 | | |
50 | | class PerfCounters { |
51 | | public: |
52 | | enum Counter { |
53 | | PERF_COUNTER_SW_CPU_CLOCK, |
54 | | PERF_COUNTER_SW_PAGE_FAULTS, |
55 | | PERF_COUNTER_SW_CONTEXT_SWITCHES, |
56 | | PERF_COUNTER_SW_CPU_MIGRATIONS, |
57 | | |
58 | | PERF_COUNTER_HW_CPU_CYCLES, |
59 | | PERF_COUNTER_HW_INSTRUCTIONS, |
60 | | PERF_COUNTER_HW_CACHE_HIT, |
61 | | PERF_COUNTER_HW_CACHE_MISSES, |
62 | | PERF_COUNTER_HW_BRANCHES, |
63 | | PERF_COUNTER_HW_BRANCH_MISSES, |
64 | | PERF_COUNTER_HW_BUS_CYCLES, |
65 | | |
66 | | PERF_COUNTER_VM_USAGE, |
67 | | PERF_COUNTER_VM_PEAK_USAGE, |
68 | | PERF_COUNTER_RESIDENT_SET_SIZE, |
69 | | |
70 | | PERF_COUNTER_BYTES_READ, |
71 | | PERF_COUNTER_BYTES_WRITE, |
72 | | PERF_COUNTER_DISK_READ, |
73 | | PERF_COUNTER_DISK_WRITE, |
74 | | }; |
75 | | |
76 | | // Add the 'default' counters as ones to collect. Returns false if any of those |
77 | | // counters are not available. |
78 | | // Counters cannot be added after a snapshot has been taken. |
79 | | bool add_default_counters(); |
80 | | |
81 | | // Add a specific counter to watch. Return false if that counter is not available. |
82 | | // Counters cannot be added after a snapshot has been taken. |
83 | | bool add_counter(Counter); |
84 | | |
85 | | // Take a snapshot of all the counters and store it. The caller can specify a name |
86 | | // for the snapshot. |
87 | | void snapshot(const std::string& name); |
88 | | |
89 | | // Returns the results of that snapshot |
90 | | const std::vector<int64_t>* counters(int snapshot) const; |
91 | | |
92 | | // Returns readable names for the added counters |
93 | 0 | const std::vector<std::string>* counter_names() const { return &_counter_names; } |
94 | | |
95 | | // Prints out the names and results for all snapshots to 'out' |
96 | | void pretty_print(std::ostream* out) const; |
97 | | |
98 | | PerfCounters(); |
99 | | ~PerfCounters(); |
100 | | |
101 | | // Refactor |
102 | | |
103 | | struct ProcStatus { |
104 | | int64_t vm_size = 0; |
105 | | int64_t vm_peak = 0; |
106 | | int64_t vm_rss = 0; |
107 | | int64_t vm_hwm = 0; |
108 | | }; |
109 | | |
110 | | static int parse_int(const std::string& state_key); |
111 | | static int64_t parse_int64(const std::string& state_key); |
112 | | static std::string parse_string(const std::string& state_key); |
113 | | // Original data's unit is B or KB. |
114 | | static int64_t parse_bytes(const std::string& state_key); |
115 | | |
116 | | // Flush cached process status info from `/proc/self/status`. |
117 | | static void refresh_proc_status(); |
118 | | static void get_proc_status(ProcStatus* out); |
119 | | // Return the process actual physical memory in bytes. |
120 | 1.84k | static inline int64_t get_vm_rss() { return _vm_rss; } |
121 | 0 | static inline std::string get_vm_rss_str() { return _vm_rss_str; } |
122 | 0 | static inline int64_t get_vm_hwm() { return _vm_hwm; } |
123 | 0 | static inline int64_t get_vm_size() { return _vm_size; } |
124 | 0 | static inline int64_t get_vm_peak() { return _vm_peak; } |
125 | | |
126 | | private: |
127 | | // Copy constructor and assignment not allowed |
128 | | PerfCounters(const PerfCounters&); |
129 | | PerfCounters& operator=(const PerfCounters&); |
130 | | |
131 | | bool init_sys_counter(Counter counter); |
132 | | bool init_proc_self_io_counter(Counter counter); |
133 | | bool init_proc_self_status_counter(Counter counter); |
134 | | |
135 | | bool get_sys_counters(std::vector<int64_t>& snapshot); |
136 | | bool get_proc_self_io_counters(std::vector<int64_t>& snapshot); |
137 | | bool get_proc_self_status_counters(std::vector<int64_t>& snapshot); |
138 | | |
139 | | enum DataSource { |
140 | | SYS_PERF_COUNTER, |
141 | | PROC_SELF_IO, |
142 | | PROC_SELF_STATUS, |
143 | | }; |
144 | | |
145 | | struct CounterData { |
146 | | Counter counter; |
147 | | DataSource source; |
148 | | TUnit::type type; |
149 | | |
150 | | // DataSource specific data. This is used to pull the counter values. |
151 | | union { |
152 | | // For SYS_PERF_COUNTER. File descriptor where the counter value is stored. |
153 | | int fd; |
154 | | // For PROC_SELF_IO. Line number from /proc/self/io file with this counter's value |
155 | | int proc_io_line_number; |
156 | | }; |
157 | | // For PROC_SELF_STATUS. Field name for counter |
158 | | std::string proc_status_field; |
159 | | }; |
160 | | |
161 | | std::vector<CounterData> _counters; |
162 | | std::vector<std::string> _counter_names; |
163 | | std::vector<std::string> _snapshot_names; |
164 | | std::vector<std::vector<int64_t>> _snapshots; |
165 | | // System perf counters can be grouped together. The OS will update all grouped counters |
166 | | // at the same time. This is useful to better correlate counter values. |
167 | | int _group_fd; |
168 | | |
169 | | static int64_t _vm_rss; |
170 | | static std::string _vm_rss_str; |
171 | | static int64_t _vm_hwm; |
172 | | static int64_t _vm_size; |
173 | | static int64_t _vm_peak; |
174 | | }; |
175 | | |
176 | | } // namespace doris |