Skip to content

Commit 1d6dfd2

Browse files
committed
feat(trace): 实现在to_json的时候,输出统计数据,并标记较高耗时的事件时间点
1 parent 11a81f3 commit 1d6dfd2

File tree

2 files changed

+100
-6
lines changed

2 files changed

+100
-6
lines changed

modules/trace/lib/sink.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -248,8 +248,7 @@ Sink::Index Sink::allocNameIndex(const std::string &name, uint32_t line)
248248
{
249249
//! 如果文件不存在了,则重写所有的名称列表
250250
if (!util::fs::IsFileExist(name_list_filename_)) {
251-
std::vector<std::string> name_vec;
252-
name_vec.resize(name_to_index_map_.size());
251+
std::vector<std::string> name_vec(name_to_index_map_.size());
253252
for (auto &item : name_to_index_map_)
254253
name_vec[item.second] = item.first;
255254

@@ -276,8 +275,7 @@ Sink::Index Sink::allocModuleIndex(const std::string &module)
276275
{
277276
//! 如果文件不存在了,则重写所有的名称列表
278277
if (!util::fs::IsFileExist(module_list_filename_)) {
279-
std::vector<std::string> module_vec;
280-
module_vec.resize(module_to_index_map_.size());
278+
std::vector<std::string> module_vec(module_to_index_map_.size());
281279
for (auto &item : module_to_index_map_)
282280
module_vec[item.second] = item.first;
283281

@@ -303,8 +301,7 @@ Sink::Index Sink::allocThreadIndex(long thread_id)
303301
{
304302
//! 如果文件不存在了,则重写所有的线程列表
305303
if (!util::fs::IsFileExist(thread_list_filename_)) {
306-
std::vector<int> thread_vec;
307-
thread_vec.resize(thread_to_index_map_.size());
304+
std::vector<int> thread_vec(thread_to_index_map_.size());
308305
for (auto &item : thread_to_index_map_)
309306
thread_vec[item.second] = item.first;
310307

modules/trace/tools/to_json/main.cpp

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
* of the source tree.
1919
*/
2020
#include <iostream>
21+
#include <limits>
2122

2223
#include <tbox/util/fs.h>
2324
#include <tbox/util/string.h>
@@ -29,7 +30,22 @@
2930
using namespace std;
3031
using namespace tbox;
3132

33+
//! 统计
34+
struct Stat {
35+
size_t times = 0; //! 次数
36+
uint64_t dur_acc_us = 0; //! 累积时长
37+
uint64_t dur_min_us = std::numeric_limits<uint64_t>::max(); //! 最小时长
38+
uint64_t dur_max_us = 0; //! 最大时长
39+
uint64_t dur_max_ts_us = 0; //! 最大时长的时间点
40+
41+
uint64_t dur_avg_us = 0; //! 平均时长
42+
uint64_t dur_warn_line_us = 0; //! 警告水位线
43+
44+
uint64_t dur_warn_count = 0; //! 超过警告水位线次数
45+
};
46+
3247
using StringVec = std::vector<std::string>;
48+
using StatVec = std::vector<Stat>;
3349

3450
//! start_time_us, duration_us, name_index, module_index, thread_index
3551
using RecordHandleFunc = std::function<void(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t)>;
@@ -119,6 +135,33 @@ void ReadAllRecordFiles(const std::string &records_dir, const StringVec &record_
119135
ReadRecordFile(records_dir + '/' + record_file, func);
120136
}
121137

138+
void DumpStatToFile(const StringVec &name_vec, const StatVec &stat_vec, const std::string &stat_filename)
139+
{
140+
std::ofstream ofs(stat_filename);
141+
if (!ofs) {
142+
std::cout << "Error: open stat file '" << stat_filename << "' fail!" << std::endl;
143+
return;
144+
}
145+
146+
auto size = name_vec.size();
147+
for (size_t i = 0; i < size; ++i) {
148+
auto &name = name_vec.at(i);
149+
auto &stat = stat_vec.at(i);
150+
151+
ofs << std::string(name.size(), '=') << std::endl
152+
<< name << std::endl
153+
<< std::string(name.size(), '-') << std::endl
154+
<< "times : " << stat.times << std::endl
155+
<< "dur_min_us : " << stat.dur_min_us << " us" << std::endl
156+
<< "dur_avg_us : " << stat.dur_avg_us << " us" << std::endl
157+
<< "dur_max_us : " << stat.dur_max_us << " us" << std::endl
158+
<< "dur_max_at_us : " << stat.dur_max_ts_us << " us" << std::endl
159+
<< "dur_warn_line_us : " << stat.dur_warn_line_us << " us" << std::endl
160+
<< "dur_warn_count : " << stat.dur_warn_count << std::endl
161+
<< std::endl;
162+
}
163+
}
164+
122165
int main(int argc, char **argv)
123166
{
124167
if (argc < 2) {
@@ -146,6 +189,7 @@ int main(int argc, char **argv)
146189
std::string names_filename = dir_path + "/names.txt";
147190
std::string modules_filename = dir_path + "/modules.txt";
148191
std::string threads_filename = dir_path + "/threads.txt";
192+
149193
StringVec name_vec, module_vec, thread_vec;
150194
if (!util::fs::ReadAllLinesFromTextFile(names_filename, name_vec))
151195
std::cerr << "Warn: load names.txt fail!" << std::endl;
@@ -161,8 +205,11 @@ int main(int argc, char **argv)
161205
return 0;
162206
}
163207

208+
std::vector<Stat> stat_vec(name_vec.size());
209+
164210
writer.writeHeader();
165211

212+
//! 第一次遍历记录文件
166213
ReadAllRecordFiles(records_dir, record_file_name_vec,
167214
[&] (uint64_t start_ts_us, uint64_t duration_us, uint64_t name_index, uint64_t module_index, uint64_t thread_index) {
168215
std::string name = "unknown-name", thread = "unknown-thread", module = "unknown-module";
@@ -177,10 +224,60 @@ int main(int argc, char **argv)
177224
module = module_vec[module_index];
178225

179226
writer.writeRecorder(name, module, thread, start_ts_us, duration_us);
227+
228+
auto &stat = stat_vec.at(name_index);
229+
++stat.times;
230+
stat.dur_acc_us += duration_us;
231+
if (stat.dur_max_us < duration_us) {
232+
stat.dur_max_us = duration_us;
233+
stat.dur_max_ts_us = start_ts_us;
234+
}
235+
236+
if (stat.dur_min_us > duration_us) {
237+
stat.dur_min_us = duration_us;
238+
}
239+
}
240+
);
241+
242+
//! 处理统计数据
243+
for (auto &stat : stat_vec) {
244+
stat.dur_avg_us = stat.dur_acc_us / stat.times;
245+
stat.dur_warn_line_us = (stat.dur_avg_us + stat.dur_max_us) / 2;
246+
}
247+
248+
//! 第二次遍历记录文件,标出超出警告线的
249+
ReadAllRecordFiles(records_dir, record_file_name_vec,
250+
[&] (uint64_t start_ts_us, uint64_t duration_us, uint64_t name_index, uint64_t module_index, uint64_t) {
251+
auto &stat = stat_vec.at(name_index);
252+
if (duration_us < stat.dur_warn_line_us)
253+
return;
254+
255+
std::string name = "unknown-name", module = "unknown-module";
256+
257+
if (name_index < name_vec.size())
258+
name = name_vec[name_index];
259+
260+
if (module_index < module_vec.size())
261+
module = module_vec[module_index];
262+
263+
++stat.dur_warn_count;
264+
writer.writeRecorder(name, module, "WARN", start_ts_us, duration_us);
180265
}
181266
);
182267

268+
//! 标记出最大时间点
269+
auto size = name_vec.size();
270+
for (size_t i = 0; i < size; ++i) {
271+
auto &name = name_vec.at(i);
272+
auto &stat = stat_vec.at(i);
273+
writer.writeRecorder(name, "", "MAX", stat.dur_max_ts_us, stat.dur_max_us);
274+
}
275+
183276
writer.writeFooter();
277+
278+
//! 输出统计到 stat.txt
279+
std::string stat_filename = dir_path + "/stat.txt";
280+
DumpStatToFile(name_vec, stat_vec, stat_filename);
184281
return 0;
185282
}
186283

0 commit comments

Comments
 (0)