blob: b4b31d9daf6e5ebec75e774f05faf2a9770a8d6a [file] [log] [blame]
Fabien Sanglard2d34e762019-02-21 15:13:29 -08001/*
2 * Copyright (C) 2019 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#include "TraceBuffer.h"
18
19#include <chrono>
20#include <sstream>
21#include <unistd.h>
22#include <vector>
23
24#include <inttypes.h>
25
26#include "android-base/utf8.h"
27
28#include "util/Files.h"
29
30namespace aapt {
31namespace tracebuffer {
32
33namespace {
34
35constexpr char kBegin = 'B';
36constexpr char kEnd = 'E';
37
38struct TracePoint {
39 pid_t tid;
40 int64_t time;
41 std::string tag;
42 char type;
43};
44
45std::vector<TracePoint> traces;
46
47int64_t GetTime() noexcept {
48 auto now = std::chrono::steady_clock::now();
49 return std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()).count();
50}
51
52} // namespace anonymous
53
54void AddWithTime(const std::string& tag, char type, int64_t time) noexcept {
55 TracePoint t = {getpid(), time, tag, type};
56 traces.emplace_back(t);
57}
58
59void Add(const std::string& tag, char type) noexcept {
60 AddWithTime(tag, type, GetTime());
61}
62
63
64
65
66void Flush(const std::string& basePath) {
67 TRACE_CALL();
68 if (basePath.empty()) {
69 return;
70 }
71
72 std::stringstream s;
73 s << basePath << aapt::file::sDirSep << "report_aapt2_" << getpid() << ".json";
74 FILE* f = android::base::utf8::fopen(s.str().c_str(), "a");
75 if (f == nullptr) {
76 return;
77 }
78
79 for(const TracePoint& trace : traces) {
80 fprintf(f, "{\"ts\" : \"%" PRIu64 "\", \"ph\" : \"%c\", \"tid\" : \"%d\" , \"pid\" : \"%d\", "
81 "\"name\" : \"%s\" },\n", trace.time, trace.type, 0, trace.tid, trace.tag.c_str());
82 }
83 fclose(f);
84 traces.clear();
85}
86
87} // namespace tracebuffer
88
89void BeginTrace(const std::string& tag) {
90 tracebuffer::Add(tag, tracebuffer::kBegin);
91}
92
93void EndTrace() {
94 tracebuffer::Add("", tracebuffer::kEnd);
95}
96
97Trace::Trace(const std::string& tag) {
98 tracebuffer::Add(tag, tracebuffer::kBegin);
99}
100
101Trace::Trace(const std::string& tag, const std::vector<android::StringPiece>& args) {
102 std::stringstream s;
103 s << tag;
104 s << " ";
105 for (auto& arg : args) {
106 s << arg.to_string();
107 s << " ";
108 }
109 tracebuffer::Add(s.str(), tracebuffer::kBegin);
110}
111
112Trace::~Trace() {
113 tracebuffer::Add("", tracebuffer::kEnd);
114}
115
116FlushTrace::FlushTrace(const std::string& basepath, const std::string& tag)
117 : basepath_(basepath) {
118 tracebuffer::Add(tag, tracebuffer::kBegin);
119}
120
121FlushTrace::FlushTrace(const std::string& basepath, const std::string& tag,
122 const std::vector<android::StringPiece>& args) : basepath_(basepath) {
123 std::stringstream s;
124 s << tag;
125 s << " ";
126 for (auto& arg : args) {
127 s << arg.to_string();
128 s << " ";
129 }
130 tracebuffer::Add(s.str(), tracebuffer::kBegin);
131}
132
133FlushTrace::FlushTrace(const std::string& basepath, const std::string& tag,
134 const std::vector<std::string>& args) : basepath_(basepath){
135 std::stringstream s;
136 s << tag;
137 s << " ";
138 for (auto& arg : args) {
139 s << arg;
140 s << " ";
141 }
142 tracebuffer::Add(s.str(), tracebuffer::kBegin);
143}
144
145FlushTrace::~FlushTrace() {
146 tracebuffer::Add("", tracebuffer::kEnd);
147 tracebuffer::Flush(basepath_);
148}
149
150} // namespace aapt
151