summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Maennich <maennich@google.com>2021-11-18 23:55:59 +0000
committerMatthias Maennich <maennich@google.com>2021-11-20 22:14:55 +0000
commit818b6d5d22f3a571c54b6c563af087a5a68f5628 (patch)
treee3084540b930e9f6cf5fbf3a2a9bccfbd575eabf
parent599c4393aed38adba5d42a9fe17228bea6d07d52 (diff)
downloadbuild-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-xbuild-prebuilts.sh1
-rw-r--r--interceptor/Android.bp6
-rw-r--r--interceptor/analysis.cc123
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;
+ }
+}