1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef SRC_TRACE_PROCESSOR_IMPORTERS_NINJA_NINJA_LOG_PARSER_H_ 18 #define SRC_TRACE_PROCESSOR_IMPORTERS_NINJA_NINJA_LOG_PARSER_H_ 19 20 #include <cstdint> 21 #include <string> 22 #include <vector> 23 24 #include "perfetto/base/status.h" 25 #include "src/trace_processor/importers/common/chunked_trace_reader.h" 26 #include "src/trace_processor/importers/common/trace_parser.h" 27 28 namespace perfetto::trace_processor { 29 30 class TraceProcessorContext; 31 32 // This class parses Ninja's (the build system, ninja-build.org) build logs and 33 // turns them into traces. A ninja log typically contains the logs of >1 ninja 34 // invocation. We map those as follows: 35 // - For each ninja invocation we create one process in the trace (from the UI 36 // perspective a process is a group of tracks). 37 // - Within each invocation we work out the parallelism from the time stamp and 38 // create one thread for each concurent stream of jobs. 39 // Caveat: this works only if ninja didn't recompact the logs. Once recompaction 40 // happens (can be forced via ninja -t recompact) there is no way to identify 41 // the boundaries of each build (recompaction deletes, for each hash, all but 42 // the most recent timestamp and rewrites the log). 43 class NinjaLogParser : public ChunkedTraceReader { 44 public: 45 explicit NinjaLogParser(TraceProcessorContext*); 46 ~NinjaLogParser() override; 47 NinjaLogParser(const NinjaLogParser&) = delete; 48 NinjaLogParser& operator=(const NinjaLogParser&) = delete; 49 50 // ChunkedTraceReader implementation 51 base::Status Parse(TraceBlobView) override; 52 base::Status NotifyEndOfFile() override; 53 54 private: 55 struct Job { JobJob56 Job(int64_t s, int64_t e, uint64_t h, const std::string& n) 57 : start_ms(s), end_ms(e), hash(h), names(n) {} 58 59 int64_t start_ms; 60 int64_t end_ms; 61 uint64_t hash; // Hash of the compiler invocation cmdline. 62 63 // Typically the one output for the compiler invocation. In case of actions 64 // generating multiple outputs this contains the join of all output names. 65 std::string names; 66 }; 67 68 TraceProcessorContext* const ctx_; 69 bool header_parsed_ = false; 70 std::vector<Job> jobs_; 71 std::vector<char> log_; 72 }; 73 74 } // namespace perfetto::trace_processor 75 76 #endif // SRC_TRACE_PROCESSOR_IMPORTERS_NINJA_NINJA_LOG_PARSER_H_ 77