diff options
author | Matthias Maennich <maennich@google.com> | 2021-11-18 23:55:59 +0000 |
---|---|---|
committer | Matthias Maennich <maennich@google.com> | 2021-11-20 22:14:55 +0000 |
commit | 818b6d5d22f3a571c54b6c563af087a5a68f5628 (patch) | |
tree | e3084540b930e9f6cf5fbf3a2a9bccfbd575eabf | |
parent | 599c4393aed38adba5d42a9fe17228bea6d07d52 (diff) | |
download | build-tools-818b6d5d22f3a571c54b6c563af087a5a68f5628.tar.gz |
Interceptor: initial analysis tooling
Add analysis tooling to process interceptor logs. As a first utility,
add --output-type text to dump the log as pb text.
Bug: 205577427
Signed-off-by: Matthias Maennich <maennich@google.com>
Change-Id: I10b3e46df6b7deb070710aa4ac9ab94a5486d43a
-rwxr-xr-x | build-prebuilts.sh | 1 | ||||
-rw-r--r-- | interceptor/Android.bp | 6 | ||||
-rw-r--r-- | interceptor/analysis.cc | 123 |
3 files changed, 130 insertions, 0 deletions
diff --git a/build-prebuilts.sh b/build-prebuilts.sh index 4a061c2..8925111 100755 --- a/build-prebuilts.sh +++ b/build-prebuilts.sh @@ -37,6 +37,7 @@ EOF e2fsdroid img2simg interceptor + interceptor_analysis lpmake lz4 mkbootfs diff --git a/interceptor/Android.bp b/interceptor/Android.bp index 56ea6b2..e944816 100644 --- a/interceptor/Android.bp +++ b/interceptor/Android.bp @@ -32,3 +32,9 @@ cc_binary_host { srcs: ["main.cc"], defaults: ["interceptor_defaults"], } + +cc_binary_host { + name: "interceptor_analysis", + srcs: ["analysis.cc",], + defaults: ["interceptor_defaults",], +} diff --git a/interceptor/analysis.cc b/interceptor/analysis.cc new file mode 100644 index 0000000..b7f1535 --- /dev/null +++ b/interceptor/analysis.cc @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <getopt.h> +#include <google/protobuf/text_format.h> +#include <sysexits.h> +#include <cstdlib> +#include <cstring> +#include <filesystem> +#include <fstream> +#include <iostream> +#include <iterator> + +#include "log.pb.h" + +namespace fs = std::filesystem; + +enum class OutputFormat { TEXT }; + +struct Options { + fs::path command_log; + OutputFormat output_format = OutputFormat::TEXT; + fs::path output; +}; + +static Options parse_args(int argc, char* argv[]) { + Options result; + + const static option opts[] = { + {"command-log", required_argument, nullptr, 'l'}, + {"output-type", required_argument, nullptr, 't'}, + {"output", required_argument, nullptr, 'o'}, + {nullptr, 0, nullptr, 0}, + }; + const auto usage = [&]() { + std::cerr << "usage: " << argv[0] << '\n' + << " -l|--command-log filename\n" + << " -o|--output filename\n" + << " [-t|--output-type (text)]\n"; + exit(EX_USAGE); + }; + while (true) { + int ix; + int c = getopt_long(argc, argv, "-l:f:o:", opts, &ix); + if (c == -1) break; + switch (c) { + case 'l': + result.command_log = fs::absolute(optarg); + break; + case 't': + if (strcmp(optarg, "text") == 0) + result.output_format = OutputFormat::TEXT; + else + usage(); + break; + case 'o': + result.output = fs::absolute(optarg); + break; + default: + usage(); + } + } + + if (result.command_log.empty() || result.output.empty()) { + usage(); + } + + if (!fs::exists(result.command_log)) { + std::cerr << "No such file: " << result.command_log << "\n"; + } + + return result; +} + +interceptor::log::Log read_log(const fs::path& log_file) { + interceptor::log::Log result; + std::ifstream input(log_file); + if (!input) { + std::cerr << "Could not open input file for reading.\n"; + exit(EX_NOINPUT); + } + result.ParseFromIstream(&input); + return result; +} + +void text_to_file(const interceptor::log::Log& log, const fs::path& output) { + std::string content; + google::protobuf::TextFormat::PrintToString(log, &content); + std::ofstream os(output); + if (!os) { + std::cerr << "Could not open output file for writing.\n"; + exit(EX_CANTCREAT); + } + os << content; + if (!os.flush()) { + std::cerr << "Failed to write to output file.\n"; + exit(EX_CANTCREAT); + } +} + +int main(int argc, char* argv[]) { + const auto options = parse_args(argc, argv); + const auto log = read_log(options.command_log); + + switch (options.output_format) { + case OutputFormat::TEXT: + text_to_file(log, options.output); + break; + } +} |