file_system_tracer.cc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  1. // Copyright (c) 2019-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. #include "env/file_system_tracer.h"
  6. #include "rocksdb/file_system.h"
  7. #include "rocksdb/system_clock.h"
  8. #include "rocksdb/trace_record.h"
  9. namespace ROCKSDB_NAMESPACE {
  10. IOStatus FileSystemTracingWrapper::NewSequentialFile(
  11. const std::string& fname, const FileOptions& file_opts,
  12. std::unique_ptr<FSSequentialFile>* result, IODebugContext* dbg) {
  13. StopWatchNano timer(clock_);
  14. timer.Start();
  15. IOStatus s = target()->NewSequentialFile(fname, file_opts, result, dbg);
  16. uint64_t elapsed = timer.ElapsedNanos();
  17. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer,
  18. 0 /*io_op_data*/, __func__, elapsed, s.ToString(),
  19. fname.substr(fname.find_last_of("/\\") + 1));
  20. io_tracer_->WriteIOOp(io_record, dbg);
  21. return s;
  22. }
  23. IOStatus FileSystemTracingWrapper::NewRandomAccessFile(
  24. const std::string& fname, const FileOptions& file_opts,
  25. std::unique_ptr<FSRandomAccessFile>* result, IODebugContext* dbg) {
  26. StopWatchNano timer(clock_);
  27. timer.Start();
  28. IOStatus s = target()->NewRandomAccessFile(fname, file_opts, result, dbg);
  29. uint64_t elapsed = timer.ElapsedNanos();
  30. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer,
  31. 0 /*io_op_data*/, __func__, elapsed, s.ToString(),
  32. fname.substr(fname.find_last_of("/\\") + 1));
  33. io_tracer_->WriteIOOp(io_record, dbg);
  34. return s;
  35. }
  36. IOStatus FileSystemTracingWrapper::NewWritableFile(
  37. const std::string& fname, const FileOptions& file_opts,
  38. std::unique_ptr<FSWritableFile>* result, IODebugContext* dbg) {
  39. StopWatchNano timer(clock_);
  40. timer.Start();
  41. IOStatus s = target()->NewWritableFile(fname, file_opts, result, dbg);
  42. uint64_t elapsed = timer.ElapsedNanos();
  43. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer,
  44. 0 /*io_op_data*/, __func__, elapsed, s.ToString(),
  45. fname.substr(fname.find_last_of("/\\") + 1));
  46. io_tracer_->WriteIOOp(io_record, dbg);
  47. return s;
  48. }
  49. IOStatus FileSystemTracingWrapper::ReopenWritableFile(
  50. const std::string& fname, const FileOptions& file_opts,
  51. std::unique_ptr<FSWritableFile>* result, IODebugContext* dbg) {
  52. StopWatchNano timer(clock_);
  53. timer.Start();
  54. IOStatus s = target()->ReopenWritableFile(fname, file_opts, result, dbg);
  55. uint64_t elapsed = timer.ElapsedNanos();
  56. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer,
  57. 0 /*io_op_data*/, __func__, elapsed, s.ToString(),
  58. fname.substr(fname.find_last_of("/\\") + 1));
  59. io_tracer_->WriteIOOp(io_record, dbg);
  60. return s;
  61. }
  62. IOStatus FileSystemTracingWrapper::ReuseWritableFile(
  63. const std::string& fname, const std::string& old_fname,
  64. const FileOptions& file_opts, std::unique_ptr<FSWritableFile>* result,
  65. IODebugContext* dbg) {
  66. StopWatchNano timer(clock_);
  67. timer.Start();
  68. IOStatus s =
  69. target()->ReuseWritableFile(fname, old_fname, file_opts, result, dbg);
  70. uint64_t elapsed = timer.ElapsedNanos();
  71. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer,
  72. 0 /*io_op_data*/, __func__, elapsed, s.ToString(),
  73. fname.substr(fname.find_last_of("/\\") + 1));
  74. io_tracer_->WriteIOOp(io_record, dbg);
  75. return s;
  76. }
  77. IOStatus FileSystemTracingWrapper::NewRandomRWFile(
  78. const std::string& fname, const FileOptions& file_opts,
  79. std::unique_ptr<FSRandomRWFile>* result, IODebugContext* dbg) {
  80. StopWatchNano timer(clock_);
  81. timer.Start();
  82. IOStatus s = target()->NewRandomRWFile(fname, file_opts, result, dbg);
  83. uint64_t elapsed = timer.ElapsedNanos();
  84. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer,
  85. 0 /*io_op_data*/, __func__, elapsed, s.ToString(),
  86. fname.substr(fname.find_last_of("/\\") + 1));
  87. io_tracer_->WriteIOOp(io_record, dbg);
  88. return s;
  89. }
  90. IOStatus FileSystemTracingWrapper::NewDirectory(
  91. const std::string& name, const IOOptions& io_opts,
  92. std::unique_ptr<FSDirectory>* result, IODebugContext* dbg) {
  93. StopWatchNano timer(clock_);
  94. timer.Start();
  95. IOStatus s = target()->NewDirectory(name, io_opts, result, dbg);
  96. uint64_t elapsed = timer.ElapsedNanos();
  97. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer,
  98. 0 /*io_op_data*/, __func__, elapsed, s.ToString(),
  99. name.substr(name.find_last_of("/\\") + 1));
  100. io_tracer_->WriteIOOp(io_record, dbg);
  101. return s;
  102. }
  103. IOStatus FileSystemTracingWrapper::GetChildren(const std::string& dir,
  104. const IOOptions& io_opts,
  105. std::vector<std::string>* r,
  106. IODebugContext* dbg) {
  107. StopWatchNano timer(clock_);
  108. timer.Start();
  109. IOStatus s = target()->GetChildren(dir, io_opts, r, dbg);
  110. uint64_t elapsed = timer.ElapsedNanos();
  111. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer,
  112. 0 /*io_op_data*/, __func__, elapsed, s.ToString(),
  113. dir.substr(dir.find_last_of("/\\") + 1));
  114. io_tracer_->WriteIOOp(io_record, dbg);
  115. return s;
  116. }
  117. IOStatus FileSystemTracingWrapper::DeleteFile(const std::string& fname,
  118. const IOOptions& options,
  119. IODebugContext* dbg) {
  120. StopWatchNano timer(clock_);
  121. timer.Start();
  122. IOStatus s = target()->DeleteFile(fname, options, dbg);
  123. uint64_t elapsed = timer.ElapsedNanos();
  124. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer,
  125. 0 /*io_op_data*/, __func__, elapsed, s.ToString(),
  126. fname.substr(fname.find_last_of("/\\") + 1));
  127. io_tracer_->WriteIOOp(io_record, dbg);
  128. return s;
  129. }
  130. IOStatus FileSystemTracingWrapper::CreateDir(const std::string& dirname,
  131. const IOOptions& options,
  132. IODebugContext* dbg) {
  133. StopWatchNano timer(clock_);
  134. timer.Start();
  135. IOStatus s = target()->CreateDir(dirname, options, dbg);
  136. uint64_t elapsed = timer.ElapsedNanos();
  137. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer,
  138. 0 /*io_op_data*/, __func__, elapsed, s.ToString(),
  139. dirname.substr(dirname.find_last_of("/\\") + 1));
  140. io_tracer_->WriteIOOp(io_record, dbg);
  141. return s;
  142. }
  143. IOStatus FileSystemTracingWrapper::CreateDirIfMissing(
  144. const std::string& dirname, const IOOptions& options, IODebugContext* dbg) {
  145. StopWatchNano timer(clock_);
  146. timer.Start();
  147. IOStatus s = target()->CreateDirIfMissing(dirname, options, dbg);
  148. uint64_t elapsed = timer.ElapsedNanos();
  149. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer,
  150. 0 /*io_op_data*/, __func__, elapsed, s.ToString(),
  151. dirname.substr(dirname.find_last_of("/\\") + 1));
  152. io_tracer_->WriteIOOp(io_record, dbg);
  153. return s;
  154. }
  155. IOStatus FileSystemTracingWrapper::DeleteDir(const std::string& dirname,
  156. const IOOptions& options,
  157. IODebugContext* dbg) {
  158. StopWatchNano timer(clock_);
  159. timer.Start();
  160. IOStatus s = target()->DeleteDir(dirname, options, dbg);
  161. uint64_t elapsed = timer.ElapsedNanos();
  162. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer,
  163. 0 /*io_op_data*/, __func__, elapsed, s.ToString(),
  164. dirname.substr(dirname.find_last_of("/\\") + 1));
  165. io_tracer_->WriteIOOp(io_record, dbg);
  166. return s;
  167. }
  168. IOStatus FileSystemTracingWrapper::GetFileSize(const std::string& fname,
  169. const IOOptions& options,
  170. uint64_t* file_size,
  171. IODebugContext* dbg) {
  172. StopWatchNano timer(clock_);
  173. timer.Start();
  174. IOStatus s = target()->GetFileSize(fname, options, file_size, dbg);
  175. uint64_t elapsed = timer.ElapsedNanos();
  176. uint64_t io_op_data = 0;
  177. io_op_data |= (1 << IOTraceOp::kIOFileSize);
  178. IOTraceRecord io_record(
  179. clock_->NowNanos(), TraceType::kIOTracer, io_op_data, __func__, elapsed,
  180. s.ToString(), fname.substr(fname.find_last_of("/\\") + 1), *file_size);
  181. io_tracer_->WriteIOOp(io_record, dbg);
  182. return s;
  183. }
  184. IOStatus FileSystemTracingWrapper::Truncate(const std::string& fname,
  185. size_t size,
  186. const IOOptions& options,
  187. IODebugContext* dbg) {
  188. StopWatchNano timer(clock_);
  189. timer.Start();
  190. IOStatus s = target()->Truncate(fname, size, options, dbg);
  191. uint64_t elapsed = timer.ElapsedNanos();
  192. uint64_t io_op_data = 0;
  193. io_op_data |= (1 << IOTraceOp::kIOFileSize);
  194. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer, io_op_data,
  195. __func__, elapsed, s.ToString(),
  196. fname.substr(fname.find_last_of("/\\") + 1), size);
  197. io_tracer_->WriteIOOp(io_record, dbg);
  198. return s;
  199. }
  200. IOStatus FSSequentialFileTracingWrapper::Read(size_t n,
  201. const IOOptions& options,
  202. Slice* result, char* scratch,
  203. IODebugContext* dbg) {
  204. StopWatchNano timer(clock_);
  205. timer.Start();
  206. IOStatus s = target()->Read(n, options, result, scratch, dbg);
  207. uint64_t elapsed = timer.ElapsedNanos();
  208. uint64_t io_op_data = 0;
  209. io_op_data |= (1 << IOTraceOp::kIOLen);
  210. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer, io_op_data,
  211. __func__, elapsed, s.ToString(), file_name_,
  212. result->size(), 0 /*Offset*/);
  213. io_tracer_->WriteIOOp(io_record, dbg);
  214. return s;
  215. }
  216. IOStatus FSSequentialFileTracingWrapper::InvalidateCache(size_t offset,
  217. size_t length) {
  218. StopWatchNano timer(clock_);
  219. timer.Start();
  220. IOStatus s = target()->InvalidateCache(offset, length);
  221. uint64_t elapsed = timer.ElapsedNanos();
  222. uint64_t io_op_data = 0;
  223. io_op_data |= (1 << IOTraceOp::kIOLen);
  224. io_op_data |= (1 << IOTraceOp::kIOOffset);
  225. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer, io_op_data,
  226. __func__, elapsed, s.ToString(), file_name_, length,
  227. offset);
  228. io_tracer_->WriteIOOp(io_record, nullptr /*dbg*/);
  229. return s;
  230. }
  231. IOStatus FSSequentialFileTracingWrapper::PositionedRead(
  232. uint64_t offset, size_t n, const IOOptions& options, Slice* result,
  233. char* scratch, IODebugContext* dbg) {
  234. StopWatchNano timer(clock_);
  235. timer.Start();
  236. IOStatus s =
  237. target()->PositionedRead(offset, n, options, result, scratch, dbg);
  238. uint64_t elapsed = timer.ElapsedNanos();
  239. uint64_t io_op_data = 0;
  240. io_op_data |= (1 << IOTraceOp::kIOLen);
  241. io_op_data |= (1 << IOTraceOp::kIOOffset);
  242. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer, io_op_data,
  243. __func__, elapsed, s.ToString(), file_name_,
  244. result->size(), offset);
  245. io_tracer_->WriteIOOp(io_record, dbg);
  246. return s;
  247. }
  248. IOStatus FSRandomAccessFileTracingWrapper::Read(uint64_t offset, size_t n,
  249. const IOOptions& options,
  250. Slice* result, char* scratch,
  251. IODebugContext* dbg) const {
  252. StopWatchNano timer(clock_);
  253. timer.Start();
  254. IOStatus s = target()->Read(offset, n, options, result, scratch, dbg);
  255. uint64_t elapsed = timer.ElapsedNanos();
  256. uint64_t io_op_data = 0;
  257. io_op_data |= (1 << IOTraceOp::kIOLen);
  258. io_op_data |= (1 << IOTraceOp::kIOOffset);
  259. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer, io_op_data,
  260. __func__, elapsed, s.ToString(), file_name_, n,
  261. offset);
  262. io_tracer_->WriteIOOp(io_record, dbg);
  263. return s;
  264. }
  265. IOStatus FSRandomAccessFileTracingWrapper::MultiRead(FSReadRequest* reqs,
  266. size_t num_reqs,
  267. const IOOptions& options,
  268. IODebugContext* dbg) {
  269. StopWatchNano timer(clock_);
  270. timer.Start();
  271. IOStatus s = target()->MultiRead(reqs, num_reqs, options, dbg);
  272. uint64_t elapsed = timer.ElapsedNanos();
  273. uint64_t latency = elapsed;
  274. uint64_t io_op_data = 0;
  275. io_op_data |= (1 << IOTraceOp::kIOLen);
  276. io_op_data |= (1 << IOTraceOp::kIOOffset);
  277. for (size_t i = 0; i < num_reqs; i++) {
  278. IOTraceRecord io_record(
  279. clock_->NowNanos(), TraceType::kIOTracer, io_op_data, __func__, latency,
  280. reqs[i].status.ToString(), file_name_, reqs[i].len, reqs[i].offset);
  281. io_tracer_->WriteIOOp(io_record, dbg);
  282. }
  283. return s;
  284. }
  285. IOStatus FSRandomAccessFileTracingWrapper::Prefetch(uint64_t offset, size_t n,
  286. const IOOptions& options,
  287. IODebugContext* dbg) {
  288. StopWatchNano timer(clock_);
  289. timer.Start();
  290. IOStatus s = target()->Prefetch(offset, n, options, dbg);
  291. uint64_t elapsed = timer.ElapsedNanos();
  292. uint64_t io_op_data = 0;
  293. io_op_data |= (1 << IOTraceOp::kIOLen);
  294. io_op_data |= (1 << IOTraceOp::kIOOffset);
  295. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer, io_op_data,
  296. __func__, elapsed, s.ToString(), file_name_, n,
  297. offset);
  298. io_tracer_->WriteIOOp(io_record, dbg);
  299. return s;
  300. }
  301. IOStatus FSRandomAccessFileTracingWrapper::InvalidateCache(size_t offset,
  302. size_t length) {
  303. StopWatchNano timer(clock_);
  304. timer.Start();
  305. IOStatus s = target()->InvalidateCache(offset, length);
  306. uint64_t elapsed = timer.ElapsedNanos();
  307. uint64_t io_op_data = 0;
  308. io_op_data |= (1 << IOTraceOp::kIOLen);
  309. io_op_data |= (1 << IOTraceOp::kIOOffset);
  310. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer, io_op_data,
  311. __func__, elapsed, s.ToString(), file_name_, length,
  312. static_cast<uint64_t>(offset));
  313. io_tracer_->WriteIOOp(io_record, nullptr /*dbg*/);
  314. return s;
  315. }
  316. IOStatus FSRandomAccessFileTracingWrapper::ReadAsync(
  317. FSReadRequest& req, const IOOptions& opts,
  318. std::function<void(FSReadRequest&, void*)> cb, void* cb_arg,
  319. void** io_handle, IOHandleDeleter* del_fn, IODebugContext* dbg) {
  320. // Create a callback and populate info.
  321. auto read_async_callback =
  322. std::bind(&FSRandomAccessFileTracingWrapper::ReadAsyncCallback, this,
  323. std::placeholders::_1, std::placeholders::_2);
  324. ReadAsyncCallbackInfo* read_async_cb_info = new ReadAsyncCallbackInfo;
  325. read_async_cb_info->cb_ = cb;
  326. read_async_cb_info->cb_arg_ = cb_arg;
  327. read_async_cb_info->start_time_ = clock_->NowNanos();
  328. read_async_cb_info->file_op_ = __func__;
  329. IOStatus s = target()->ReadAsync(req, opts, read_async_callback,
  330. read_async_cb_info, io_handle, del_fn, dbg);
  331. #ifndef __clang_analyzer__
  332. if (!s.ok()) {
  333. delete read_async_cb_info;
  334. }
  335. #endif // __clang_analyzer__
  336. return s;
  337. }
  338. void FSRandomAccessFileTracingWrapper::ReadAsyncCallback(FSReadRequest& req,
  339. void* cb_arg) {
  340. ReadAsyncCallbackInfo* read_async_cb_info =
  341. static_cast<ReadAsyncCallbackInfo*>(cb_arg);
  342. assert(read_async_cb_info);
  343. assert(read_async_cb_info->cb_);
  344. uint64_t elapsed = clock_->NowNanos() - read_async_cb_info->start_time_;
  345. uint64_t io_op_data = 0;
  346. io_op_data |= (1 << IOTraceOp::kIOLen);
  347. io_op_data |= (1 << IOTraceOp::kIOOffset);
  348. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer, io_op_data,
  349. read_async_cb_info->file_op_, elapsed,
  350. req.status.ToString(), file_name_, req.result.size(),
  351. req.offset);
  352. io_tracer_->WriteIOOp(io_record, nullptr /*dbg*/);
  353. // call the underlying callback.
  354. read_async_cb_info->cb_(req, read_async_cb_info->cb_arg_);
  355. delete read_async_cb_info;
  356. }
  357. IOStatus FSWritableFileTracingWrapper::Append(const Slice& data,
  358. const IOOptions& options,
  359. IODebugContext* dbg) {
  360. StopWatchNano timer(clock_);
  361. timer.Start();
  362. IOStatus s = target()->Append(data, options, dbg);
  363. uint64_t elapsed = timer.ElapsedNanos();
  364. uint64_t io_op_data = 0;
  365. io_op_data |= (1 << IOTraceOp::kIOLen);
  366. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer, io_op_data,
  367. __func__, elapsed, s.ToString(), file_name_,
  368. data.size(), 0 /*Offset*/);
  369. io_tracer_->WriteIOOp(io_record, dbg);
  370. return s;
  371. }
  372. IOStatus FSWritableFileTracingWrapper::PositionedAppend(
  373. const Slice& data, uint64_t offset, const IOOptions& options,
  374. IODebugContext* dbg) {
  375. StopWatchNano timer(clock_);
  376. timer.Start();
  377. IOStatus s = target()->PositionedAppend(data, offset, options, dbg);
  378. uint64_t elapsed = timer.ElapsedNanos();
  379. uint64_t io_op_data = 0;
  380. io_op_data |= (1 << IOTraceOp::kIOLen);
  381. io_op_data |= (1 << IOTraceOp::kIOOffset);
  382. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer, io_op_data,
  383. __func__, elapsed, s.ToString(), file_name_,
  384. data.size(), offset);
  385. io_tracer_->WriteIOOp(io_record, dbg);
  386. return s;
  387. }
  388. IOStatus FSWritableFileTracingWrapper::Truncate(uint64_t size,
  389. const IOOptions& options,
  390. IODebugContext* dbg) {
  391. StopWatchNano timer(clock_);
  392. timer.Start();
  393. IOStatus s = target()->Truncate(size, options, dbg);
  394. uint64_t elapsed = timer.ElapsedNanos();
  395. uint64_t io_op_data = 0;
  396. io_op_data |= (1 << IOTraceOp::kIOLen);
  397. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer, io_op_data,
  398. __func__, elapsed, s.ToString(), file_name_, size,
  399. 0 /*Offset*/);
  400. io_tracer_->WriteIOOp(io_record, dbg);
  401. return s;
  402. }
  403. IOStatus FSWritableFileTracingWrapper::Close(const IOOptions& options,
  404. IODebugContext* dbg) {
  405. StopWatchNano timer(clock_);
  406. timer.Start();
  407. IOStatus s = target()->Close(options, dbg);
  408. uint64_t elapsed = timer.ElapsedNanos();
  409. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer,
  410. 0 /*io_op_data*/, __func__, elapsed, s.ToString(),
  411. file_name_);
  412. io_tracer_->WriteIOOp(io_record, dbg);
  413. return s;
  414. }
  415. uint64_t FSWritableFileTracingWrapper::GetFileSize(const IOOptions& options,
  416. IODebugContext* dbg) {
  417. StopWatchNano timer(clock_);
  418. timer.Start();
  419. uint64_t file_size = target()->GetFileSize(options, dbg);
  420. uint64_t elapsed = timer.ElapsedNanos();
  421. uint64_t io_op_data = 0;
  422. io_op_data |= (1 << IOTraceOp::kIOFileSize);
  423. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer, io_op_data,
  424. __func__, elapsed, "OK", file_name_, file_size);
  425. io_tracer_->WriteIOOp(io_record, dbg);
  426. return file_size;
  427. }
  428. IOStatus FSWritableFileTracingWrapper::InvalidateCache(size_t offset,
  429. size_t length) {
  430. StopWatchNano timer(clock_);
  431. timer.Start();
  432. IOStatus s = target()->InvalidateCache(offset, length);
  433. uint64_t elapsed = timer.ElapsedNanos();
  434. uint64_t io_op_data = 0;
  435. io_op_data |= (1 << IOTraceOp::kIOLen);
  436. io_op_data |= (1 << IOTraceOp::kIOOffset);
  437. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer, io_op_data,
  438. __func__, elapsed, s.ToString(), file_name_, length,
  439. static_cast<uint64_t>(offset));
  440. io_tracer_->WriteIOOp(io_record, nullptr /*dbg*/);
  441. return s;
  442. }
  443. IOStatus FSRandomRWFileTracingWrapper::Write(uint64_t offset, const Slice& data,
  444. const IOOptions& options,
  445. IODebugContext* dbg) {
  446. StopWatchNano timer(clock_);
  447. timer.Start();
  448. IOStatus s = target()->Write(offset, data, options, dbg);
  449. uint64_t elapsed = timer.ElapsedNanos();
  450. uint64_t io_op_data = 0;
  451. io_op_data |= (1 << IOTraceOp::kIOLen);
  452. io_op_data |= (1 << IOTraceOp::kIOOffset);
  453. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer, io_op_data,
  454. __func__, elapsed, s.ToString(), file_name_,
  455. data.size(), offset);
  456. io_tracer_->WriteIOOp(io_record, dbg);
  457. return s;
  458. }
  459. IOStatus FSRandomRWFileTracingWrapper::Read(uint64_t offset, size_t n,
  460. const IOOptions& options,
  461. Slice* result, char* scratch,
  462. IODebugContext* dbg) const {
  463. StopWatchNano timer(clock_);
  464. timer.Start();
  465. IOStatus s = target()->Read(offset, n, options, result, scratch, dbg);
  466. uint64_t elapsed = timer.ElapsedNanos();
  467. uint64_t io_op_data = 0;
  468. io_op_data |= (1 << IOTraceOp::kIOLen);
  469. io_op_data |= (1 << IOTraceOp::kIOOffset);
  470. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer, io_op_data,
  471. __func__, elapsed, s.ToString(), file_name_, n,
  472. offset);
  473. io_tracer_->WriteIOOp(io_record, dbg);
  474. return s;
  475. }
  476. IOStatus FSRandomRWFileTracingWrapper::Flush(const IOOptions& options,
  477. IODebugContext* dbg) {
  478. StopWatchNano timer(clock_);
  479. timer.Start();
  480. IOStatus s = target()->Flush(options, dbg);
  481. uint64_t elapsed = timer.ElapsedNanos();
  482. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer,
  483. 0 /*io_op_data*/, __func__, elapsed, s.ToString(),
  484. file_name_);
  485. io_tracer_->WriteIOOp(io_record, dbg);
  486. return s;
  487. }
  488. IOStatus FSRandomRWFileTracingWrapper::Close(const IOOptions& options,
  489. IODebugContext* dbg) {
  490. StopWatchNano timer(clock_);
  491. timer.Start();
  492. IOStatus s = target()->Close(options, dbg);
  493. uint64_t elapsed = timer.ElapsedNanos();
  494. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer,
  495. 0 /*io_op_data*/, __func__, elapsed, s.ToString(),
  496. file_name_);
  497. io_tracer_->WriteIOOp(io_record, dbg);
  498. return s;
  499. }
  500. IOStatus FSRandomRWFileTracingWrapper::Sync(const IOOptions& options,
  501. IODebugContext* dbg) {
  502. StopWatchNano timer(clock_);
  503. timer.Start();
  504. IOStatus s = target()->Sync(options, dbg);
  505. uint64_t elapsed = timer.ElapsedNanos();
  506. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer,
  507. 0 /*io_op_data*/, __func__, elapsed, s.ToString(),
  508. file_name_);
  509. io_tracer_->WriteIOOp(io_record, dbg);
  510. return s;
  511. }
  512. IOStatus FSRandomRWFileTracingWrapper::Fsync(const IOOptions& options,
  513. IODebugContext* dbg) {
  514. StopWatchNano timer(clock_);
  515. timer.Start();
  516. IOStatus s = target()->Fsync(options, dbg);
  517. uint64_t elapsed = timer.ElapsedNanos();
  518. IOTraceRecord io_record(clock_->NowNanos(), TraceType::kIOTracer,
  519. 0 /*io_op_data*/, __func__, elapsed, s.ToString(),
  520. file_name_);
  521. io_tracer_->WriteIOOp(io_record, dbg);
  522. return s;
  523. }
  524. } // namespace ROCKSDB_NAMESPACE