Skip to content

Commit

Permalink
rpcdaemon: add config flag to toggle response dump in interface log (#…
Browse files Browse the repository at this point in the history
…1959)

cmd: add optional command-line option to dump response in interface log
  • Loading branch information
canepat authored Apr 10, 2024
1 parent 98447ef commit bbc3c91
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 2 deletions.
4 changes: 4 additions & 0 deletions cmd/common/rpcdaemon_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ static void add_options_interface_log(CLI::App& cli, const std::string& option_p
->description("Maximum size in megabytes of each interface log file for " + end_point_descr)
->check(CLI::Range(1, 1024))
->capture_default_str();

cli.add_flag("--" + option_prefix + ".log.dump_response", settings.dump_response)
->description("Enable response dump in interface log for " + end_point_descr)
->capture_default_str();
}

void add_rpcdaemon_options(CLI::App& cli, silkworm::rpc::DaemonSettings& settings) {
Expand Down
10 changes: 9 additions & 1 deletion silkworm/rpc/common/interface_log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ class InterfaceLogImpl final {
flush();
}

[[nodiscard]] bool dump_response() const {
return dump_response_;
}

[[nodiscard]] std::filesystem::path path() const {
return file_path_;
}
Expand All @@ -53,6 +57,7 @@ class InterfaceLogImpl final {
private:
std::string name_;
bool auto_flush_;
bool dump_response_;
std::filesystem::path file_path_;
std::size_t max_file_size_;
std::size_t max_files_;
Expand All @@ -63,6 +68,7 @@ class InterfaceLogImpl final {
InterfaceLogImpl::InterfaceLogImpl(InterfaceLogSettings settings)
: name_{std::move(settings.ifc_name)},
auto_flush_{settings.auto_flush},
dump_response_{settings.dump_response},
file_path_{settings.container_folder / std::filesystem::path{name_ + ".log"}},
max_file_size_{settings.max_file_size_mb * kMebi},
max_files_{settings.max_files},
Expand Down Expand Up @@ -96,7 +102,9 @@ void InterfaceLog::log_req(std::string_view msg) {
}

void InterfaceLog::log_rsp(std::string_view msg) {
p_impl_->log("RSP <- {}", msg);
if (p_impl_->dump_response()) {
p_impl_->log("RSP <- {}", msg);
}
}

void InterfaceLog::flush() {
Expand Down
1 change: 1 addition & 0 deletions silkworm/rpc/common/interface_log.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ struct InterfaceLogSettings {
std::size_t max_file_size_mb{1};
std::size_t max_files{100};
bool auto_flush{false};
bool dump_response{false};
};

class InterfaceLog final {
Expand Down
41 changes: 40 additions & 1 deletion silkworm/rpc/common/interface_log_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@

namespace silkworm::rpc {

TEST_CASE("InterfaceLog basic", "[rpc][common][interface_log]") {
TEST_CASE("InterfaceLog dump: full (req+rsp)", "[rpc][common][interface_log]") {
const auto tmp_dir{TemporaryDirectory::get_unique_temporary_path()};
InterfaceLogSettings settings{
.enabled = true,
.ifc_name = "eth_rpc",
.container_folder = tmp_dir,
.dump_response = true,
};
auto ifc_log{std::make_unique<InterfaceLog>(settings)};
REQUIRE(!ifc_log->path().empty());
Expand Down Expand Up @@ -68,4 +69,42 @@ TEST_CASE("InterfaceLog basic", "[rpc][common][interface_log]") {
CHECK(log_ifstream.eof());
}

TEST_CASE("InterfaceLog dump: default (only req)", "[rpc][common][interface_log]") {
const auto tmp_dir{TemporaryDirectory::get_unique_temporary_path()};
InterfaceLogSettings settings{
.enabled = true,
.ifc_name = "eth_rpc",
.container_folder = tmp_dir,
};
auto ifc_log{std::make_unique<InterfaceLog>(settings)};
REQUIRE(!ifc_log->path().empty());
ifc_log->log_req(R"({"json":"2.0"})");
ifc_log->log_rsp(R"({"json":"2.0"})");
std::ifstream log_ifstream{ifc_log->path().string()};

// Log file must be empty before flushing
CHECK(log_ifstream.get() == -1);
CHECK(log_ifstream.eof());
log_ifstream.clear();
log_ifstream.seekg(0);

SECTION("explicit flush") {
// InterfaceLog instance gets flushed here but remains alive until the end
ifc_log->flush();
}

SECTION("implicit flush") {
// InterfaceLog instance gets destroyed here and implicitly flushed
ifc_log.reset();
}

// First line must be the request
std::string content;
std::getline(log_ifstream, content);
CHECK(absl::StrContains(content, R"(REQ -> {"json":"2.0"})"));
// No other content is present
CHECK(log_ifstream.get() == -1);
CHECK(log_ifstream.eof());
}

} // namespace silkworm::rpc

0 comments on commit bbc3c91

Please sign in to comment.