Skip to content

Commit 91b8f1a

Browse files
committed
feat(trace):改进trace,使之支持module字段
1 parent 3c9c910 commit 91b8f1a

File tree

6 files changed

+110
-40
lines changed

6 files changed

+110
-40
lines changed

modules/trace/lib/sink.cpp

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@
2323
#include <fcntl.h>
2424

2525
#include <cstring>
26-
#include <iostream>
2726
#include <vector>
2827
#include <sstream>
2928

3029
#include <sys/syscall.h>
3130
#include <tbox/base/defines.h>
31+
#include <tbox/base/log.h>
3232
#include <tbox/util/fs.h>
3333
#include <tbox/util/string.h>
3434
#include <tbox/util/scalable_integer.h>
@@ -39,7 +39,7 @@ namespace trace {
3939
void CommitRecordFunc(const char *name, const char *module, uint32_t line,
4040
uint64_t end_timepoint_us, uint64_t duration_us)
4141
{
42-
Sink::GetInstance().commitRecord(name, line, end_timepoint_us, duration_us);
42+
Sink::GetInstance().commitRecord(name, module, line, end_timepoint_us, duration_us);
4343
}
4444

4545
#define ENDLINE "\n"
@@ -72,12 +72,13 @@ bool Sink::setPathPrefix(const std::string &path_prefix)
7272
auto striped_path_prefix = util::string::Strip(path_prefix);
7373

7474
if (striped_path_prefix.empty() || striped_path_prefix.back() == '/') {
75-
std::cerr << "Err: path_prefix '" << path_prefix << "' is invalid." << std::endl;
75+
LogWarn("path_prefix '%s' is invalid.", path_prefix.c_str());
7676
return false;
7777
}
7878

7979
dir_path_ = striped_path_prefix + '.' + GetLocalDateTimeStr() + '.' + std::to_string(::getpid());
8080
name_list_filename_ = dir_path_ + "/names.txt";
81+
module_list_filename_ = dir_path_ + "/modules.txt";
8182
thread_list_filename_ = dir_path_ + "/threads.txt";
8283
CHECK_CLOSE_RESET_FD(curr_record_fd_);
8384

@@ -96,7 +97,7 @@ bool Sink::enable()
9697
return true;
9798

9899
if (dir_path_.empty()) {
99-
std::cerr << "Warn: no path_prefix" << std::endl;
100+
LogWarn("path_prefix is empty, can't enable.");
100101
return false;
101102
}
102103

@@ -117,11 +118,10 @@ void Sink::disable()
117118
async_pipe_.cleanup();
118119
CHECK_CLOSE_RESET_FD(curr_record_fd_);
119120
buffer_.hasReadAll();
120-
curr_record_filename_.clear();
121121
}
122122
}
123123

124-
void Sink::commitRecord(const char *name, uint32_t line, uint64_t end_timepoint_us, uint64_t duration_us)
124+
void Sink::commitRecord(const char *name, const char *module, uint32_t line, uint64_t end_timepoint_us, uint64_t duration_us)
125125
{
126126
if (!is_enabled_)
127127
return;
@@ -131,12 +131,14 @@ void Sink::commitRecord(const char *name, uint32_t line, uint64_t end_timepoint_
131131
.end_ts_us = end_timepoint_us,
132132
.duration_us = duration_us,
133133
.line = line,
134-
.name_size = ::strlen(name) + 1
134+
.name_size = ::strlen(name) + 1,
135+
.module_size = ::strlen(module) + 1
135136
};
136137

137138
async_pipe_.appendLock();
138139
async_pipe_.appendLockless(&header, sizeof(header));
139140
async_pipe_.appendLockless(name, header.name_size);
141+
async_pipe_.appendLockless(module, header.module_size);
140142
async_pipe_.appendUnlock();
141143
}
142144

@@ -152,23 +154,27 @@ void Sink::onBackendRecvData(const void *data, size_t size)
152154
//! A: 因为直接指针引用会有对齐的问题。
153155

154156
//! 如果长度不够,就跳过,等下一次
155-
if ((header.name_size + sizeof(header)) > buffer_.readableSize())
157+
if ((header.name_size + header.module_size + sizeof(header)) > buffer_.readableSize())
156158
break;
157159

158160
buffer_.hasRead(sizeof(header));
159161

160-
onBackendRecvRecord(header, reinterpret_cast<const char*>(buffer_.readableBegin()));
161-
buffer_.hasRead(header.name_size);
162+
const char *name = reinterpret_cast<const char*>(buffer_.readableBegin());
163+
const char *module = name + header.name_size;
164+
onBackendRecvRecord(header, name, module);
165+
166+
buffer_.hasRead(header.name_size + header.module_size);
162167
}
163168
}
164169

165-
void Sink::onBackendRecvRecord(const RecordHeader &record, const char *name)
170+
void Sink::onBackendRecvRecord(const RecordHeader &record, const char *name, const char *module)
166171
{
167172
if (!checkAndCreateRecordFile())
168173
return;
169174

170175
auto thread_index = allocThreadIndex(record.thread_id);
171176
auto name_index = allocNameIndex(name, record.line);
177+
auto module_index = allocModuleIndex(module);
172178
auto time_diff = record.end_ts_us - last_timepoint_us_;
173179

174180
constexpr size_t kBufferSize = 40;
@@ -179,10 +185,11 @@ void Sink::onBackendRecvRecord(const RecordHeader &record, const char *name)
179185
data_size += util::DumpScalableInteger(record.duration_us, (buffer + data_size), (kBufferSize - data_size));
180186
data_size += util::DumpScalableInteger(thread_index, (buffer + data_size), (kBufferSize - data_size));
181187
data_size += util::DumpScalableInteger(name_index, (buffer + data_size), (kBufferSize - data_size));
188+
data_size += util::DumpScalableInteger(module_index, (buffer + data_size), (kBufferSize - data_size));
182189

183190
auto wsize = ::write(curr_record_fd_, buffer, data_size);
184191
if (wsize != static_cast<ssize_t>(data_size)) {
185-
std::cerr << "Err: write file error" << std::endl;
192+
LogErrno(errno, "write record file '%s' fail", curr_record_filename_.c_str());
186193
return;
187194
}
188195

@@ -205,7 +212,7 @@ bool Sink::checkAndCreateRecordFile()
205212

206213
//!检查并创建路径
207214
if (!util::fs::MakeDirectory(records_path, false)) {
208-
std::cerr << "Err: create director " << records_path << " fail. error:" << errno << ',' << strerror(errno) << std::endl;
215+
LogErrno(errno, "create directory '%s' fail", records_path);
209216
return false;
210217
}
211218

@@ -228,7 +235,7 @@ bool Sink::checkAndCreateRecordFile()
228235

229236
curr_record_fd_ = ::open(curr_record_filename_.c_str(), flags, S_IRUSR | S_IWUSR);
230237
if (curr_record_fd_ < 0) {
231-
std::cerr << "Err: open file " << curr_record_filename_ << " fail. error:" << errno << ',' << strerror(errno) << std::endl;
238+
LogErrno(errno, "open record file '%s' fail", curr_record_filename_.c_str());
232239
return false;
233240
}
234241

@@ -265,6 +272,33 @@ Sink::Index Sink::allocNameIndex(const std::string &name, uint32_t line)
265272
return new_index;
266273
}
267274

275+
Sink::Index Sink::allocModuleIndex(const std::string &module)
276+
{
277+
//! 如果文件不存在了,则重写所有的名称列表
278+
if (!util::fs::IsFileExist(module_list_filename_)) {
279+
std::vector<std::string> module_vec;
280+
module_vec.resize(module_to_index_map_.size());
281+
for (auto &item : module_to_index_map_)
282+
module_vec[item.second] = item.first;
283+
284+
std::ostringstream oss;
285+
for (auto &module : module_vec)
286+
oss << module << ENDLINE;
287+
288+
util::fs::WriteStringToTextFile(module_list_filename_, oss.str(), is_file_sync_enabled_);
289+
}
290+
291+
auto iter = module_to_index_map_.find(module);
292+
if (iter != module_to_index_map_.end())
293+
return iter->second;
294+
295+
auto new_index = next_module_index_++;
296+
module_to_index_map_[module] = new_index;
297+
298+
util::fs::AppendStringToTextFile(module_list_filename_, module + ENDLINE, is_file_sync_enabled_);
299+
return new_index;
300+
}
301+
268302
Sink::Index Sink::allocThreadIndex(long thread_id)
269303
{
270304
//! 如果文件不存在了,则重写所有的线程列表

modules/trace/lib/sink.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class Sink {
4444
* 目录结构:
4545
* .
4646
* |-- names.txt # 函数名列表
47+
* |-- modules.txt # 模块名列表
4748
* |-- threads.txt # 线程名列表
4849
* `-- records # 记录文件目录,其下存在一个或多个记录文件
4950
* `-- 20240530_041046.bin
@@ -76,7 +77,7 @@ class Sink {
7677
* \param end_ts 记录结束的时间点,单位: us
7778
* \param duration_us 记录持续时长,单位:us
7879
*/
79-
void commitRecord(const char *name, uint32_t line, uint64_t end_timepoint_us, uint64_t duration_us);
80+
void commitRecord(const char *name, const char *module, uint32_t line, uint64_t end_timepoint_us, uint64_t duration_us);
8081

8182
protected:
8283
~Sink();
@@ -87,22 +88,25 @@ class Sink {
8788
uint64_t duration_us;
8889
uint32_t line;
8990
size_t name_size;
91+
size_t module_size;
9092
};
9193

9294
using Index = uint64_t;
9395

9496
void onBackendRecvData(const void *data, size_t size);
95-
void onBackendRecvRecord(const RecordHeader &record, const char *name);
97+
void onBackendRecvRecord(const RecordHeader &record, const char *name, const char *module);
9698

9799
bool checkAndCreateRecordFile();
98100

99101
Index allocNameIndex(const std::string &name, uint32_t line);
102+
Index allocModuleIndex(const std::string &module);
100103
Index allocThreadIndex(long thread_id);
101104

102105
private:
103106
std::string dir_path_;
104107
size_t record_file_max_size_ = std::numeric_limits<size_t>::max();
105108
std::string name_list_filename_;
109+
std::string module_list_filename_;
106110
std::string thread_list_filename_;
107111
bool is_file_sync_enabled_ = false;
108112

@@ -120,6 +124,9 @@ class Sink {
120124
//! 名称编码
121125
std::map<std::string, Index> name_to_index_map_;
122126
uint32_t next_name_index_ = 0;
127+
//! 模块编码
128+
std::map<std::string, Index> module_to_index_map_;
129+
uint32_t next_module_index_ = 0;
123130
//! 线程号编码
124131
std::map<long, Index> thread_to_index_map_;
125132
int next_thread_index_ = 0;

modules/trace/lib/sink_test.cpp

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#include <sys/syscall.h>
2323
#include <thread>
2424

25+
#include <tbox/base/log.h>
26+
#include <tbox/base/log_output.h>
2527
#include <tbox/util/fs.h>
2628
#include <tbox/util/string.h>
2729
#include <tbox/util/timestamp.h>
@@ -38,44 +40,53 @@ TEST(Sink, Base) {
3840
ts.setPathPrefix(path_prefix);
3941

4042
ts.enable();
41-
ts.commitRecord("void hello()", 1, 100, 10);
42-
ts.commitRecord("int world(int, std::string)", 2, 101, 1);
43-
ts.commitRecord("void hello()", 1, 200, 10);
44-
ts.commitRecord("bool bye(double)", 3, 201, 100);
43+
ts.commitRecord("void hello()", "a", 1, 100, 10);
44+
ts.commitRecord("int world(int, std::string)", "a", 2, 101, 1);
45+
ts.commitRecord("void hello()", "b", 1, 200, 10);
46+
ts.commitRecord("bool bye(double)", "b", 3, 201, 100);
4547
ts.disable();
4648

4749
std::string path = ts.getDirPath();
48-
std::string name_list_filename = path + "/name_list.txt";
49-
std::string thread_list_filename = path + "/thread_list.txt";
50+
std::string name_list_filename = path + "/names.txt";
51+
std::string thread_list_filename = path + "/threads.txt";
52+
std::string module_list_filename = path + "/modules.txt";
5053
std::string record_filename = ts.getCurrRecordFilename();
5154

5255
ASSERT_TRUE(util::fs::IsFileExist(name_list_filename));
5356
ASSERT_TRUE(util::fs::IsFileExist(thread_list_filename));
57+
ASSERT_TRUE(util::fs::IsFileExist(module_list_filename));
5458
ASSERT_TRUE(util::fs::IsFileExist(record_filename));
5559

5660
{
5761
std::string name_list_content;
5862
ASSERT_TRUE(util::fs::ReadStringFromTextFile(name_list_filename, name_list_content));
59-
std::string target_content = "void hello() at L1\r\nint world(int, std::string) at L2\r\nbool bye(double) at L3\r\n";
63+
std::string target_content = "void hello() at L1\nint world(int, std::string) at L2\nbool bye(double) at L3\n";
6064
EXPECT_EQ(name_list_content, target_content);
6165
}
6266

67+
{
68+
std::string module_list_content;
69+
ASSERT_TRUE(util::fs::ReadStringFromTextFile(module_list_filename, module_list_content));
70+
std::string target_content = "a\nb\n";
71+
EXPECT_EQ(module_list_content, target_content);
72+
}
73+
6374
{
6475
std::string thread_list_content;
6576
ASSERT_TRUE(util::fs::ReadStringFromTextFile(thread_list_filename, thread_list_content));
66-
std::string target_content = std::to_string(::syscall(SYS_gettid)) + "\r\n";
77+
std::string target_content = std::to_string(::syscall(SYS_gettid)) + "\n";
6778
EXPECT_EQ(thread_list_content, target_content);
6879
}
6980

7081
{
7182
std::string first_record_content;
7283
ASSERT_TRUE(util::fs::ReadBinaryFromFile(record_filename, first_record_content));
7384
auto first_record_content_hex = util::string::RawDataToHexStr(first_record_content.data(), first_record_content.size());
74-
std::string target_content = "64 0a 00 00 01 01 00 01 63 0a 00 00 01 64 00 02";
85+
std::string target_content = "64 0a 00 00 00 01 01 00 01 00 63 0a 00 00 01 01 64 00 02 01";
7586
EXPECT_EQ(first_record_content_hex, target_content);
7687
}
7788

78-
//util::fs::RemoveDirectory("/tmp/cpp-tbox-test");
89+
util::fs::RemoveDirectory("/tmp/cpp-tbox-test");
7990
}
8091

8192
TEST(Sink, MultiThread) {
@@ -87,7 +98,7 @@ TEST(Sink, MultiThread) {
8798

8899
auto test_func = [&ts] (const std::string name) {
89100
for (int i = 0; i < 1000; ++i) {
90-
ts.commitRecord(name.c_str(), 100, util::GetCurrentMicrosecondsFrom1970(), 10);
101+
ts.commitRecord(name.c_str(), "A", 100, util::GetCurrentMicrosecondsFrom1970(), 10);
91102
}
92103
};
93104

@@ -98,7 +109,7 @@ TEST(Sink, MultiThread) {
98109
ts.disable();
99110

100111
//!TODO: 检查记录和条数是否有2000条
101-
//util::fs::RemoveDirectory("/tmp/cpp-tbox-test");
112+
util::fs::RemoveDirectory("/tmp/cpp-tbox-test");
102113
}
103114

104115
}

0 commit comments

Comments
 (0)