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 <stdint.h> 21 22 #include <map> 23 #include <string> 24 #include <vector> 25 26 #include "src/trace_processor/importers/common/chunked_trace_reader.h" 27 #include "src/trace_processor/importers/common/trace_parser.h" 28 29 namespace perfetto { 30 namespace trace_processor { 31 32 class TraceProcessorContext; 33 34 // This class parses Ninja's (the build system, ninja-build.org) build logs and 35 // turns them into traces. A ninja log typically contains the logs of >1 ninja 36 // invocation. We map those as follows: 37 // - For each ninja invocation we create one process in the trace (from the UI 38 // perspective a process is a group of tracks). 39 // - Within each invocation we work out the parallelism from the time stamp and 40 // create one thread for each concurent stream of jobs. 41 // Caveat: this works only if ninja didn't recompact the logs. Once recompaction 42 // happens (can be forced via ninja -t recompact) there is no way to identify 43 // the boundaries of each build (recompaction deletes, for each hash, all but 44 // the most recent timestamp and rewrites the log). 45 class NinjaLogParser : public ChunkedTraceReader { 46 public: 47 explicit NinjaLogParser(TraceProcessorContext*); 48 ~NinjaLogParser() override; 49 NinjaLogParser(const NinjaLogParser&) = delete; 50 NinjaLogParser& operator=(const NinjaLogParser&) = delete; 51 52 // ChunkedTraceReader implementation 53 util::Status Parse(std::unique_ptr<uint8_t[]>, size_t) override; 54 void NotifyEndOfFile() override; 55 56 private: 57 struct Job { JobJob58 Job(uint32_t b, int64_t s, int64_t e, uint64_t h, const std::string& n) 59 : build_id(b), start_ms(s), end_ms(e), hash(h), names(n) {} 60 61 uint32_t build_id; // The synthesized PID of the build "process". 62 int64_t start_ms; 63 int64_t end_ms; 64 uint64_t hash; // Hash of the compiler invocation cmdline. 65 66 // Typically the one output for the compiler invocation. In case of actions 67 // generating multiple outputs this contains the join of all output names. 68 std::string names; 69 }; 70 71 TraceProcessorContext* const ctx_; 72 bool header_parsed_ = false; 73 int64_t last_end_seen_ = 0; 74 uint32_t cur_build_id_ = 0; 75 std::vector<Job> jobs_; 76 std::vector<char> log_; 77 }; 78 79 } // namespace trace_processor 80 } // namespace perfetto 81 82 #endif // SRC_TRACE_PROCESSOR_IMPORTERS_NINJA_NINJA_LOG_PARSER_H_ 83