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 {
3939void 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+
268302Sink::Index Sink::allocThreadIndex (long thread_id)
269303{
270304 // ! 如果文件不存在了,则重写所有的线程列表
0 commit comments