diff options
author | Matthias Maennich <maennich@google.com> | 2021-11-18 16:52:24 +0000 |
---|---|---|
committer | Matthias Maennich <maennich@google.com> | 2021-11-20 22:14:55 +0000 |
commit | 599c4393aed38adba5d42a9fe17228bea6d07d52 (patch) | |
tree | ce43f58becdd85633ed902e4b200af63639cd54b | |
parent | 40563db38b39bc09c40eed8f833f06d1e14b35bc (diff) | |
download | build-tools-599c4393aed38adba5d42a9fe17228bea6d07d52.tar.gz |
interceptor: replace JSON log by proto log
This implements serialization of commands to a corresponding protobuf
based log protocol. Child processes append log::Message to the log
(currently this implies a 'Command'). The parent process will reread the
log before terminating and will combine the log to a more compact
log::Log for further processing.
Bug: 205577427
Signed-off-by: Matthias Maennich <maennich@google.com>
Change-Id: I29cde728601fc3796f9b3ff0ff1b1d030bb86678
-rw-r--r-- | interceptor/Android.bp | 2 | ||||
-rw-r--r-- | interceptor/interceptor.cc | 25 | ||||
-rw-r--r-- | interceptor/interceptor.h | 3 | ||||
-rw-r--r-- | interceptor/main.cc | 31 |
4 files changed, 52 insertions, 9 deletions
diff --git a/interceptor/Android.bp b/interceptor/Android.bp index 85081c5..56ea6b2 100644 --- a/interceptor/Android.bp +++ b/interceptor/Android.bp @@ -2,6 +2,8 @@ cc_defaults { name: "interceptor_defaults", static_libs: [ "libc++fs", + "libinterceptor_log", + "libprotobuf-cpp-full", ], } diff --git a/interceptor/interceptor.cc b/interceptor/interceptor.cc index 0a52870..f31b343 100644 --- a/interceptor/interceptor.cc +++ b/interceptor/interceptor.cc @@ -35,6 +35,7 @@ #include <utility> #include <android-base/strings.h> +#include <google/protobuf/util/delimited_message_util.h> namespace fs = std::filesystem; @@ -44,7 +45,7 @@ namespace fs = std::filesystem; static void process_command(const char* filename, char* const argv[], char* const envp[]); // log command if logging is enabled -static void log(const interceptor::Command&, const std::string& prefix); +static void log(const interceptor::Command&); // execute potentially modified command static void exec(const interceptor::Command&); @@ -144,6 +145,19 @@ std::string Command::repr() const { return os.str(); } +log::Message Command::message() const { + log::Message result; + auto& command = *result.mutable_command(); + + command.set_program(program_); + *command.mutable_args() = {args().cbegin(), args().cend()}; + command.set_current_dir(cwd_); + *command.mutable_outputs() = {outputs().cbegin(), outputs().cend()}; + *command.mutable_inputs() = {inputs().cbegin(), inputs().cend()}; + + return result; +} + void Command::make_relative() { // determine the ROOT_DIR std::string root_dir; @@ -315,20 +329,21 @@ static void process_command(const char* filename, char* const argv[], char* cons command.analyze(); - log(command, ""); + log(command); // pass down the transformed command to execve exec(command); } -static void log(const interceptor::Command& command, const std::string& prefix) { +static void log(const interceptor::Command& command) { const auto& env = command.env(); if (const auto env_it = env.find(ENV_command_log); env_it != env.cend()) { std::ofstream file; - file.open(std::string(env_it->second), std::ofstream::out | std::ofstream::app); + file.open(std::string(env_it->second), + std::ofstream::out | std::ofstream::app | std::ofstream::binary); if (file.is_open()) { - file << prefix << command.repr() << ",\n"; + google::protobuf::util::SerializeDelimitedToOstream(command.message(), &file); } } } diff --git a/interceptor/interceptor.h b/interceptor/interceptor.h index f7ecae7..9e9a1e8 100644 --- a/interceptor/interceptor.h +++ b/interceptor/interceptor.h @@ -20,6 +20,8 @@ #include <unordered_map> #include <vector> +#include "log.pb.h" + // Options passed via environment variables from the interceptor starter constexpr static auto ENV_command_log = "INTERCEPTOR_command_log"; constexpr static auto ENV_root_dir = "INTERCEPTOR_root_dir"; @@ -51,6 +53,7 @@ class Command { const Outputs& outputs() const { return outputs_; } std::string repr() const; + log::Message message() const; // make command line calls relative to ROOT_DIR void make_relative(); diff --git a/interceptor/main.cc b/interceptor/main.cc index ae3d623..e9184e6 100644 --- a/interceptor/main.cc +++ b/interceptor/main.cc @@ -16,6 +16,7 @@ #include <getopt.h> #include <stdlib.h> +#include <sysexits.h> #include <cstdlib> #include <filesystem> #include <fstream> @@ -23,6 +24,8 @@ #include <optional> #include <sstream> +#include <google/protobuf/util/delimited_message_util.h> + #include "interceptor.h" namespace fs = std::filesystem; @@ -79,7 +82,7 @@ static void setup_interceptor_library_path() { interceptor_library = fs::read_symlink(interceptor_library); if (!fs::is_regular_file(interceptor_library)) { std::cerr << "Interceptor library could not be found!\n"; - exit(1); + exit(EX_CONFIG); } setenv("LD_PRELOAD", interceptor_library.c_str(), 1); } @@ -101,14 +104,32 @@ class CommandLog { if (command_log_file_) { setenv(ENV_command_log, command_log_file_->c_str(), 1); std::ofstream command_log(command_log_file_->c_str(), std::ios_base::trunc); - command_log << "[\n"; + if (!command_log) { + std::cerr << "Could not open command log for writing: " << *command_log_file_ << "\n"; + exit(EX_CANTCREAT); + } } } ~CommandLog() { if (command_log_file_) { - std::ofstream command_log(command_log_file_->c_str(), std::ios_base::app); - command_log << "]\n"; + // compact the log by re-reading the individual log::Message's to combine + // them to a log::Log + interceptor::log::Log log; + { + std::ifstream command_log(command_log_file_->c_str(), std::ios_base::binary); + + google::protobuf::io::IstreamInputStream input_stream(&command_log); + interceptor::log::Message message; + while (true) { + if (!google::protobuf::util::ParseDelimitedFromZeroCopyStream(&message, &input_stream, + nullptr)) + break; + if (message.has_command()) log.add_commands()->Swap(message.release_command()); + } + } + std::ofstream command_log(command_log_file_->c_str(), std::ios_base::binary); + log.SerializeToOstream(&command_log); } } }; @@ -121,5 +142,7 @@ int main(int argc, char* argv[]) { CommandLog command_log(options.command_log); + // TODO: cleanly to google::protobuf::ShutdownProtobufLibrary(); + return std::system(options.command_line.c_str()); } |