summaryrefslogtreecommitdiffstats
path: root/src/rocksdb/tools/io_tracer_parser_tool.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/rocksdb/tools/io_tracer_parser_tool.cc')
-rw-r--r--src/rocksdb/tools/io_tracer_parser_tool.cc144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/rocksdb/tools/io_tracer_parser_tool.cc b/src/rocksdb/tools/io_tracer_parser_tool.cc
new file mode 100644
index 000000000..01b920f3b
--- /dev/null
+++ b/src/rocksdb/tools/io_tracer_parser_tool.cc
@@ -0,0 +1,144 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+
+#ifndef ROCKSDB_LITE
+#ifdef GFLAGS
+#include "tools/io_tracer_parser_tool.h"
+
+#include <cinttypes>
+#include <cstdio>
+#include <iomanip>
+#include <memory>
+#include <sstream>
+
+#include "port/lang.h"
+#include "rocksdb/trace_reader_writer.h"
+#include "trace_replay/io_tracer.h"
+#include "util/gflags_compat.h"
+
+using GFLAGS_NAMESPACE::ParseCommandLineFlags;
+
+DEFINE_string(io_trace_file, "", "The IO trace file path.");
+
+namespace ROCKSDB_NAMESPACE {
+
+IOTraceRecordParser::IOTraceRecordParser(const std::string& input_file)
+ : input_file_(input_file) {}
+
+void IOTraceRecordParser::PrintHumanReadableHeader(
+ const IOTraceHeader& header) {
+ std::stringstream ss;
+ ss << "Start Time: " << header.start_time
+ << "\nRocksDB Major Version: " << header.rocksdb_major_version
+ << "\nRocksDB Minor Version: " << header.rocksdb_minor_version << "\n";
+ fprintf(stdout, "%s", ss.str().c_str());
+}
+
+void IOTraceRecordParser::PrintHumanReadableIOTraceRecord(
+ const IOTraceRecord& record) {
+ std::stringstream ss;
+ ss << "Access Time : " << std::setw(20) << std::left
+ << 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()
+ << ", Latency: " << std::setw(10) << std::left << record.latency
+ << ", IO Status: " << record.io_status.c_str();
+
+ // 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 (Since
+ // IOTraceOp::kIOLen = 1 in the enum). So find all the set positions in
+ // io_op_data one by one and, update corresponsing info in the trace record,
+ // unset that bit to find other set bits until io_op_data = 0.
+ /* Read remaining options based on io_op_data set by file operation */
+ 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:
+ 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);
+ }
+ // unset the rightmost bit.
+ io_op_data &= (io_op_data - 1);
+ }
+
+ int64_t trace_data = static_cast<int64_t>(record.trace_data);
+ while (trace_data) {
+ // Find the rightmost set bit.
+ uint32_t set_pos = static_cast<uint32_t>(log2(trace_data & -trace_data));
+ switch (set_pos) {
+ case IODebugContext::TraceData::kRequestID:
+ ss << ", Request Id: " << record.request_id;
+ break;
+ default:
+ assert(false);
+ }
+ // unset the rightmost bit.
+ trace_data &= (trace_data - 1);
+ }
+
+ ss << "\n";
+ fprintf(stdout, "%s", ss.str().c_str());
+}
+
+int IOTraceRecordParser::ReadIOTraceRecords() {
+ Status status;
+ Env* env(Env::Default());
+ std::unique_ptr<TraceReader> trace_reader;
+ std::unique_ptr<IOTraceReader> io_trace_reader;
+
+ status = NewFileTraceReader(env, EnvOptions(), input_file_, &trace_reader);
+ if (!status.ok()) {
+ fprintf(stderr, "%s: %s\n", input_file_.c_str(), status.ToString().c_str());
+ return 1;
+ }
+ io_trace_reader.reset(new IOTraceReader(std::move(trace_reader)));
+
+ // Read the header and dump it in a file.
+ IOTraceHeader header;
+ status = io_trace_reader->ReadHeader(&header);
+ if (!status.ok()) {
+ fprintf(stderr, "%s: %s\n", input_file_.c_str(), status.ToString().c_str());
+ return 1;
+ }
+ PrintHumanReadableHeader(header);
+
+ // Read the records one by one and print them in human readable format.
+ while (status.ok()) {
+ IOTraceRecord record;
+ status = io_trace_reader->ReadIOOp(&record);
+ if (!status.ok()) {
+ break;
+ }
+ PrintHumanReadableIOTraceRecord(record);
+ }
+ return 0;
+}
+
+int io_tracer_parser(int argc, char** argv) {
+ ParseCommandLineFlags(&argc, &argv, true);
+
+ if (FLAGS_io_trace_file.empty()) {
+ fprintf(stderr, "IO Trace file path is empty\n");
+ return 1;
+ }
+
+ IOTraceRecordParser io_tracer_parser(FLAGS_io_trace_file);
+ return io_tracer_parser.ReadIOTraceRecords();
+}
+
+} // namespace ROCKSDB_NAMESPACE
+#endif // GFLAGS
+#endif // ROCKSDB_LITE