In IOTracing, add filename with each operation in trace file. (#7885)
Summary: 1. In IOTracing, add filename with each IOTrace record. Filename is stored in file object (Tracing Wrappers). 2. Change the logic of figuring out which additional information (file_size, length, offset etc) needs to be store with each operation which is different for different operations. When new information will be added in future (depends on operation), this change would make the future additions simple. Logic: In IOTraceRecord, io_op_data is added and its bitwise positions represent which additional information need to added in the record from enum IOTraceOp. Values in IOTraceOp represent bitwise positions. So if length and offset needs to be stored (IOTraceOp::kIOLen is 1 and IOTraceOp::kIOOffset is 2), position 1 and 2 (from rightmost bit) will be set and io_op_data will contain 110. Pull Request resolved: https://github.com/facebook/rocksdb/pull/7885 Test Plan: Updated io_tracer_test and verified the trace file manually. Reviewed By: anand1976 Differential Revision: D25982353 Pulled By: akankshamahajan15 fbshipit-source-id: ebfc5539cc0e231d7794a6b42b73f5403e360b22
This commit is contained in:
parent
431e8afba7
commit
1d226018af
@ -810,7 +810,8 @@ Status ExternalSstFileIngestionJob::AssignGlobalSeqnoForIngestedFile(
|
|||||||
fs_->NewRandomRWFile(file_to_ingest->internal_file_path, env_options_,
|
fs_->NewRandomRWFile(file_to_ingest->internal_file_path, env_options_,
|
||||||
&rwfile, nullptr);
|
&rwfile, nullptr);
|
||||||
if (status.ok()) {
|
if (status.ok()) {
|
||||||
FSRandomRWFilePtr fsptr(std::move(rwfile), io_tracer_);
|
FSRandomRWFilePtr fsptr(std::move(rwfile), io_tracer_,
|
||||||
|
file_to_ingest->internal_file_path);
|
||||||
std::string seqno_val;
|
std::string seqno_val;
|
||||||
PutFixed64(&seqno_val, seqno);
|
PutFixed64(&seqno_val, seqno);
|
||||||
status = fsptr->Write(file_to_ingest->global_seqno_offset, seqno_val,
|
status = fsptr->Write(file_to_ingest->global_seqno_offset, seqno_val,
|
||||||
|
205
env/file_system_tracer.cc
vendored
205
env/file_system_tracer.cc
vendored
@ -16,8 +16,9 @@ IOStatus FileSystemTracingWrapper::NewSequentialFile(
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->NewSequentialFile(fname, file_opts, result, dbg);
|
IOStatus s = target()->NewSequentialFile(fname, file_opts, result, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOFileName, __func__,
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer,
|
||||||
elapsed, s.ToString(), fname);
|
0 /*io_op_data*/, __func__, elapsed, s.ToString(),
|
||||||
|
fname.substr(fname.find_last_of("/\\") + 1));
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -29,8 +30,9 @@ IOStatus FileSystemTracingWrapper::NewRandomAccessFile(
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->NewRandomAccessFile(fname, file_opts, result, dbg);
|
IOStatus s = target()->NewRandomAccessFile(fname, file_opts, result, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOFileName, __func__,
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer,
|
||||||
elapsed, s.ToString(), fname);
|
0 /*io_op_data*/, __func__, elapsed, s.ToString(),
|
||||||
|
fname.substr(fname.find_last_of("/\\") + 1));
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -42,8 +44,9 @@ IOStatus FileSystemTracingWrapper::NewWritableFile(
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->NewWritableFile(fname, file_opts, result, dbg);
|
IOStatus s = target()->NewWritableFile(fname, file_opts, result, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOFileName, __func__,
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer,
|
||||||
elapsed, s.ToString(), fname);
|
0 /*io_op_data*/, __func__, elapsed, s.ToString(),
|
||||||
|
fname.substr(fname.find_last_of("/\\") + 1));
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -55,8 +58,9 @@ IOStatus FileSystemTracingWrapper::ReopenWritableFile(
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->ReopenWritableFile(fname, file_opts, result, dbg);
|
IOStatus s = target()->ReopenWritableFile(fname, file_opts, result, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOFileName, __func__,
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer,
|
||||||
elapsed, s.ToString(), fname);
|
0 /*io_op_data*/, __func__, elapsed, s.ToString(),
|
||||||
|
fname.substr(fname.find_last_of("/\\") + 1));
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -70,8 +74,9 @@ IOStatus FileSystemTracingWrapper::ReuseWritableFile(
|
|||||||
IOStatus s =
|
IOStatus s =
|
||||||
target()->ReuseWritableFile(fname, old_fname, file_opts, result, dbg);
|
target()->ReuseWritableFile(fname, old_fname, file_opts, result, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOFileName, __func__,
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer,
|
||||||
elapsed, s.ToString(), fname);
|
0 /*io_op_data*/, __func__, elapsed, s.ToString(),
|
||||||
|
fname.substr(fname.find_last_of("/\\") + 1));
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -83,8 +88,9 @@ IOStatus FileSystemTracingWrapper::NewRandomRWFile(
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->NewRandomRWFile(fname, file_opts, result, dbg);
|
IOStatus s = target()->NewRandomRWFile(fname, file_opts, result, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOFileName, __func__,
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer,
|
||||||
elapsed, s.ToString(), fname);
|
0 /*io_op_data*/, __func__, elapsed, s.ToString(),
|
||||||
|
fname.substr(fname.find_last_of("/\\") + 1));
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -96,8 +102,9 @@ IOStatus FileSystemTracingWrapper::NewDirectory(
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->NewDirectory(name, io_opts, result, dbg);
|
IOStatus s = target()->NewDirectory(name, io_opts, result, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOFileName, __func__,
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer,
|
||||||
elapsed, s.ToString(), name);
|
0 /*io_op_data*/, __func__, elapsed, s.ToString(),
|
||||||
|
name.substr(name.find_last_of("/\\") + 1));
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -110,8 +117,9 @@ IOStatus FileSystemTracingWrapper::GetChildren(const std::string& dir,
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->GetChildren(dir, io_opts, r, dbg);
|
IOStatus s = target()->GetChildren(dir, io_opts, r, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOFileName, __func__,
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer,
|
||||||
elapsed, s.ToString(), dir);
|
0 /*io_op_data*/, __func__, elapsed, s.ToString(),
|
||||||
|
dir.substr(dir.find_last_of("/\\") + 1));
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -123,8 +131,9 @@ IOStatus FileSystemTracingWrapper::DeleteFile(const std::string& fname,
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->DeleteFile(fname, options, dbg);
|
IOStatus s = target()->DeleteFile(fname, options, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOFileName, __func__,
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer,
|
||||||
elapsed, s.ToString(), fname);
|
0 /*io_op_data*/, __func__, elapsed, s.ToString(),
|
||||||
|
fname.substr(fname.find_last_of("/\\") + 1));
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -136,8 +145,9 @@ IOStatus FileSystemTracingWrapper::CreateDir(const std::string& dirname,
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->CreateDir(dirname, options, dbg);
|
IOStatus s = target()->CreateDir(dirname, options, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOFileName, __func__,
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer,
|
||||||
elapsed, s.ToString(), dirname);
|
0 /*io_op_data*/, __func__, elapsed, s.ToString(),
|
||||||
|
dirname.substr(dirname.find_last_of("/\\") + 1));
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -148,8 +158,9 @@ IOStatus FileSystemTracingWrapper::CreateDirIfMissing(
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->CreateDirIfMissing(dirname, options, dbg);
|
IOStatus s = target()->CreateDirIfMissing(dirname, options, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOFileName, __func__,
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer,
|
||||||
elapsed, s.ToString(), dirname);
|
0 /*io_op_data*/, __func__, elapsed, s.ToString(),
|
||||||
|
dirname.substr(dirname.find_last_of("/\\") + 1));
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -161,8 +172,9 @@ IOStatus FileSystemTracingWrapper::DeleteDir(const std::string& dirname,
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->DeleteDir(dirname, options, dbg);
|
IOStatus s = target()->DeleteDir(dirname, options, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOFileName, __func__,
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer,
|
||||||
elapsed, s.ToString(), dirname);
|
0 /*io_op_data*/, __func__, elapsed, s.ToString(),
|
||||||
|
dirname.substr(dirname.find_last_of("/\\") + 1));
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -175,8 +187,11 @@ IOStatus FileSystemTracingWrapper::GetFileSize(const std::string& fname,
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->GetFileSize(fname, options, file_size, dbg);
|
IOStatus s = target()->GetFileSize(fname, options, file_size, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOFileNameAndFileSize,
|
uint64_t io_op_data = 0;
|
||||||
__func__, elapsed, s.ToString(), fname, *file_size);
|
io_op_data |= (1 << IOTraceOp::kIOFileSize);
|
||||||
|
IOTraceRecord io_record(
|
||||||
|
env_->NowNanos(), TraceType::kIOTracer, io_op_data, __func__, elapsed,
|
||||||
|
s.ToString(), fname.substr(fname.find_last_of("/\\") + 1), *file_size);
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -189,8 +204,11 @@ IOStatus FileSystemTracingWrapper::Truncate(const std::string& fname,
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->Truncate(fname, size, options, dbg);
|
IOStatus s = target()->Truncate(fname, size, options, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOFileNameAndFileSize,
|
uint64_t io_op_data = 0;
|
||||||
__func__, elapsed, s.ToString(), fname, size);
|
io_op_data |= (1 << IOTraceOp::kIOFileSize);
|
||||||
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer, io_op_data,
|
||||||
|
__func__, elapsed, s.ToString(),
|
||||||
|
fname.substr(fname.find_last_of("/\\") + 1), size);
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -203,8 +221,11 @@ IOStatus FSSequentialFileTracingWrapper::Read(size_t n,
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->Read(n, options, result, scratch, dbg);
|
IOStatus s = target()->Read(n, options, result, scratch, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOLen, __func__,
|
uint64_t io_op_data = 0;
|
||||||
elapsed, s.ToString(), result->size());
|
io_op_data |= (1 << IOTraceOp::kIOLen);
|
||||||
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer, io_op_data,
|
||||||
|
__func__, elapsed, s.ToString(), file_name_,
|
||||||
|
result->size(), 0 /*Offset*/);
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -215,8 +236,12 @@ IOStatus FSSequentialFileTracingWrapper::InvalidateCache(size_t offset,
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->InvalidateCache(offset, length);
|
IOStatus s = target()->InvalidateCache(offset, length);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOLenAndOffset,
|
uint64_t io_op_data = 0;
|
||||||
__func__, elapsed, s.ToString(), length, offset);
|
io_op_data |= (1 << IOTraceOp::kIOLen);
|
||||||
|
io_op_data |= (1 << IOTraceOp::kIOOffset);
|
||||||
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer, io_op_data,
|
||||||
|
__func__, elapsed, s.ToString(), file_name_, length,
|
||||||
|
offset);
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -229,9 +254,12 @@ IOStatus FSSequentialFileTracingWrapper::PositionedRead(
|
|||||||
IOStatus s =
|
IOStatus s =
|
||||||
target()->PositionedRead(offset, n, options, result, scratch, dbg);
|
target()->PositionedRead(offset, n, options, result, scratch, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOLenAndOffset,
|
uint64_t io_op_data = 0;
|
||||||
__func__, elapsed, s.ToString(), result->size(),
|
io_op_data |= (1 << IOTraceOp::kIOLen);
|
||||||
offset);
|
io_op_data |= (1 << IOTraceOp::kIOOffset);
|
||||||
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer, io_op_data,
|
||||||
|
__func__, elapsed, s.ToString(), file_name_,
|
||||||
|
result->size(), offset);
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -244,8 +272,12 @@ IOStatus FSRandomAccessFileTracingWrapper::Read(uint64_t offset, size_t n,
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->Read(offset, n, options, result, scratch, dbg);
|
IOStatus s = target()->Read(offset, n, options, result, scratch, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOLenAndOffset,
|
uint64_t io_op_data = 0;
|
||||||
__func__, elapsed, s.ToString(), n, offset);
|
io_op_data |= (1 << IOTraceOp::kIOLen);
|
||||||
|
io_op_data |= (1 << IOTraceOp::kIOOffset);
|
||||||
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer, io_op_data,
|
||||||
|
__func__, elapsed, s.ToString(), file_name_, n,
|
||||||
|
offset);
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -259,10 +291,13 @@ IOStatus FSRandomAccessFileTracingWrapper::MultiRead(FSReadRequest* reqs,
|
|||||||
IOStatus s = target()->MultiRead(reqs, num_reqs, options, dbg);
|
IOStatus s = target()->MultiRead(reqs, num_reqs, options, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
uint64_t latency = elapsed;
|
uint64_t latency = elapsed;
|
||||||
|
uint64_t io_op_data = 0;
|
||||||
|
io_op_data |= (1 << IOTraceOp::kIOLen);
|
||||||
|
io_op_data |= (1 << IOTraceOp::kIOOffset);
|
||||||
for (size_t i = 0; i < num_reqs; i++) {
|
for (size_t i = 0; i < num_reqs; i++) {
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOLenAndOffset,
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer, io_op_data,
|
||||||
__func__, latency, reqs[i].status.ToString(),
|
__func__, latency, reqs[i].status.ToString(),
|
||||||
reqs[i].len, reqs[i].offset);
|
file_name_, reqs[i].len, reqs[i].offset);
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
@ -275,8 +310,12 @@ IOStatus FSRandomAccessFileTracingWrapper::Prefetch(uint64_t offset, size_t n,
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->Prefetch(offset, n, options, dbg);
|
IOStatus s = target()->Prefetch(offset, n, options, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOLenAndOffset,
|
uint64_t io_op_data = 0;
|
||||||
__func__, elapsed, s.ToString(), n, offset);
|
io_op_data |= (1 << IOTraceOp::kIOLen);
|
||||||
|
io_op_data |= (1 << IOTraceOp::kIOOffset);
|
||||||
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer, io_op_data,
|
||||||
|
__func__, elapsed, s.ToString(), file_name_, n,
|
||||||
|
offset);
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -287,8 +326,11 @@ IOStatus FSRandomAccessFileTracingWrapper::InvalidateCache(size_t offset,
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->InvalidateCache(offset, length);
|
IOStatus s = target()->InvalidateCache(offset, length);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOLenAndOffset,
|
uint64_t io_op_data = 0;
|
||||||
__func__, elapsed, s.ToString(), length,
|
io_op_data |= (1 << IOTraceOp::kIOLen);
|
||||||
|
io_op_data |= (1 << IOTraceOp::kIOOffset);
|
||||||
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer, io_op_data,
|
||||||
|
__func__, elapsed, s.ToString(), file_name_, length,
|
||||||
static_cast<uint64_t>(offset));
|
static_cast<uint64_t>(offset));
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
@ -301,8 +343,11 @@ IOStatus FSWritableFileTracingWrapper::Append(const Slice& data,
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->Append(data, options, dbg);
|
IOStatus s = target()->Append(data, options, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOLen, __func__,
|
uint64_t io_op_data = 0;
|
||||||
elapsed, s.ToString(), data.size());
|
io_op_data |= (1 << IOTraceOp::kIOLen);
|
||||||
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer, io_op_data,
|
||||||
|
__func__, elapsed, s.ToString(), file_name_,
|
||||||
|
data.size(), 0 /*Offset*/);
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -314,8 +359,12 @@ IOStatus FSWritableFileTracingWrapper::PositionedAppend(
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->PositionedAppend(data, offset, options, dbg);
|
IOStatus s = target()->PositionedAppend(data, offset, options, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOLenAndOffset,
|
uint64_t io_op_data = 0;
|
||||||
__func__, elapsed, s.ToString(), data.size(), offset);
|
io_op_data |= (1 << IOTraceOp::kIOLen);
|
||||||
|
io_op_data |= (1 << IOTraceOp::kIOOffset);
|
||||||
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer, io_op_data,
|
||||||
|
__func__, elapsed, s.ToString(), file_name_,
|
||||||
|
data.size(), offset);
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -327,8 +376,11 @@ IOStatus FSWritableFileTracingWrapper::Truncate(uint64_t size,
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->Truncate(size, options, dbg);
|
IOStatus s = target()->Truncate(size, options, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOLen, __func__,
|
uint64_t io_op_data = 0;
|
||||||
elapsed, s.ToString(), size);
|
io_op_data |= (1 << IOTraceOp::kIOLen);
|
||||||
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer, io_op_data,
|
||||||
|
__func__, elapsed, s.ToString(), file_name_, size,
|
||||||
|
0 /*Offset*/);
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -339,8 +391,9 @@ IOStatus FSWritableFileTracingWrapper::Close(const IOOptions& options,
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->Close(options, dbg);
|
IOStatus s = target()->Close(options, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOGeneral, __func__,
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer,
|
||||||
elapsed, s.ToString());
|
0 /*io_op_data*/, __func__, elapsed, s.ToString(),
|
||||||
|
file_name_);
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -351,9 +404,10 @@ uint64_t FSWritableFileTracingWrapper::GetFileSize(const IOOptions& options,
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
uint64_t file_size = target()->GetFileSize(options, dbg);
|
uint64_t file_size = target()->GetFileSize(options, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOFileNameAndFileSize,
|
uint64_t io_op_data = 0;
|
||||||
"GetFileSize", elapsed, "OK", "" /* file_name */,
|
io_op_data |= (1 << IOTraceOp::kIOFileSize);
|
||||||
file_size);
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer, io_op_data,
|
||||||
|
__func__, elapsed, "OK", file_name_, file_size);
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return file_size;
|
return file_size;
|
||||||
}
|
}
|
||||||
@ -364,8 +418,11 @@ IOStatus FSWritableFileTracingWrapper::InvalidateCache(size_t offset,
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->InvalidateCache(offset, length);
|
IOStatus s = target()->InvalidateCache(offset, length);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOLenAndOffset,
|
uint64_t io_op_data = 0;
|
||||||
__func__, elapsed, s.ToString(), length,
|
io_op_data |= (1 << IOTraceOp::kIOLen);
|
||||||
|
io_op_data |= (1 << IOTraceOp::kIOOffset);
|
||||||
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer, io_op_data,
|
||||||
|
__func__, elapsed, s.ToString(), file_name_, length,
|
||||||
static_cast<uint64_t>(offset));
|
static_cast<uint64_t>(offset));
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
@ -378,8 +435,12 @@ IOStatus FSRandomRWFileTracingWrapper::Write(uint64_t offset, const Slice& data,
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->Write(offset, data, options, dbg);
|
IOStatus s = target()->Write(offset, data, options, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOLenAndOffset,
|
uint64_t io_op_data = 0;
|
||||||
__func__, elapsed, s.ToString(), data.size(), offset);
|
io_op_data |= (1 << IOTraceOp::kIOLen);
|
||||||
|
io_op_data |= (1 << IOTraceOp::kIOOffset);
|
||||||
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer, io_op_data,
|
||||||
|
__func__, elapsed, s.ToString(), file_name_,
|
||||||
|
data.size(), offset);
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -392,8 +453,12 @@ IOStatus FSRandomRWFileTracingWrapper::Read(uint64_t offset, size_t n,
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->Read(offset, n, options, result, scratch, dbg);
|
IOStatus s = target()->Read(offset, n, options, result, scratch, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOLenAndOffset,
|
uint64_t io_op_data = 0;
|
||||||
__func__, elapsed, s.ToString(), n, offset);
|
io_op_data |= (1 << IOTraceOp::kIOLen);
|
||||||
|
io_op_data |= (1 << IOTraceOp::kIOOffset);
|
||||||
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer, io_op_data,
|
||||||
|
__func__, elapsed, s.ToString(), file_name_, n,
|
||||||
|
offset);
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -404,8 +469,9 @@ IOStatus FSRandomRWFileTracingWrapper::Flush(const IOOptions& options,
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->Flush(options, dbg);
|
IOStatus s = target()->Flush(options, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOGeneral, __func__,
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer,
|
||||||
elapsed, s.ToString());
|
0 /*io_op_data*/, __func__, elapsed, s.ToString(),
|
||||||
|
file_name_);
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -416,8 +482,9 @@ IOStatus FSRandomRWFileTracingWrapper::Close(const IOOptions& options,
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->Close(options, dbg);
|
IOStatus s = target()->Close(options, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOGeneral, __func__,
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer,
|
||||||
elapsed, s.ToString());
|
0 /*io_op_data*/, __func__, elapsed, s.ToString(),
|
||||||
|
file_name_);
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -428,8 +495,9 @@ IOStatus FSRandomRWFileTracingWrapper::Sync(const IOOptions& options,
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->Sync(options, dbg);
|
IOStatus s = target()->Sync(options, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOGeneral, __func__,
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer,
|
||||||
elapsed, s.ToString());
|
0 /*io_op_data*/, __func__, elapsed, s.ToString(),
|
||||||
|
file_name_);
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -440,8 +508,9 @@ IOStatus FSRandomRWFileTracingWrapper::Fsync(const IOOptions& options,
|
|||||||
timer.Start();
|
timer.Start();
|
||||||
IOStatus s = target()->Fsync(options, dbg);
|
IOStatus s = target()->Fsync(options, dbg);
|
||||||
uint64_t elapsed = timer.ElapsedNanos();
|
uint64_t elapsed = timer.ElapsedNanos();
|
||||||
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOGeneral, __func__,
|
IOTraceRecord io_record(env_->NowNanos(), TraceType::kIOTracer,
|
||||||
elapsed, s.ToString());
|
0 /*io_op_data*/, __func__, elapsed, s.ToString(),
|
||||||
|
file_name_);
|
||||||
io_tracer_->WriteIOOp(io_record);
|
io_tracer_->WriteIOOp(io_record);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
64
env/file_system_tracer.h
vendored
64
env/file_system_tracer.h
vendored
@ -131,10 +131,12 @@ class FileSystemPtr {
|
|||||||
class FSSequentialFileTracingWrapper : public FSSequentialFileWrapper {
|
class FSSequentialFileTracingWrapper : public FSSequentialFileWrapper {
|
||||||
public:
|
public:
|
||||||
FSSequentialFileTracingWrapper(FSSequentialFile* t,
|
FSSequentialFileTracingWrapper(FSSequentialFile* t,
|
||||||
std::shared_ptr<IOTracer> io_tracer)
|
std::shared_ptr<IOTracer> io_tracer,
|
||||||
|
const std::string& file_name)
|
||||||
: FSSequentialFileWrapper(t),
|
: FSSequentialFileWrapper(t),
|
||||||
io_tracer_(io_tracer),
|
io_tracer_(io_tracer),
|
||||||
env_(Env::Default()) {}
|
env_(Env::Default()),
|
||||||
|
file_name_(file_name) {}
|
||||||
|
|
||||||
~FSSequentialFileTracingWrapper() override {}
|
~FSSequentialFileTracingWrapper() override {}
|
||||||
|
|
||||||
@ -150,6 +152,7 @@ class FSSequentialFileTracingWrapper : public FSSequentialFileWrapper {
|
|||||||
private:
|
private:
|
||||||
std::shared_ptr<IOTracer> io_tracer_;
|
std::shared_ptr<IOTracer> io_tracer_;
|
||||||
Env* env_;
|
Env* env_;
|
||||||
|
std::string file_name_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// The FSSequentialFilePtr is a wrapper class that takes pointer to storage
|
// The FSSequentialFilePtr is a wrapper class that takes pointer to storage
|
||||||
@ -161,10 +164,13 @@ class FSSequentialFilePtr {
|
|||||||
public:
|
public:
|
||||||
FSSequentialFilePtr() = delete;
|
FSSequentialFilePtr() = delete;
|
||||||
FSSequentialFilePtr(std::unique_ptr<FSSequentialFile>&& fs,
|
FSSequentialFilePtr(std::unique_ptr<FSSequentialFile>&& fs,
|
||||||
const std::shared_ptr<IOTracer>& io_tracer)
|
const std::shared_ptr<IOTracer>& io_tracer,
|
||||||
|
const std::string& file_name)
|
||||||
: fs_(std::move(fs)),
|
: fs_(std::move(fs)),
|
||||||
io_tracer_(io_tracer),
|
io_tracer_(io_tracer),
|
||||||
fs_tracer_(fs_.get(), io_tracer_) {}
|
fs_tracer_(fs_.get(), io_tracer_,
|
||||||
|
file_name.substr(file_name.find_last_of("/\\") +
|
||||||
|
1) /* pass file name */) {}
|
||||||
|
|
||||||
FSSequentialFile* operator->() const {
|
FSSequentialFile* operator->() const {
|
||||||
if (io_tracer_ && io_tracer_->is_tracing_enabled()) {
|
if (io_tracer_ && io_tracer_->is_tracing_enabled()) {
|
||||||
@ -197,10 +203,12 @@ class FSSequentialFilePtr {
|
|||||||
class FSRandomAccessFileTracingWrapper : public FSRandomAccessFileWrapper {
|
class FSRandomAccessFileTracingWrapper : public FSRandomAccessFileWrapper {
|
||||||
public:
|
public:
|
||||||
FSRandomAccessFileTracingWrapper(FSRandomAccessFile* t,
|
FSRandomAccessFileTracingWrapper(FSRandomAccessFile* t,
|
||||||
std::shared_ptr<IOTracer> io_tracer)
|
std::shared_ptr<IOTracer> io_tracer,
|
||||||
|
const std::string& file_name)
|
||||||
: FSRandomAccessFileWrapper(t),
|
: FSRandomAccessFileWrapper(t),
|
||||||
io_tracer_(io_tracer),
|
io_tracer_(io_tracer),
|
||||||
env_(Env::Default()) {}
|
env_(Env::Default()),
|
||||||
|
file_name_(file_name) {}
|
||||||
|
|
||||||
~FSRandomAccessFileTracingWrapper() override {}
|
~FSRandomAccessFileTracingWrapper() override {}
|
||||||
|
|
||||||
@ -219,6 +227,8 @@ class FSRandomAccessFileTracingWrapper : public FSRandomAccessFileWrapper {
|
|||||||
private:
|
private:
|
||||||
std::shared_ptr<IOTracer> io_tracer_;
|
std::shared_ptr<IOTracer> io_tracer_;
|
||||||
Env* env_;
|
Env* env_;
|
||||||
|
// Stores file name instead of full path.
|
||||||
|
std::string file_name_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// The FSRandomAccessFilePtr is a wrapper class that takes pointer to storage
|
// The FSRandomAccessFilePtr is a wrapper class that takes pointer to storage
|
||||||
@ -229,10 +239,13 @@ class FSRandomAccessFileTracingWrapper : public FSRandomAccessFileWrapper {
|
|||||||
class FSRandomAccessFilePtr {
|
class FSRandomAccessFilePtr {
|
||||||
public:
|
public:
|
||||||
FSRandomAccessFilePtr(std::unique_ptr<FSRandomAccessFile>&& fs,
|
FSRandomAccessFilePtr(std::unique_ptr<FSRandomAccessFile>&& fs,
|
||||||
const std::shared_ptr<IOTracer>& io_tracer)
|
const std::shared_ptr<IOTracer>& io_tracer,
|
||||||
|
const std::string& file_name)
|
||||||
: fs_(std::move(fs)),
|
: fs_(std::move(fs)),
|
||||||
io_tracer_(io_tracer),
|
io_tracer_(io_tracer),
|
||||||
fs_tracer_(fs_.get(), io_tracer_) {}
|
fs_tracer_(fs_.get(), io_tracer_,
|
||||||
|
file_name.substr(file_name.find_last_of("/\\") +
|
||||||
|
1) /* pass file name */) {}
|
||||||
|
|
||||||
FSRandomAccessFile* operator->() const {
|
FSRandomAccessFile* operator->() const {
|
||||||
if (io_tracer_ && io_tracer_->is_tracing_enabled()) {
|
if (io_tracer_ && io_tracer_->is_tracing_enabled()) {
|
||||||
@ -265,8 +278,12 @@ class FSRandomAccessFilePtr {
|
|||||||
class FSWritableFileTracingWrapper : public FSWritableFileWrapper {
|
class FSWritableFileTracingWrapper : public FSWritableFileWrapper {
|
||||||
public:
|
public:
|
||||||
FSWritableFileTracingWrapper(FSWritableFile* t,
|
FSWritableFileTracingWrapper(FSWritableFile* t,
|
||||||
std::shared_ptr<IOTracer> io_tracer)
|
std::shared_ptr<IOTracer> io_tracer,
|
||||||
: FSWritableFileWrapper(t), io_tracer_(io_tracer), env_(Env::Default()) {}
|
const std::string& file_name)
|
||||||
|
: FSWritableFileWrapper(t),
|
||||||
|
io_tracer_(io_tracer),
|
||||||
|
env_(Env::Default()),
|
||||||
|
file_name_(file_name) {}
|
||||||
|
|
||||||
~FSWritableFileTracingWrapper() override {}
|
~FSWritableFileTracingWrapper() override {}
|
||||||
|
|
||||||
@ -300,6 +317,8 @@ class FSWritableFileTracingWrapper : public FSWritableFileWrapper {
|
|||||||
private:
|
private:
|
||||||
std::shared_ptr<IOTracer> io_tracer_;
|
std::shared_ptr<IOTracer> io_tracer_;
|
||||||
Env* env_;
|
Env* env_;
|
||||||
|
// Stores file name instead of full path.
|
||||||
|
std::string file_name_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// The FSWritableFilePtr is a wrapper class that takes pointer to storage
|
// The FSWritableFilePtr is a wrapper class that takes pointer to storage
|
||||||
@ -310,9 +329,13 @@ class FSWritableFileTracingWrapper : public FSWritableFileWrapper {
|
|||||||
class FSWritableFilePtr {
|
class FSWritableFilePtr {
|
||||||
public:
|
public:
|
||||||
FSWritableFilePtr(std::unique_ptr<FSWritableFile>&& fs,
|
FSWritableFilePtr(std::unique_ptr<FSWritableFile>&& fs,
|
||||||
const std::shared_ptr<IOTracer>& io_tracer)
|
const std::shared_ptr<IOTracer>& io_tracer,
|
||||||
|
const std::string& file_name)
|
||||||
: fs_(std::move(fs)), io_tracer_(io_tracer) {
|
: fs_(std::move(fs)), io_tracer_(io_tracer) {
|
||||||
fs_tracer_.reset(new FSWritableFileTracingWrapper(fs_.get(), io_tracer_));
|
fs_tracer_.reset(new FSWritableFileTracingWrapper(
|
||||||
|
fs_.get(), io_tracer_,
|
||||||
|
file_name.substr(file_name.find_last_of("/\\") +
|
||||||
|
1) /* pass file name */));
|
||||||
}
|
}
|
||||||
|
|
||||||
FSWritableFile* operator->() const {
|
FSWritableFile* operator->() const {
|
||||||
@ -352,8 +375,12 @@ class FSWritableFilePtr {
|
|||||||
class FSRandomRWFileTracingWrapper : public FSRandomRWFileWrapper {
|
class FSRandomRWFileTracingWrapper : public FSRandomRWFileWrapper {
|
||||||
public:
|
public:
|
||||||
FSRandomRWFileTracingWrapper(FSRandomRWFile* t,
|
FSRandomRWFileTracingWrapper(FSRandomRWFile* t,
|
||||||
std::shared_ptr<IOTracer> io_tracer)
|
std::shared_ptr<IOTracer> io_tracer,
|
||||||
: FSRandomRWFileWrapper(t), io_tracer_(io_tracer), env_(Env::Default()) {}
|
const std::string& file_name)
|
||||||
|
: FSRandomRWFileWrapper(t),
|
||||||
|
io_tracer_(io_tracer),
|
||||||
|
env_(Env::Default()),
|
||||||
|
file_name_(file_name) {}
|
||||||
|
|
||||||
~FSRandomRWFileTracingWrapper() override {}
|
~FSRandomRWFileTracingWrapper() override {}
|
||||||
|
|
||||||
@ -375,6 +402,8 @@ class FSRandomRWFileTracingWrapper : public FSRandomRWFileWrapper {
|
|||||||
private:
|
private:
|
||||||
std::shared_ptr<IOTracer> io_tracer_;
|
std::shared_ptr<IOTracer> io_tracer_;
|
||||||
Env* env_;
|
Env* env_;
|
||||||
|
// Stores file name instead of full path.
|
||||||
|
std::string file_name_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// The FSRandomRWFilePtr is a wrapper class that takes pointer to storage
|
// The FSRandomRWFilePtr is a wrapper class that takes pointer to storage
|
||||||
@ -385,10 +414,13 @@ class FSRandomRWFileTracingWrapper : public FSRandomRWFileWrapper {
|
|||||||
class FSRandomRWFilePtr {
|
class FSRandomRWFilePtr {
|
||||||
public:
|
public:
|
||||||
FSRandomRWFilePtr(std::unique_ptr<FSRandomRWFile>&& fs,
|
FSRandomRWFilePtr(std::unique_ptr<FSRandomRWFile>&& fs,
|
||||||
std::shared_ptr<IOTracer> io_tracer)
|
std::shared_ptr<IOTracer> io_tracer,
|
||||||
|
const std::string& file_name)
|
||||||
: fs_(std::move(fs)),
|
: fs_(std::move(fs)),
|
||||||
io_tracer_(io_tracer),
|
io_tracer_(io_tracer),
|
||||||
fs_tracer_(fs_.get(), io_tracer_) {}
|
fs_tracer_(fs_.get(), io_tracer_,
|
||||||
|
file_name.substr(file_name.find_last_of("/\\") +
|
||||||
|
1) /* pass file name */) {}
|
||||||
|
|
||||||
FSRandomRWFile* operator->() const {
|
FSRandomRWFile* operator->() const {
|
||||||
if (io_tracer_ && io_tracer_->is_tracing_enabled()) {
|
if (io_tracer_ && io_tracer_->is_tracing_enabled()) {
|
||||||
|
@ -82,7 +82,7 @@ class RandomAccessFileReader {
|
|||||||
HistogramImpl* file_read_hist = nullptr,
|
HistogramImpl* file_read_hist = nullptr,
|
||||||
RateLimiter* rate_limiter = nullptr,
|
RateLimiter* rate_limiter = nullptr,
|
||||||
const std::vector<std::shared_ptr<EventListener>>& listeners = {})
|
const std::vector<std::shared_ptr<EventListener>>& listeners = {})
|
||||||
: file_(std::move(raf), io_tracer),
|
: file_(std::move(raf), io_tracer, _file_name),
|
||||||
file_name_(std::move(_file_name)),
|
file_name_(std::move(_file_name)),
|
||||||
env_(_env),
|
env_(_env),
|
||||||
stats_(stats),
|
stats_(stats),
|
||||||
|
@ -31,7 +31,8 @@ class SequentialFileReader {
|
|||||||
explicit SequentialFileReader(
|
explicit SequentialFileReader(
|
||||||
std::unique_ptr<FSSequentialFile>&& _file, const std::string& _file_name,
|
std::unique_ptr<FSSequentialFile>&& _file, const std::string& _file_name,
|
||||||
const std::shared_ptr<IOTracer>& io_tracer = nullptr)
|
const std::shared_ptr<IOTracer>& io_tracer = nullptr)
|
||||||
: file_name_(_file_name), file_(std::move(_file), io_tracer) {}
|
: file_name_(_file_name),
|
||||||
|
file_(std::move(_file), io_tracer, _file_name) {}
|
||||||
|
|
||||||
explicit SequentialFileReader(
|
explicit SequentialFileReader(
|
||||||
std::unique_ptr<FSSequentialFile>&& _file, const std::string& _file_name,
|
std::unique_ptr<FSSequentialFile>&& _file, const std::string& _file_name,
|
||||||
@ -39,7 +40,7 @@ class SequentialFileReader {
|
|||||||
const std::shared_ptr<IOTracer>& io_tracer = nullptr)
|
const std::shared_ptr<IOTracer>& io_tracer = nullptr)
|
||||||
: file_name_(_file_name),
|
: file_name_(_file_name),
|
||||||
file_(NewReadaheadSequentialFile(std::move(_file), _readahead_size),
|
file_(NewReadaheadSequentialFile(std::move(_file), _readahead_size),
|
||||||
io_tracer) {}
|
io_tracer, _file_name) {}
|
||||||
|
|
||||||
SequentialFileReader(const SequentialFileReader&) = delete;
|
SequentialFileReader(const SequentialFileReader&) = delete;
|
||||||
SequentialFileReader& operator=(const SequentialFileReader&) = delete;
|
SequentialFileReader& operator=(const SequentialFileReader&) = delete;
|
||||||
|
@ -151,7 +151,7 @@ class WritableFileWriter {
|
|||||||
const std::vector<std::shared_ptr<EventListener>>& listeners = {},
|
const std::vector<std::shared_ptr<EventListener>>& listeners = {},
|
||||||
FileChecksumGenFactory* file_checksum_gen_factory = nullptr)
|
FileChecksumGenFactory* file_checksum_gen_factory = nullptr)
|
||||||
: file_name_(_file_name),
|
: file_name_(_file_name),
|
||||||
writable_file_(std::move(file), io_tracer),
|
writable_file_(std::move(file), io_tracer, _file_name),
|
||||||
env_(env),
|
env_(env),
|
||||||
buf_(),
|
buf_(),
|
||||||
max_buffer_size_(options.writable_file_max_buffer_size),
|
max_buffer_size_(options.writable_file_max_buffer_size),
|
||||||
|
@ -38,32 +38,39 @@ void IOTraceRecordParser::PrintHumanReadableHeader(
|
|||||||
void IOTraceRecordParser::PrintHumanReadableIOTraceRecord(
|
void IOTraceRecordParser::PrintHumanReadableIOTraceRecord(
|
||||||
const IOTraceRecord& record) {
|
const IOTraceRecord& record) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "Access Time : " << std::setw(17) << std::left
|
ss << "Access Time : " << std::setw(20) << std::left
|
||||||
<< record.access_timestamp << ", File Operation: " << std::setw(18)
|
<< record.access_timestamp << ", File Name: " << std::setw(20) << std::left
|
||||||
|
<< record.file_name.c_str() << ", File Operation: " << std::setw(18)
|
||||||
<< std::left << record.file_operation.c_str()
|
<< std::left << record.file_operation.c_str()
|
||||||
<< ", Latency: " << std::setw(9) << std::left << record.latency
|
<< ", Latency: " << std::setw(10) << std::left << record.latency
|
||||||
<< ", IO Status: " << record.io_status.c_str();
|
<< ", IO Status: " << record.io_status.c_str();
|
||||||
|
|
||||||
switch (record.trace_type) {
|
// Each bit in io_op_data stores which corresponding info from IOTraceOp will
|
||||||
case TraceType::kIOGeneral:
|
// be added in the trace. Foreg, if bit at position 1 is set then
|
||||||
break;
|
// IOTraceOp::kIOLen (length) will be logged in the record (Since
|
||||||
case TraceType::kIOFileNameAndFileSize:
|
// IOTraceOp::kIOLen = 1 in the enum). So find all the set positions in
|
||||||
ss << ", File Size: " << record.file_size;
|
// io_op_data one by one and, update corresponsing info in the trace record,
|
||||||
FALLTHROUGH_INTENDED;
|
// unset that bit to find other set bits until io_op_data = 0.
|
||||||
case TraceType::kIOFileName: {
|
/* Read remaining options based on io_op_data set by file operation */
|
||||||
if (!record.file_name.empty()) {
|
int64_t io_op_data = static_cast<int64_t>(record.io_op_data);
|
||||||
ss << ", File Name: " << record.file_name.c_str();
|
while (io_op_data) {
|
||||||
}
|
// Find the rightmost set bit.
|
||||||
break;
|
uint32_t set_pos = static_cast<uint32_t>(log2(io_op_data & -io_op_data));
|
||||||
|
switch (set_pos) {
|
||||||
|
case IOTraceOp::kIOFileSize:
|
||||||
|
ss << ", File Size: " << record.file_size;
|
||||||
|
break;
|
||||||
|
case IOTraceOp::kIOLen:
|
||||||
|
ss << ", Length: " << record.len;
|
||||||
|
break;
|
||||||
|
case IOTraceOp::kIOOffset:
|
||||||
|
ss << ", Offset: " << record.offset;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
}
|
}
|
||||||
case TraceType::kIOLenAndOffset:
|
// unset the rightmost bit.
|
||||||
ss << ", Offset: " << record.offset;
|
io_op_data &= (io_op_data - 1);
|
||||||
FALLTHROUGH_INTENDED;
|
|
||||||
case TraceType::kIOLen:
|
|
||||||
ss << ", Length: " << record.len;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
}
|
}
|
||||||
ss << "\n";
|
ss << "\n";
|
||||||
fprintf(stdout, "%s", ss.str().c_str());
|
fprintf(stdout, "%s", ss.str().c_str());
|
||||||
|
@ -31,32 +31,43 @@ Status IOTraceWriter::WriteIOOp(const IOTraceRecord& record) {
|
|||||||
Trace trace;
|
Trace trace;
|
||||||
trace.ts = record.access_timestamp;
|
trace.ts = record.access_timestamp;
|
||||||
trace.type = record.trace_type;
|
trace.type = record.trace_type;
|
||||||
|
PutFixed64(&trace.payload, record.io_op_data);
|
||||||
Slice file_operation(record.file_operation);
|
Slice file_operation(record.file_operation);
|
||||||
PutLengthPrefixedSlice(&trace.payload, file_operation);
|
PutLengthPrefixedSlice(&trace.payload, file_operation);
|
||||||
PutFixed64(&trace.payload, record.latency);
|
PutFixed64(&trace.payload, record.latency);
|
||||||
Slice io_status(record.io_status);
|
Slice io_status(record.io_status);
|
||||||
PutLengthPrefixedSlice(&trace.payload, io_status);
|
PutLengthPrefixedSlice(&trace.payload, io_status);
|
||||||
/* Write remaining options based on trace_type set by file operation */
|
Slice file_name(record.file_name);
|
||||||
switch (record.trace_type) {
|
PutLengthPrefixedSlice(&trace.payload, file_name);
|
||||||
case TraceType::kIOGeneral:
|
|
||||||
break;
|
// Each bit in io_op_data stores which corresponding info from IOTraceOp will
|
||||||
case TraceType::kIOFileNameAndFileSize:
|
// be added in the trace. Foreg, if bit at position 1 is set then
|
||||||
PutFixed64(&trace.payload, record.file_size);
|
// IOTraceOp::kIOLen (length) will be logged in the record (Since
|
||||||
FALLTHROUGH_INTENDED;
|
// IOTraceOp::kIOLen = 1 in the enum). So find all the set positions in
|
||||||
case TraceType::kIOFileName: {
|
// io_op_data one by one and, update corresponsing info in the trace record,
|
||||||
Slice file_name(record.file_name);
|
// unset that bit to find other set bits until io_op_data = 0.
|
||||||
PutLengthPrefixedSlice(&trace.payload, file_name);
|
/* Write remaining options based on io_op_data set by file operation */
|
||||||
break;
|
int64_t io_op_data = static_cast<int64_t>(record.io_op_data);
|
||||||
|
while (io_op_data) {
|
||||||
|
// Find the rightmost set bit.
|
||||||
|
uint32_t set_pos = static_cast<uint32_t>(log2(io_op_data & -io_op_data));
|
||||||
|
switch (set_pos) {
|
||||||
|
case IOTraceOp::kIOFileSize:
|
||||||
|
PutFixed64(&trace.payload, record.file_size);
|
||||||
|
break;
|
||||||
|
case IOTraceOp::kIOLen:
|
||||||
|
PutFixed64(&trace.payload, record.len);
|
||||||
|
break;
|
||||||
|
case IOTraceOp::kIOOffset:
|
||||||
|
PutFixed64(&trace.payload, record.offset);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
}
|
}
|
||||||
case TraceType::kIOLenAndOffset:
|
// unset the rightmost bit.
|
||||||
PutFixed64(&trace.payload, record.offset);
|
io_op_data &= (io_op_data - 1);
|
||||||
FALLTHROUGH_INTENDED;
|
|
||||||
case TraceType::kIOLen:
|
|
||||||
PutFixed64(&trace.payload, record.len);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string encoded_trace;
|
std::string encoded_trace;
|
||||||
TracerHelper::EncodeTrace(trace, &encoded_trace);
|
TracerHelper::EncodeTrace(trace, &encoded_trace);
|
||||||
return trace_writer_->Write(encoded_trace);
|
return trace_writer_->Write(encoded_trace);
|
||||||
@ -135,6 +146,10 @@ Status IOTraceReader::ReadIOOp(IOTraceRecord* record) {
|
|||||||
record->trace_type = trace.type;
|
record->trace_type = trace.type;
|
||||||
Slice enc_slice = Slice(trace.payload);
|
Slice enc_slice = Slice(trace.payload);
|
||||||
|
|
||||||
|
if (!GetFixed64(&enc_slice, &record->io_op_data)) {
|
||||||
|
return Status::Incomplete(
|
||||||
|
"Incomplete access record: Failed to read trace data.");
|
||||||
|
}
|
||||||
Slice file_operation;
|
Slice file_operation;
|
||||||
if (!GetLengthPrefixedSlice(&enc_slice, &file_operation)) {
|
if (!GetLengthPrefixedSlice(&enc_slice, &file_operation)) {
|
||||||
return Status::Incomplete(
|
return Status::Incomplete(
|
||||||
@ -151,40 +166,49 @@ Status IOTraceReader::ReadIOOp(IOTraceRecord* record) {
|
|||||||
"Incomplete access record: Failed to read IO status.");
|
"Incomplete access record: Failed to read IO status.");
|
||||||
}
|
}
|
||||||
record->io_status = io_status.ToString();
|
record->io_status = io_status.ToString();
|
||||||
/* Read remaining options based on trace_type set by file operation */
|
Slice file_name;
|
||||||
switch (record->trace_type) {
|
if (!GetLengthPrefixedSlice(&enc_slice, &file_name)) {
|
||||||
case TraceType::kIOGeneral:
|
return Status::Incomplete(
|
||||||
break;
|
"Incomplete access record: Failed to read file name.");
|
||||||
case TraceType::kIOFileNameAndFileSize:
|
}
|
||||||
if (!GetFixed64(&enc_slice, &record->file_size)) {
|
record->file_name = file_name.ToString();
|
||||||
return Status::Incomplete(
|
|
||||||
"Incomplete access record: Failed to read file size.");
|
// Each bit in io_op_data stores which corresponding info from IOTraceOp will
|
||||||
}
|
// be added in the trace. Foreg, if bit at position 1 is set then
|
||||||
FALLTHROUGH_INTENDED;
|
// IOTraceOp::kIOLen (length) will be logged in the record (Since
|
||||||
case TraceType::kIOFileName: {
|
// IOTraceOp::kIOLen = 1 in the enum). So find all the set positions in
|
||||||
Slice file_name;
|
// io_op_data one by one and, update corresponsing info in the trace record,
|
||||||
if (!GetLengthPrefixedSlice(&enc_slice, &file_name)) {
|
// unset that bit to find other set bits until io_op_data = 0.
|
||||||
return Status::Incomplete(
|
/* Read remaining options based on io_op_data set by file operation */
|
||||||
"Incomplete access record: Failed to read file name.");
|
// Assuming 63 bits will be used at max.
|
||||||
}
|
int64_t io_op_data = static_cast<int64_t>(record->io_op_data);
|
||||||
record->file_name = file_name.ToString();
|
while (io_op_data) {
|
||||||
break;
|
// Find the rightmost set bit.
|
||||||
|
uint32_t set_pos = static_cast<uint32_t>(log2(io_op_data & -io_op_data));
|
||||||
|
switch (set_pos) {
|
||||||
|
case IOTraceOp::kIOFileSize:
|
||||||
|
if (!GetFixed64(&enc_slice, &record->file_size)) {
|
||||||
|
return Status::Incomplete(
|
||||||
|
"Incomplete access record: Failed to read file size.");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IOTraceOp::kIOLen:
|
||||||
|
if (!GetFixed64(&enc_slice, &record->len)) {
|
||||||
|
return Status::Incomplete(
|
||||||
|
"Incomplete access record: Failed to read length.");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IOTraceOp::kIOOffset:
|
||||||
|
if (!GetFixed64(&enc_slice, &record->offset)) {
|
||||||
|
return Status::Incomplete(
|
||||||
|
"Incomplete access record: Failed to read offset.");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
}
|
}
|
||||||
case TraceType::kIOLenAndOffset:
|
// unset the rightmost bit.
|
||||||
if (!GetFixed64(&enc_slice, &record->offset)) {
|
io_op_data &= (io_op_data - 1);
|
||||||
return Status::Incomplete(
|
|
||||||
"Incomplete access record: Failed to read offset.");
|
|
||||||
}
|
|
||||||
FALLTHROUGH_INTENDED;
|
|
||||||
case TraceType::kIOLen: {
|
|
||||||
if (!GetFixed64(&enc_slice, &record->len)) {
|
|
||||||
return Status::Incomplete(
|
|
||||||
"Incomplete access record: Failed to read length.");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
}
|
}
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
|
@ -16,15 +16,37 @@
|
|||||||
|
|
||||||
namespace ROCKSDB_NAMESPACE {
|
namespace ROCKSDB_NAMESPACE {
|
||||||
|
|
||||||
|
/* In order to log new data in trace record for specified operations, do
|
||||||
|
following:
|
||||||
|
1. Add new data in IOTraceOP (say kIONewData= 3)
|
||||||
|
2. Log it in IOTraceWriter::WriteIOOp, and read that in
|
||||||
|
IOTraceReader::ReadIOOp and
|
||||||
|
IOTraceRecordParser::PrintHumanReadableIOTraceRecord in the switch case.
|
||||||
|
3. In the FileSystemTracer APIs where this data will be logged with, update
|
||||||
|
io_op_data |= (1 << IOTraceOp::kIONewData).
|
||||||
|
*/
|
||||||
|
enum IOTraceOp : char {
|
||||||
|
// The value of each enum represents the bitwise position for
|
||||||
|
// IOTraceRecord.io_op_data.
|
||||||
|
kIOFileSize = 0,
|
||||||
|
kIOLen = 1,
|
||||||
|
kIOOffset = 2,
|
||||||
|
};
|
||||||
|
|
||||||
struct IOTraceRecord {
|
struct IOTraceRecord {
|
||||||
// Required fields for all accesses.
|
// Required fields for all accesses.
|
||||||
uint64_t access_timestamp = 0;
|
uint64_t access_timestamp = 0;
|
||||||
TraceType trace_type = TraceType::kTraceMax;
|
TraceType trace_type = TraceType::kTraceMax;
|
||||||
|
// Each bit in io_op_data stores which corresponding info from IOTraceOp will
|
||||||
|
// be added in the trace. Foreg, if bit at position 1 is set then
|
||||||
|
// IOTraceOp::kIOLen (length) will be logged in the record.
|
||||||
|
uint64_t io_op_data = 0;
|
||||||
std::string file_operation;
|
std::string file_operation;
|
||||||
uint64_t latency = 0;
|
uint64_t latency = 0;
|
||||||
std::string io_status;
|
std::string io_status;
|
||||||
// Required fields for read.
|
// Stores file name instead of full path.
|
||||||
std::string file_name;
|
std::string file_name;
|
||||||
|
// Fields added to record based on IO operation.
|
||||||
uint64_t len = 0;
|
uint64_t len = 0;
|
||||||
uint64_t offset = 0;
|
uint64_t offset = 0;
|
||||||
uint64_t file_size = 0;
|
uint64_t file_size = 0;
|
||||||
@ -32,21 +54,12 @@ struct IOTraceRecord {
|
|||||||
IOTraceRecord() {}
|
IOTraceRecord() {}
|
||||||
|
|
||||||
IOTraceRecord(const uint64_t& _access_timestamp, const TraceType& _trace_type,
|
IOTraceRecord(const uint64_t& _access_timestamp, const TraceType& _trace_type,
|
||||||
const std::string& _file_operation, const uint64_t& _latency,
|
const uint64_t& _io_op_data, const std::string& _file_operation,
|
||||||
const std::string& _io_status, const std::string& _file_name)
|
const uint64_t& _latency, const std::string& _io_status,
|
||||||
: access_timestamp(_access_timestamp),
|
const std::string& _file_name, const uint64_t& _file_size = 0)
|
||||||
trace_type(_trace_type),
|
|
||||||
file_operation(_file_operation),
|
|
||||||
latency(_latency),
|
|
||||||
io_status(_io_status),
|
|
||||||
file_name(_file_name) {}
|
|
||||||
|
|
||||||
IOTraceRecord(const uint64_t& _access_timestamp, const TraceType& _trace_type,
|
|
||||||
const std::string& _file_operation, const uint64_t& _latency,
|
|
||||||
const std::string& _io_status, const std::string& _file_name,
|
|
||||||
const uint64_t& _file_size)
|
|
||||||
: access_timestamp(_access_timestamp),
|
: access_timestamp(_access_timestamp),
|
||||||
trace_type(_trace_type),
|
trace_type(_trace_type),
|
||||||
|
io_op_data(_io_op_data),
|
||||||
file_operation(_file_operation),
|
file_operation(_file_operation),
|
||||||
latency(_latency),
|
latency(_latency),
|
||||||
io_status(_io_status),
|
io_status(_io_status),
|
||||||
@ -54,14 +67,17 @@ struct IOTraceRecord {
|
|||||||
file_size(_file_size) {}
|
file_size(_file_size) {}
|
||||||
|
|
||||||
IOTraceRecord(const uint64_t& _access_timestamp, const TraceType& _trace_type,
|
IOTraceRecord(const uint64_t& _access_timestamp, const TraceType& _trace_type,
|
||||||
const std::string& _file_operation, const uint64_t& _latency,
|
const uint64_t& _io_op_data, const std::string& _file_operation,
|
||||||
const std::string& _io_status, const uint64_t& _len = 0,
|
const uint64_t& _latency, const std::string& _io_status,
|
||||||
const uint64_t& _offset = 0)
|
const std::string& _file_name, const uint64_t& _len,
|
||||||
|
const uint64_t& _offset)
|
||||||
: access_timestamp(_access_timestamp),
|
: access_timestamp(_access_timestamp),
|
||||||
trace_type(_trace_type),
|
trace_type(_trace_type),
|
||||||
|
io_op_data(_io_op_data),
|
||||||
file_operation(_file_operation),
|
file_operation(_file_operation),
|
||||||
latency(_latency),
|
latency(_latency),
|
||||||
io_status(_io_status),
|
io_status(_io_status),
|
||||||
|
file_name(_file_name),
|
||||||
len(_len),
|
len(_len),
|
||||||
offset(_offset) {}
|
offset(_offset) {}
|
||||||
};
|
};
|
||||||
|
@ -52,7 +52,10 @@ class IOTracerTest : public testing::Test {
|
|||||||
assert(writer);
|
assert(writer);
|
||||||
for (uint64_t i = 0; i < nrecords; i++) {
|
for (uint64_t i = 0; i < nrecords; i++) {
|
||||||
IOTraceRecord record;
|
IOTraceRecord record;
|
||||||
record.trace_type = TraceType::kIOLenAndOffset;
|
record.io_op_data = 0;
|
||||||
|
record.trace_type = TraceType::kIOTracer;
|
||||||
|
record.io_op_data |= (1 << IOTraceOp::kIOLen);
|
||||||
|
record.io_op_data |= (1 << IOTraceOp::kIOOffset);
|
||||||
record.file_operation = GetFileOperation(i);
|
record.file_operation = GetFileOperation(i);
|
||||||
record.io_status = IOStatus::OK().ToString();
|
record.io_status = IOStatus::OK().ToString();
|
||||||
record.file_name = kDummyFile + std::to_string(i);
|
record.file_name = kDummyFile + std::to_string(i);
|
||||||
@ -80,10 +83,117 @@ class IOTracerTest : public testing::Test {
|
|||||||
std::string test_path_;
|
std::string test_path_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TEST_F(IOTracerTest, MultipleRecordsWithDifferentIOOpOptions) {
|
||||||
|
std::string file_name = kDummyFile + std::to_string(5);
|
||||||
|
{
|
||||||
|
TraceOptions trace_opt;
|
||||||
|
std::unique_ptr<TraceWriter> trace_writer;
|
||||||
|
ASSERT_OK(NewFileTraceWriter(env_, env_options_, trace_file_path_,
|
||||||
|
&trace_writer));
|
||||||
|
IOTracer writer;
|
||||||
|
ASSERT_OK(writer.StartIOTrace(env_, trace_opt, std::move(trace_writer)));
|
||||||
|
|
||||||
|
// Write general record.
|
||||||
|
IOTraceRecord record0(0, TraceType::kIOTracer, 0 /*io_op_data*/,
|
||||||
|
GetFileOperation(0), 155 /*latency*/,
|
||||||
|
IOStatus::OK().ToString(), file_name);
|
||||||
|
writer.WriteIOOp(record0);
|
||||||
|
|
||||||
|
// Write record with FileSize.
|
||||||
|
uint64_t io_op_data = 0;
|
||||||
|
io_op_data |= (1 << IOTraceOp::kIOFileSize);
|
||||||
|
IOTraceRecord record1(0, TraceType::kIOTracer, io_op_data,
|
||||||
|
GetFileOperation(1), 10 /*latency*/,
|
||||||
|
IOStatus::OK().ToString(), file_name,
|
||||||
|
256 /*file_size*/);
|
||||||
|
writer.WriteIOOp(record1);
|
||||||
|
|
||||||
|
// Write record with Length.
|
||||||
|
io_op_data = 0;
|
||||||
|
io_op_data |= (1 << IOTraceOp::kIOLen);
|
||||||
|
IOTraceRecord record2(0, TraceType::kIOTracer, io_op_data,
|
||||||
|
GetFileOperation(2), 10 /*latency*/,
|
||||||
|
IOStatus::OK().ToString(), file_name, 100 /*length*/,
|
||||||
|
200 /*offset*/);
|
||||||
|
writer.WriteIOOp(record2);
|
||||||
|
|
||||||
|
// Write record with Length and offset.
|
||||||
|
io_op_data = 0;
|
||||||
|
io_op_data |= (1 << IOTraceOp::kIOLen);
|
||||||
|
io_op_data |= (1 << IOTraceOp::kIOOffset);
|
||||||
|
IOTraceRecord record3(0, TraceType::kIOTracer, io_op_data,
|
||||||
|
GetFileOperation(3), 10 /*latency*/,
|
||||||
|
IOStatus::OK().ToString(), file_name, 120 /*length*/,
|
||||||
|
17 /*offset*/);
|
||||||
|
writer.WriteIOOp(record3);
|
||||||
|
|
||||||
|
// Write record with offset.
|
||||||
|
io_op_data = 0;
|
||||||
|
io_op_data |= (1 << IOTraceOp::kIOOffset);
|
||||||
|
IOTraceRecord record4(0, TraceType::kIOTracer, io_op_data,
|
||||||
|
GetFileOperation(4), 10 /*latency*/,
|
||||||
|
IOStatus::OK().ToString(), file_name, 13 /*length*/,
|
||||||
|
50 /*offset*/);
|
||||||
|
writer.WriteIOOp(record4);
|
||||||
|
ASSERT_OK(env_->FileExists(trace_file_path_));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// Verify trace file is generated correctly.
|
||||||
|
std::unique_ptr<TraceReader> trace_reader;
|
||||||
|
ASSERT_OK(NewFileTraceReader(env_, env_options_, trace_file_path_,
|
||||||
|
&trace_reader));
|
||||||
|
IOTraceReader reader(std::move(trace_reader));
|
||||||
|
IOTraceHeader header;
|
||||||
|
ASSERT_OK(reader.ReadHeader(&header));
|
||||||
|
ASSERT_EQ(kMajorVersion, static_cast<int>(header.rocksdb_major_version));
|
||||||
|
ASSERT_EQ(kMinorVersion, static_cast<int>(header.rocksdb_minor_version));
|
||||||
|
|
||||||
|
// Read general record.
|
||||||
|
IOTraceRecord record0;
|
||||||
|
ASSERT_OK(reader.ReadIOOp(&record0));
|
||||||
|
ASSERT_EQ(record0.file_operation, GetFileOperation(0));
|
||||||
|
ASSERT_EQ(record0.latency, 155);
|
||||||
|
ASSERT_EQ(record0.file_name, file_name);
|
||||||
|
|
||||||
|
// Read record with FileSize.
|
||||||
|
IOTraceRecord record1;
|
||||||
|
ASSERT_OK(reader.ReadIOOp(&record1));
|
||||||
|
ASSERT_EQ(record1.file_size, 256);
|
||||||
|
ASSERT_EQ(record1.len, 0);
|
||||||
|
ASSERT_EQ(record1.offset, 0);
|
||||||
|
|
||||||
|
// Read record with Length.
|
||||||
|
IOTraceRecord record2;
|
||||||
|
ASSERT_OK(reader.ReadIOOp(&record2));
|
||||||
|
ASSERT_EQ(record2.len, 100);
|
||||||
|
ASSERT_EQ(record2.file_size, 0);
|
||||||
|
ASSERT_EQ(record2.offset, 0);
|
||||||
|
|
||||||
|
// Read record with Length and offset.
|
||||||
|
IOTraceRecord record3;
|
||||||
|
ASSERT_OK(reader.ReadIOOp(&record3));
|
||||||
|
ASSERT_EQ(record3.len, 120);
|
||||||
|
ASSERT_EQ(record3.file_size, 0);
|
||||||
|
ASSERT_EQ(record3.offset, 17);
|
||||||
|
|
||||||
|
// Read record with offset.
|
||||||
|
IOTraceRecord record4;
|
||||||
|
ASSERT_OK(reader.ReadIOOp(&record4));
|
||||||
|
ASSERT_EQ(record4.len, 0);
|
||||||
|
ASSERT_EQ(record4.file_size, 0);
|
||||||
|
ASSERT_EQ(record4.offset, 50);
|
||||||
|
|
||||||
|
// Read one more record and it should report error.
|
||||||
|
IOTraceRecord record5;
|
||||||
|
ASSERT_NOK(reader.ReadIOOp(&record5));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(IOTracerTest, AtomicWrite) {
|
TEST_F(IOTracerTest, AtomicWrite) {
|
||||||
std::string file_name = kDummyFile + std::to_string(0);
|
std::string file_name = kDummyFile + std::to_string(0);
|
||||||
{
|
{
|
||||||
IOTraceRecord record(0, TraceType::kIOFileName, GetFileOperation(0), 0,
|
IOTraceRecord record(0, TraceType::kIOTracer, 0 /*io_op_data*/,
|
||||||
|
GetFileOperation(0), 10 /*latency*/,
|
||||||
IOStatus::OK().ToString(), file_name);
|
IOStatus::OK().ToString(), file_name);
|
||||||
TraceOptions trace_opt;
|
TraceOptions trace_opt;
|
||||||
std::unique_ptr<TraceWriter> trace_writer;
|
std::unique_ptr<TraceWriter> trace_writer;
|
||||||
@ -115,9 +225,11 @@ TEST_F(IOTracerTest, AtomicWrite) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IOTracerTest, AtomicWriteBeforeStartTrace) {
|
TEST_F(IOTracerTest, AtomicWriteBeforeStartTrace) {
|
||||||
|
std::string file_name = kDummyFile + std::to_string(0);
|
||||||
{
|
{
|
||||||
IOTraceRecord record(0, TraceType::kIOGeneral, GetFileOperation(0), 0,
|
IOTraceRecord record(0, TraceType::kIOTracer, 0 /*io_op_data*/,
|
||||||
IOStatus::OK().ToString());
|
GetFileOperation(0), 0, IOStatus::OK().ToString(),
|
||||||
|
file_name);
|
||||||
std::unique_ptr<TraceWriter> trace_writer;
|
std::unique_ptr<TraceWriter> trace_writer;
|
||||||
ASSERT_OK(NewFileTraceWriter(env_, env_options_, trace_file_path_,
|
ASSERT_OK(NewFileTraceWriter(env_, env_options_, trace_file_path_,
|
||||||
&trace_writer));
|
&trace_writer));
|
||||||
@ -139,10 +251,13 @@ TEST_F(IOTracerTest, AtomicWriteBeforeStartTrace) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IOTracerTest, AtomicNoWriteAfterEndTrace) {
|
TEST_F(IOTracerTest, AtomicNoWriteAfterEndTrace) {
|
||||||
|
std::string file_name = kDummyFile + std::to_string(0);
|
||||||
{
|
{
|
||||||
IOTraceRecord record(0, TraceType::kIOFileNameAndFileSize,
|
uint64_t io_op_data = 0;
|
||||||
GetFileOperation(2), 0 /*latency*/,
|
io_op_data |= (1 << IOTraceOp::kIOFileSize);
|
||||||
IOStatus::OK().ToString(), "", 10 /*file_size*/);
|
IOTraceRecord record(
|
||||||
|
0, TraceType::kIOTracer, io_op_data, GetFileOperation(2), 0 /*latency*/,
|
||||||
|
IOStatus::OK().ToString(), file_name, 10 /*file_size*/);
|
||||||
TraceOptions trace_opt;
|
TraceOptions trace_opt;
|
||||||
std::unique_ptr<TraceWriter> trace_writer;
|
std::unique_ptr<TraceWriter> trace_writer;
|
||||||
ASSERT_OK(NewFileTraceWriter(env_, env_options_, trace_file_path_,
|
ASSERT_OK(NewFileTraceWriter(env_, env_options_, trace_file_path_,
|
||||||
|
@ -46,12 +46,8 @@ enum TraceType : char {
|
|||||||
kBlockTraceDataBlock = 9,
|
kBlockTraceDataBlock = 9,
|
||||||
kBlockTraceUncompressionDictBlock = 10,
|
kBlockTraceUncompressionDictBlock = 10,
|
||||||
kBlockTraceRangeDeletionBlock = 11,
|
kBlockTraceRangeDeletionBlock = 11,
|
||||||
// IO Trace related types based on options that will be added in trace file.
|
// For IOTracing.
|
||||||
kIOGeneral = 12,
|
kIOTracer = 12,
|
||||||
kIOFileName = 13,
|
|
||||||
kIOFileNameAndFileSize = 14,
|
|
||||||
kIOLen = 15,
|
|
||||||
kIOLenAndOffset = 16,
|
|
||||||
// All trace types should be added before kTraceMax
|
// All trace types should be added before kTraceMax
|
||||||
kTraceMax,
|
kTraceMax,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user