• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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