xref: /aosp_15_r20/art/libartbase/base/metrics/metrics_common.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
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