Skip to content

Commit

Permalink
feat(trace): 实现在to_json的时候,输出统计数据,并标记较高耗时的事件时间点
Browse files Browse the repository at this point in the history
  • Loading branch information
hevake committed Jun 9, 2024
1 parent 11a81f3 commit 1d6dfd2
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 6 deletions.
9 changes: 3 additions & 6 deletions modules/trace/lib/sink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,7 @@ Sink::Index Sink::allocNameIndex(const std::string &name, uint32_t line)
{
//! 如果文件不存在了,则重写所有的名称列表
if (!util::fs::IsFileExist(name_list_filename_)) {
std::vector<std::string> name_vec;
name_vec.resize(name_to_index_map_.size());
std::vector<std::string> name_vec(name_to_index_map_.size());
for (auto &item : name_to_index_map_)
name_vec[item.second] = item.first;

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

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

Expand Down
97 changes: 97 additions & 0 deletions modules/trace/tools/to_json/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* of the source tree.
*/
#include <iostream>
#include <limits>

#include <tbox/util/fs.h>
#include <tbox/util/string.h>
Expand All @@ -29,7 +30,22 @@
using namespace std;
using namespace tbox;

//! 统计
struct Stat {
size_t times = 0; //! 次数
uint64_t dur_acc_us = 0; //! 累积时长
uint64_t dur_min_us = std::numeric_limits<uint64_t>::max(); //! 最小时长
uint64_t dur_max_us = 0; //! 最大时长
uint64_t dur_max_ts_us = 0; //! 最大时长的时间点

uint64_t dur_avg_us = 0; //! 平均时长
uint64_t dur_warn_line_us = 0; //! 警告水位线

uint64_t dur_warn_count = 0; //! 超过警告水位线次数
};

using StringVec = std::vector<std::string>;
using StatVec = std::vector<Stat>;

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

void DumpStatToFile(const StringVec &name_vec, const StatVec &stat_vec, const std::string &stat_filename)
{
std::ofstream ofs(stat_filename);
if (!ofs) {
std::cout << "Error: open stat file '" << stat_filename << "' fail!" << std::endl;
return;
}

auto size = name_vec.size();
for (size_t i = 0; i < size; ++i) {
auto &name = name_vec.at(i);
auto &stat = stat_vec.at(i);

ofs << std::string(name.size(), '=') << std::endl
<< name << std::endl
<< std::string(name.size(), '-') << std::endl
<< "times : " << stat.times << std::endl
<< "dur_min_us : " << stat.dur_min_us << " us" << std::endl
<< "dur_avg_us : " << stat.dur_avg_us << " us" << std::endl
<< "dur_max_us : " << stat.dur_max_us << " us" << std::endl
<< "dur_max_at_us : " << stat.dur_max_ts_us << " us" << std::endl
<< "dur_warn_line_us : " << stat.dur_warn_line_us << " us" << std::endl
<< "dur_warn_count : " << stat.dur_warn_count << std::endl
<< std::endl;
}
}

int main(int argc, char **argv)
{
if (argc < 2) {
Expand Down Expand Up @@ -146,6 +189,7 @@ int main(int argc, char **argv)
std::string names_filename = dir_path + "/names.txt";
std::string modules_filename = dir_path + "/modules.txt";
std::string threads_filename = dir_path + "/threads.txt";

StringVec name_vec, module_vec, thread_vec;
if (!util::fs::ReadAllLinesFromTextFile(names_filename, name_vec))
std::cerr << "Warn: load names.txt fail!" << std::endl;
Expand All @@ -161,8 +205,11 @@ int main(int argc, char **argv)
return 0;
}

std::vector<Stat> stat_vec(name_vec.size());

writer.writeHeader();

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

writer.writeRecorder(name, module, thread, start_ts_us, duration_us);

auto &stat = stat_vec.at(name_index);
++stat.times;
stat.dur_acc_us += duration_us;
if (stat.dur_max_us < duration_us) {
stat.dur_max_us = duration_us;
stat.dur_max_ts_us = start_ts_us;
}

if (stat.dur_min_us > duration_us) {
stat.dur_min_us = duration_us;
}
}
);

//! 处理统计数据
for (auto &stat : stat_vec) {
stat.dur_avg_us = stat.dur_acc_us / stat.times;
stat.dur_warn_line_us = (stat.dur_avg_us + stat.dur_max_us) / 2;
}

//! 第二次遍历记录文件,标出超出警告线的
ReadAllRecordFiles(records_dir, record_file_name_vec,
[&] (uint64_t start_ts_us, uint64_t duration_us, uint64_t name_index, uint64_t module_index, uint64_t) {
auto &stat = stat_vec.at(name_index);
if (duration_us < stat.dur_warn_line_us)
return;

std::string name = "unknown-name", module = "unknown-module";

if (name_index < name_vec.size())
name = name_vec[name_index];

if (module_index < module_vec.size())
module = module_vec[module_index];

++stat.dur_warn_count;
writer.writeRecorder(name, module, "WARN", start_ts_us, duration_us);
}
);

//! 标记出最大时间点
auto size = name_vec.size();
for (size_t i = 0; i < size; ++i) {
auto &name = name_vec.at(i);
auto &stat = stat_vec.at(i);
writer.writeRecorder(name, "", "MAX", stat.dur_max_ts_us, stat.dur_max_us);
}

writer.writeFooter();

//! 输出统计到 stat.txt
std::string stat_filename = dir_path + "/stat.txt";
DumpStatToFile(name_vec, stat_vec, stat_filename);
return 0;
}

0 comments on commit 1d6dfd2

Please sign in to comment.