1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2020 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker #include <sstream>
18*795d594fSAndroid Build Coastguard Worker
19*795d594fSAndroid Build Coastguard Worker #include "android-base/file.h"
20*795d594fSAndroid Build Coastguard Worker #include "android-base/logging.h"
21*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
22*795d594fSAndroid Build Coastguard Worker #include "base/scoped_flock.h"
23*795d594fSAndroid Build Coastguard Worker #include "metrics.h"
24*795d594fSAndroid Build Coastguard Worker
25*795d594fSAndroid Build Coastguard Worker #pragma clang diagnostic push
26*795d594fSAndroid Build Coastguard Worker #pragma clang diagnostic error "-Wconversion"
27*795d594fSAndroid Build Coastguard Worker
28*795d594fSAndroid Build Coastguard Worker namespace art {
29*795d594fSAndroid Build Coastguard Worker namespace metrics {
30*795d594fSAndroid Build Coastguard Worker
DatumName(DatumId datum)31*795d594fSAndroid Build Coastguard Worker std::string DatumName(DatumId datum) {
32*795d594fSAndroid Build Coastguard Worker switch (datum) {
33*795d594fSAndroid Build Coastguard Worker #define ART_METRIC(name, Kind, ...) \
34*795d594fSAndroid Build Coastguard Worker case DatumId::k##name: \
35*795d594fSAndroid Build Coastguard Worker return #name;
36*795d594fSAndroid Build Coastguard Worker ART_METRICS(ART_METRIC)
37*795d594fSAndroid Build Coastguard Worker #undef ART_METRIC
38*795d594fSAndroid Build Coastguard Worker
39*795d594fSAndroid Build Coastguard Worker default:
40*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Unknown datum id: " << static_cast<unsigned>(datum);
41*795d594fSAndroid Build Coastguard Worker UNREACHABLE();
42*795d594fSAndroid Build Coastguard Worker }
43*795d594fSAndroid Build Coastguard Worker }
44*795d594fSAndroid Build Coastguard Worker
CreateDefault()45*795d594fSAndroid Build Coastguard Worker SessionData SessionData::CreateDefault() {
46*795d594fSAndroid Build Coastguard Worker #ifdef _WIN32
47*795d594fSAndroid Build Coastguard Worker int32_t uid = kInvalidUserId; // Windows does not support getuid();
48*795d594fSAndroid Build Coastguard Worker #else
49*795d594fSAndroid Build Coastguard Worker int32_t uid = static_cast<int32_t>(getuid());
50*795d594fSAndroid Build Coastguard Worker #endif
51*795d594fSAndroid Build Coastguard Worker
52*795d594fSAndroid Build Coastguard Worker return SessionData{
53*795d594fSAndroid Build Coastguard Worker .session_id = kInvalidSessionId,
54*795d594fSAndroid Build Coastguard Worker .uid = uid,
55*795d594fSAndroid Build Coastguard Worker .compilation_reason = CompilationReason::kUnknown,
56*795d594fSAndroid Build Coastguard Worker .compiler_filter = CompilerFilterReporting::kUnknown,
57*795d594fSAndroid Build Coastguard Worker };
58*795d594fSAndroid Build Coastguard Worker }
59*795d594fSAndroid Build Coastguard Worker
ArtMetrics()60*795d594fSAndroid Build Coastguard Worker ArtMetrics::ArtMetrics()
61*795d594fSAndroid Build Coastguard Worker : beginning_timestamp_{MilliTime()},
62*795d594fSAndroid Build Coastguard Worker last_report_timestamp_{beginning_timestamp_}
63*795d594fSAndroid Build Coastguard Worker #define ART_METRIC(name, Kind, ...) \
64*795d594fSAndroid Build Coastguard Worker , name##_ {}
65*795d594fSAndroid Build Coastguard Worker ART_METRICS(ART_METRIC)
66*795d594fSAndroid Build Coastguard Worker #undef ART_METRIC
67*795d594fSAndroid Build Coastguard Worker {
68*795d594fSAndroid Build Coastguard Worker }
69*795d594fSAndroid Build Coastguard Worker
ReportAllMetricsAndResetValueMetrics(const std::vector<MetricsBackend * > & backends)70*795d594fSAndroid Build Coastguard Worker void ArtMetrics::ReportAllMetricsAndResetValueMetrics(
71*795d594fSAndroid Build Coastguard Worker const std::vector<MetricsBackend*>& backends) {
72*795d594fSAndroid Build Coastguard Worker uint64_t current_timestamp_ = MilliTime();
73*795d594fSAndroid Build Coastguard Worker for (auto& backend : backends) {
74*795d594fSAndroid Build Coastguard Worker backend->BeginReport(current_timestamp_ - beginning_timestamp_);
75*795d594fSAndroid Build Coastguard Worker }
76*795d594fSAndroid Build Coastguard Worker
77*795d594fSAndroid Build Coastguard Worker #define REPORT_METRIC(name, Kind, ...) name()->Report(backends);
78*795d594fSAndroid Build Coastguard Worker ART_EVENT_METRICS(REPORT_METRIC)
79*795d594fSAndroid Build Coastguard Worker #undef REPORT_METRIC
80*795d594fSAndroid Build Coastguard Worker
81*795d594fSAndroid Build Coastguard Worker // Update ART_DATUM_DELTA_TIME_ELAPSED_MS before ART Value Metrics are reported.
82*795d594fSAndroid Build Coastguard Worker TimeElapsedDelta()->Add(current_timestamp_ - last_report_timestamp_);
83*795d594fSAndroid Build Coastguard Worker
84*795d594fSAndroid Build Coastguard Worker #define REPORT_METRIC(name, Kind, ...) name()->ReportAndReset(backends);
85*795d594fSAndroid Build Coastguard Worker ART_VALUE_METRICS(REPORT_METRIC)
86*795d594fSAndroid Build Coastguard Worker #undef REPORT_METRIC
87*795d594fSAndroid Build Coastguard Worker
88*795d594fSAndroid Build Coastguard Worker for (auto& backend : backends) {
89*795d594fSAndroid Build Coastguard Worker backend->EndReport();
90*795d594fSAndroid Build Coastguard Worker }
91*795d594fSAndroid Build Coastguard Worker
92*795d594fSAndroid Build Coastguard Worker // Save the current timestamp to be able to calculate the elapsed time for the next report cycle.
93*795d594fSAndroid Build Coastguard Worker last_report_timestamp_ = current_timestamp_;
94*795d594fSAndroid Build Coastguard Worker }
95*795d594fSAndroid Build Coastguard Worker
DumpForSigQuit(std::ostream & os)96*795d594fSAndroid Build Coastguard Worker void ArtMetrics::DumpForSigQuit(std::ostream& os) {
97*795d594fSAndroid Build Coastguard Worker StringBackend backend(std::make_unique<TextFormatter>());
98*795d594fSAndroid Build Coastguard Worker ReportAllMetricsAndResetValueMetrics({&backend});
99*795d594fSAndroid Build Coastguard Worker os << backend.GetAndResetBuffer();
100*795d594fSAndroid Build Coastguard Worker }
101*795d594fSAndroid Build Coastguard Worker
Reset()102*795d594fSAndroid Build Coastguard Worker void ArtMetrics::Reset() {
103*795d594fSAndroid Build Coastguard Worker beginning_timestamp_ = MilliTime();
104*795d594fSAndroid Build Coastguard Worker #define RESET_METRIC(name, ...) name##_.Reset();
105*795d594fSAndroid Build Coastguard Worker ART_METRICS(RESET_METRIC)
106*795d594fSAndroid Build Coastguard Worker #undef RESET_METRIC
107*795d594fSAndroid Build Coastguard Worker }
108*795d594fSAndroid Build Coastguard Worker
StringBackend(std::unique_ptr<MetricsFormatter> formatter)109*795d594fSAndroid Build Coastguard Worker StringBackend::StringBackend(std::unique_ptr<MetricsFormatter> formatter)
110*795d594fSAndroid Build Coastguard Worker : formatter_(std::move(formatter)) {}
111*795d594fSAndroid Build Coastguard Worker
GetAndResetBuffer()112*795d594fSAndroid Build Coastguard Worker std::string StringBackend::GetAndResetBuffer() {
113*795d594fSAndroid Build Coastguard Worker return formatter_->GetAndResetBuffer();
114*795d594fSAndroid Build Coastguard Worker }
115*795d594fSAndroid Build Coastguard Worker
BeginOrUpdateSession(const SessionData & session_data)116*795d594fSAndroid Build Coastguard Worker void StringBackend::BeginOrUpdateSession(const SessionData& session_data) {
117*795d594fSAndroid Build Coastguard Worker session_data_ = session_data;
118*795d594fSAndroid Build Coastguard Worker }
119*795d594fSAndroid Build Coastguard Worker
BeginReport(uint64_t timestamp_since_start_ms)120*795d594fSAndroid Build Coastguard Worker void StringBackend::BeginReport(uint64_t timestamp_since_start_ms) {
121*795d594fSAndroid Build Coastguard Worker formatter_->FormatBeginReport(timestamp_since_start_ms, session_data_);
122*795d594fSAndroid Build Coastguard Worker }
123*795d594fSAndroid Build Coastguard Worker
EndReport()124*795d594fSAndroid Build Coastguard Worker void StringBackend::EndReport() {
125*795d594fSAndroid Build Coastguard Worker formatter_->FormatEndReport();
126*795d594fSAndroid Build Coastguard Worker }
127*795d594fSAndroid Build Coastguard Worker
ReportCounter(DatumId counter_type,uint64_t value)128*795d594fSAndroid Build Coastguard Worker void StringBackend::ReportCounter(DatumId counter_type, uint64_t value) {
129*795d594fSAndroid Build Coastguard Worker formatter_->FormatReportCounter(counter_type, value);
130*795d594fSAndroid Build Coastguard Worker }
131*795d594fSAndroid Build Coastguard Worker
ReportHistogram(DatumId histogram_type,int64_t minimum_value_,int64_t maximum_value_,const std::vector<uint32_t> & buckets)132*795d594fSAndroid Build Coastguard Worker void StringBackend::ReportHistogram(DatumId histogram_type,
133*795d594fSAndroid Build Coastguard Worker int64_t minimum_value_,
134*795d594fSAndroid Build Coastguard Worker int64_t maximum_value_,
135*795d594fSAndroid Build Coastguard Worker const std::vector<uint32_t>& buckets) {
136*795d594fSAndroid Build Coastguard Worker formatter_->FormatReportHistogram(histogram_type, minimum_value_, maximum_value_, buckets);
137*795d594fSAndroid Build Coastguard Worker }
138*795d594fSAndroid Build Coastguard Worker
FormatBeginReport(uint64_t timestamp_since_start_ms,const std::optional<SessionData> & session_data)139*795d594fSAndroid Build Coastguard Worker void TextFormatter::FormatBeginReport(uint64_t timestamp_since_start_ms,
140*795d594fSAndroid Build Coastguard Worker const std::optional<SessionData>& session_data) {
141*795d594fSAndroid Build Coastguard Worker os_ << "\n*** ART internal metrics ***\n";
142*795d594fSAndroid Build Coastguard Worker os_ << " Metadata:\n";
143*795d594fSAndroid Build Coastguard Worker os_ << " timestamp_since_start_ms: " << timestamp_since_start_ms << "\n";
144*795d594fSAndroid Build Coastguard Worker if (session_data.has_value()) {
145*795d594fSAndroid Build Coastguard Worker os_ << " session_id: " << session_data->session_id << "\n";
146*795d594fSAndroid Build Coastguard Worker os_ << " uid: " << session_data->uid << "\n";
147*795d594fSAndroid Build Coastguard Worker os_ << " compilation_reason: " << CompilationReasonName(session_data->compilation_reason)
148*795d594fSAndroid Build Coastguard Worker << "\n";
149*795d594fSAndroid Build Coastguard Worker os_ << " compiler_filter: " << CompilerFilterReportingName(session_data->compiler_filter)
150*795d594fSAndroid Build Coastguard Worker << "\n";
151*795d594fSAndroid Build Coastguard Worker }
152*795d594fSAndroid Build Coastguard Worker os_ << " Metrics:\n";
153*795d594fSAndroid Build Coastguard Worker }
154*795d594fSAndroid Build Coastguard Worker
FormatReportCounter(DatumId counter_type,uint64_t value)155*795d594fSAndroid Build Coastguard Worker void TextFormatter::FormatReportCounter(DatumId counter_type, uint64_t value) {
156*795d594fSAndroid Build Coastguard Worker os_ << " " << DatumName(counter_type) << ": count = " << value << "\n";
157*795d594fSAndroid Build Coastguard Worker }
158*795d594fSAndroid Build Coastguard Worker
FormatReportHistogram(DatumId histogram_type,int64_t minimum_value_,int64_t maximum_value_,const std::vector<uint32_t> & buckets)159*795d594fSAndroid Build Coastguard Worker void TextFormatter::FormatReportHistogram(DatumId histogram_type,
160*795d594fSAndroid Build Coastguard Worker int64_t minimum_value_,
161*795d594fSAndroid Build Coastguard Worker int64_t maximum_value_,
162*795d594fSAndroid Build Coastguard Worker const std::vector<uint32_t>& buckets) {
163*795d594fSAndroid Build Coastguard Worker os_ << " " << DatumName(histogram_type) << ": range = "
164*795d594fSAndroid Build Coastguard Worker << minimum_value_ << "..." << maximum_value_;
165*795d594fSAndroid Build Coastguard Worker if (!buckets.empty()) {
166*795d594fSAndroid Build Coastguard Worker os_ << ", buckets: ";
167*795d594fSAndroid Build Coastguard Worker bool first = true;
168*795d594fSAndroid Build Coastguard Worker for (const auto& count : buckets) {
169*795d594fSAndroid Build Coastguard Worker if (!first) {
170*795d594fSAndroid Build Coastguard Worker os_ << ",";
171*795d594fSAndroid Build Coastguard Worker }
172*795d594fSAndroid Build Coastguard Worker first = false;
173*795d594fSAndroid Build Coastguard Worker os_ << count;
174*795d594fSAndroid Build Coastguard Worker }
175*795d594fSAndroid Build Coastguard Worker os_ << "\n";
176*795d594fSAndroid Build Coastguard Worker } else {
177*795d594fSAndroid Build Coastguard Worker os_ << ", no buckets\n";
178*795d594fSAndroid Build Coastguard Worker }
179*795d594fSAndroid Build Coastguard Worker }
180*795d594fSAndroid Build Coastguard Worker
FormatEndReport()181*795d594fSAndroid Build Coastguard Worker void TextFormatter::FormatEndReport() {
182*795d594fSAndroid Build Coastguard Worker os_ << "*** Done dumping ART internal metrics ***\n";
183*795d594fSAndroid Build Coastguard Worker }
184*795d594fSAndroid Build Coastguard Worker
GetAndResetBuffer()185*795d594fSAndroid Build Coastguard Worker std::string TextFormatter::GetAndResetBuffer() {
186*795d594fSAndroid Build Coastguard Worker std::string result = os_.str();
187*795d594fSAndroid Build Coastguard Worker os_.clear();
188*795d594fSAndroid Build Coastguard Worker os_.str("");
189*795d594fSAndroid Build Coastguard Worker return result;
190*795d594fSAndroid Build Coastguard Worker }
191*795d594fSAndroid Build Coastguard Worker
FormatBeginReport(uint64_t timestamp_millis,const std::optional<SessionData> & session_data)192*795d594fSAndroid Build Coastguard Worker void XmlFormatter::FormatBeginReport(uint64_t timestamp_millis,
193*795d594fSAndroid Build Coastguard Worker const std::optional<SessionData>& session_data) {
194*795d594fSAndroid Build Coastguard Worker tinyxml2::XMLElement* art_runtime_metrics = document_.NewElement("art_runtime_metrics");
195*795d594fSAndroid Build Coastguard Worker document_.InsertEndChild(art_runtime_metrics);
196*795d594fSAndroid Build Coastguard Worker
197*795d594fSAndroid Build Coastguard Worker art_runtime_metrics->InsertNewChildElement("version")->SetText(version.data());
198*795d594fSAndroid Build Coastguard Worker
199*795d594fSAndroid Build Coastguard Worker tinyxml2::XMLElement* metadata = art_runtime_metrics->InsertNewChildElement("metadata");
200*795d594fSAndroid Build Coastguard Worker metadata->InsertNewChildElement("timestamp_since_start_ms")->SetText(timestamp_millis);
201*795d594fSAndroid Build Coastguard Worker
202*795d594fSAndroid Build Coastguard Worker if (session_data.has_value()) {
203*795d594fSAndroid Build Coastguard Worker metadata->InsertNewChildElement("session_id")->SetText(session_data->session_id);
204*795d594fSAndroid Build Coastguard Worker metadata->InsertNewChildElement("uid")->SetText(session_data->uid);
205*795d594fSAndroid Build Coastguard Worker metadata
206*795d594fSAndroid Build Coastguard Worker ->InsertNewChildElement("compilation_reason")
207*795d594fSAndroid Build Coastguard Worker ->SetText(CompilationReasonName(session_data->compilation_reason));
208*795d594fSAndroid Build Coastguard Worker metadata
209*795d594fSAndroid Build Coastguard Worker ->InsertNewChildElement("compiler_filter")
210*795d594fSAndroid Build Coastguard Worker ->SetText(CompilerFilterReportingName(session_data->compiler_filter));
211*795d594fSAndroid Build Coastguard Worker }
212*795d594fSAndroid Build Coastguard Worker
213*795d594fSAndroid Build Coastguard Worker art_runtime_metrics->InsertNewChildElement("metrics");
214*795d594fSAndroid Build Coastguard Worker }
215*795d594fSAndroid Build Coastguard Worker
FormatReportCounter(DatumId counter_type,uint64_t value)216*795d594fSAndroid Build Coastguard Worker void XmlFormatter::FormatReportCounter(DatumId counter_type, uint64_t value) {
217*795d594fSAndroid Build Coastguard Worker tinyxml2::XMLElement* metrics = document_.RootElement()->FirstChildElement("metrics");
218*795d594fSAndroid Build Coastguard Worker
219*795d594fSAndroid Build Coastguard Worker tinyxml2::XMLElement* counter = metrics->InsertNewChildElement(DatumName(counter_type).data());
220*795d594fSAndroid Build Coastguard Worker counter->InsertNewChildElement("counter_type")->SetText("count");
221*795d594fSAndroid Build Coastguard Worker counter->InsertNewChildElement("value")->SetText(value);
222*795d594fSAndroid Build Coastguard Worker }
223*795d594fSAndroid Build Coastguard Worker
FormatReportHistogram(DatumId histogram_type,int64_t low_value,int64_t high_value,const std::vector<uint32_t> & buckets)224*795d594fSAndroid Build Coastguard Worker void XmlFormatter::FormatReportHistogram(DatumId histogram_type,
225*795d594fSAndroid Build Coastguard Worker int64_t low_value,
226*795d594fSAndroid Build Coastguard Worker int64_t high_value,
227*795d594fSAndroid Build Coastguard Worker const std::vector<uint32_t>& buckets) {
228*795d594fSAndroid Build Coastguard Worker tinyxml2::XMLElement* metrics = document_.RootElement()->FirstChildElement("metrics");
229*795d594fSAndroid Build Coastguard Worker
230*795d594fSAndroid Build Coastguard Worker tinyxml2::XMLElement* histogram =
231*795d594fSAndroid Build Coastguard Worker metrics->InsertNewChildElement(DatumName(histogram_type).data());
232*795d594fSAndroid Build Coastguard Worker histogram->InsertNewChildElement("counter_type")->SetText("histogram");
233*795d594fSAndroid Build Coastguard Worker histogram->InsertNewChildElement("minimum_value")->SetText(low_value);
234*795d594fSAndroid Build Coastguard Worker histogram->InsertNewChildElement("maximum_value")->SetText(high_value);
235*795d594fSAndroid Build Coastguard Worker
236*795d594fSAndroid Build Coastguard Worker tinyxml2::XMLElement* buckets_element = histogram->InsertNewChildElement("buckets");
237*795d594fSAndroid Build Coastguard Worker for (const auto& count : buckets) {
238*795d594fSAndroid Build Coastguard Worker buckets_element->InsertNewChildElement("bucket")->SetText(count);
239*795d594fSAndroid Build Coastguard Worker }
240*795d594fSAndroid Build Coastguard Worker }
241*795d594fSAndroid Build Coastguard Worker
FormatEndReport()242*795d594fSAndroid Build Coastguard Worker void XmlFormatter::FormatEndReport() {}
243*795d594fSAndroid Build Coastguard Worker
GetAndResetBuffer()244*795d594fSAndroid Build Coastguard Worker std::string XmlFormatter::GetAndResetBuffer() {
245*795d594fSAndroid Build Coastguard Worker tinyxml2::XMLPrinter printer(/*file=*/nullptr, /*compact=*/true);
246*795d594fSAndroid Build Coastguard Worker document_.Print(&printer);
247*795d594fSAndroid Build Coastguard Worker std::string result = printer.CStr();
248*795d594fSAndroid Build Coastguard Worker document_.Clear();
249*795d594fSAndroid Build Coastguard Worker
250*795d594fSAndroid Build Coastguard Worker return result;
251*795d594fSAndroid Build Coastguard Worker }
252*795d594fSAndroid Build Coastguard Worker
LogBackend(std::unique_ptr<MetricsFormatter> formatter,android::base::LogSeverity level)253*795d594fSAndroid Build Coastguard Worker LogBackend::LogBackend(std::unique_ptr<MetricsFormatter> formatter,
254*795d594fSAndroid Build Coastguard Worker android::base::LogSeverity level)
255*795d594fSAndroid Build Coastguard Worker : StringBackend{std::move(formatter)}, level_{level}
256*795d594fSAndroid Build Coastguard Worker {}
257*795d594fSAndroid Build Coastguard Worker
BeginReport(uint64_t timestamp_since_start_ms)258*795d594fSAndroid Build Coastguard Worker void LogBackend::BeginReport(uint64_t timestamp_since_start_ms) {
259*795d594fSAndroid Build Coastguard Worker StringBackend::GetAndResetBuffer();
260*795d594fSAndroid Build Coastguard Worker StringBackend::BeginReport(timestamp_since_start_ms);
261*795d594fSAndroid Build Coastguard Worker }
262*795d594fSAndroid Build Coastguard Worker
EndReport()263*795d594fSAndroid Build Coastguard Worker void LogBackend::EndReport() {
264*795d594fSAndroid Build Coastguard Worker StringBackend::EndReport();
265*795d594fSAndroid Build Coastguard Worker LOG_STREAM(level_) << StringBackend::GetAndResetBuffer();
266*795d594fSAndroid Build Coastguard Worker }
267*795d594fSAndroid Build Coastguard Worker
FileBackend(std::unique_ptr<MetricsFormatter> formatter,const std::string & filename)268*795d594fSAndroid Build Coastguard Worker FileBackend::FileBackend(std::unique_ptr<MetricsFormatter> formatter,
269*795d594fSAndroid Build Coastguard Worker const std::string& filename)
270*795d594fSAndroid Build Coastguard Worker : StringBackend{std::move(formatter)}, filename_{filename}
271*795d594fSAndroid Build Coastguard Worker {}
272*795d594fSAndroid Build Coastguard Worker
BeginReport(uint64_t timestamp_since_start_ms)273*795d594fSAndroid Build Coastguard Worker void FileBackend::BeginReport(uint64_t timestamp_since_start_ms) {
274*795d594fSAndroid Build Coastguard Worker StringBackend::GetAndResetBuffer();
275*795d594fSAndroid Build Coastguard Worker StringBackend::BeginReport(timestamp_since_start_ms);
276*795d594fSAndroid Build Coastguard Worker }
277*795d594fSAndroid Build Coastguard Worker
EndReport()278*795d594fSAndroid Build Coastguard Worker void FileBackend::EndReport() {
279*795d594fSAndroid Build Coastguard Worker StringBackend::EndReport();
280*795d594fSAndroid Build Coastguard Worker std::string error_message;
281*795d594fSAndroid Build Coastguard Worker auto file{
282*795d594fSAndroid Build Coastguard Worker LockedFile::Open(filename_.c_str(), O_CREAT | O_WRONLY | O_APPEND, true, &error_message)};
283*795d594fSAndroid Build Coastguard Worker if (file.get() == nullptr) {
284*795d594fSAndroid Build Coastguard Worker LOG(WARNING) << "Could open metrics file '" << filename_ << "': " << error_message;
285*795d594fSAndroid Build Coastguard Worker } else {
286*795d594fSAndroid Build Coastguard Worker if (!android::base::WriteStringToFd(StringBackend::GetAndResetBuffer(), file.get()->Fd())) {
287*795d594fSAndroid Build Coastguard Worker PLOG(WARNING) << "Error writing metrics to file";
288*795d594fSAndroid Build Coastguard Worker }
289*795d594fSAndroid Build Coastguard Worker }
290*795d594fSAndroid Build Coastguard Worker }
291*795d594fSAndroid Build Coastguard Worker
292*795d594fSAndroid Build Coastguard Worker // Make sure CompilationReasonName and CompilationReasonForName are inverses.
293*795d594fSAndroid Build Coastguard Worker static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kError)) ==
294*795d594fSAndroid Build Coastguard Worker CompilationReason::kError);
295*795d594fSAndroid Build Coastguard Worker static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kUnknown)) ==
296*795d594fSAndroid Build Coastguard Worker CompilationReason::kUnknown);
297*795d594fSAndroid Build Coastguard Worker static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kFirstBoot)) ==
298*795d594fSAndroid Build Coastguard Worker CompilationReason::kFirstBoot);
299*795d594fSAndroid Build Coastguard Worker static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kBootAfterOTA)) ==
300*795d594fSAndroid Build Coastguard Worker CompilationReason::kBootAfterOTA);
301*795d594fSAndroid Build Coastguard Worker static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kPostBoot)) ==
302*795d594fSAndroid Build Coastguard Worker CompilationReason::kPostBoot);
303*795d594fSAndroid Build Coastguard Worker static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kInstall)) ==
304*795d594fSAndroid Build Coastguard Worker CompilationReason::kInstall);
305*795d594fSAndroid Build Coastguard Worker static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kInstallFast)) ==
306*795d594fSAndroid Build Coastguard Worker CompilationReason::kInstallFast);
307*795d594fSAndroid Build Coastguard Worker static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kInstallBulk)) ==
308*795d594fSAndroid Build Coastguard Worker CompilationReason::kInstallBulk);
309*795d594fSAndroid Build Coastguard Worker static_assert(
310*795d594fSAndroid Build Coastguard Worker CompilationReasonFromName(CompilationReasonName(CompilationReason::kInstallBulkSecondary)) ==
311*795d594fSAndroid Build Coastguard Worker CompilationReason::kInstallBulkSecondary);
312*795d594fSAndroid Build Coastguard Worker static_assert(
313*795d594fSAndroid Build Coastguard Worker CompilationReasonFromName(CompilationReasonName(CompilationReason::kInstallBulkDowngraded)) ==
314*795d594fSAndroid Build Coastguard Worker CompilationReason::kInstallBulkDowngraded);
315*795d594fSAndroid Build Coastguard Worker static_assert(CompilationReasonFromName(
316*795d594fSAndroid Build Coastguard Worker CompilationReasonName(CompilationReason::kInstallBulkSecondaryDowngraded)) ==
317*795d594fSAndroid Build Coastguard Worker CompilationReason::kInstallBulkSecondaryDowngraded);
318*795d594fSAndroid Build Coastguard Worker static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kBgDexopt)) ==
319*795d594fSAndroid Build Coastguard Worker CompilationReason::kBgDexopt);
320*795d594fSAndroid Build Coastguard Worker static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kABOTA)) ==
321*795d594fSAndroid Build Coastguard Worker CompilationReason::kABOTA);
322*795d594fSAndroid Build Coastguard Worker static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kInactive)) ==
323*795d594fSAndroid Build Coastguard Worker CompilationReason::kInactive);
324*795d594fSAndroid Build Coastguard Worker static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kShared)) ==
325*795d594fSAndroid Build Coastguard Worker CompilationReason::kShared);
326*795d594fSAndroid Build Coastguard Worker static_assert(
327*795d594fSAndroid Build Coastguard Worker CompilationReasonFromName(CompilationReasonName(CompilationReason::kInstallWithDexMetadata)) ==
328*795d594fSAndroid Build Coastguard Worker CompilationReason::kInstallWithDexMetadata);
329*795d594fSAndroid Build Coastguard Worker static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kPrebuilt)) ==
330*795d594fSAndroid Build Coastguard Worker CompilationReason::kPrebuilt);
331*795d594fSAndroid Build Coastguard Worker static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kCmdLine)) ==
332*795d594fSAndroid Build Coastguard Worker CompilationReason::kCmdLine);
333*795d594fSAndroid Build Coastguard Worker static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kVdex)) ==
334*795d594fSAndroid Build Coastguard Worker CompilationReason::kVdex);
335*795d594fSAndroid Build Coastguard Worker static_assert(
336*795d594fSAndroid Build Coastguard Worker CompilationReasonFromName(CompilationReasonName(CompilationReason::kBootAfterMainlineUpdate)) ==
337*795d594fSAndroid Build Coastguard Worker CompilationReason::kBootAfterMainlineUpdate);
338*795d594fSAndroid Build Coastguard Worker
339*795d594fSAndroid Build Coastguard Worker } // namespace metrics
340*795d594fSAndroid Build Coastguard Worker } // namespace art
341*795d594fSAndroid Build Coastguard Worker
342*795d594fSAndroid Build Coastguard Worker #pragma clang diagnostic pop // -Wconversion
343