blob: c8c8701327696c815f3eeb150373858566c17683 [file] [log] [blame]
Eric Holk480d9812021-01-27 23:41:45 +00001/*
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#include <sstream>
18
Eric Holkc7ac91b2021-02-04 21:44:01 +000019#include "android-base/file.h"
Eric Holk480d9812021-01-27 23:41:45 +000020#include "android-base/logging.h"
21#include "base/macros.h"
Eric Holkc7ac91b2021-02-04 21:44:01 +000022#include "base/scoped_flock.h"
Eric Holk480d9812021-01-27 23:41:45 +000023#include "metrics.h"
24
25#pragma clang diagnostic push
26#pragma clang diagnostic error "-Wconversion"
27
28namespace art {
29namespace metrics {
30
31std::string DatumName(DatumId datum) {
32 switch (datum) {
Eric Holka4c87952021-03-05 17:58:17 -080033#define ART_METRIC(name, Kind, ...) \
Eric Holk480d9812021-01-27 23:41:45 +000034 case DatumId::k##name: \
35 return #name;
Eric Holka4c87952021-03-05 17:58:17 -080036 ART_METRICS(ART_METRIC)
37#undef ART_METRIC
Eric Holk480d9812021-01-27 23:41:45 +000038
39 default:
40 LOG(FATAL) << "Unknown datum id: " << static_cast<unsigned>(datum);
41 UNREACHABLE();
42 }
43}
44
Eric Holkc7ac91b2021-02-04 21:44:01 +000045SessionData SessionData::CreateDefault() {
46#ifdef _WIN32
47 int32_t uid = kInvalidUserId; // Windows does not support getuid();
48#else
49 int32_t uid = static_cast<int32_t>(getuid());
50#endif
51
52 return SessionData{
53 .compilation_reason = CompilationReason::kUnknown,
54 .compiler_filter = std::nullopt,
55 .session_id = kInvalidSessionId,
56 .uid = uid,
57 };
58}
59
60ArtMetrics::ArtMetrics() : beginning_timestamp_ {MilliTime()}
Eric Holka4c87952021-03-05 17:58:17 -080061#define ART_METRIC(name, Kind, ...) \
Eric Holk480d9812021-01-27 23:41:45 +000062 , name##_ {}
Eric Holka4c87952021-03-05 17:58:17 -080063ART_METRICS(ART_METRIC)
64#undef ART_METRIC
Eric Holk480d9812021-01-27 23:41:45 +000065{
66}
67
68void ArtMetrics::ReportAllMetrics(MetricsBackend* backend) const {
Eric Holkc7ac91b2021-02-04 21:44:01 +000069 backend->BeginReport(MilliTime() - beginning_timestamp_);
70
Eric Holka4c87952021-03-05 17:58:17 -080071#define ART_METRIC(name, Kind, ...) name()->Report(backend);
72 ART_METRICS(ART_METRIC)
Eric Holkd91328f2021-03-17 16:21:51 -070073#undef ART_METRIC
Eric Holkc7ac91b2021-02-04 21:44:01 +000074
75 backend->EndReport();
Eric Holk480d9812021-01-27 23:41:45 +000076}
77
78void ArtMetrics::DumpForSigQuit(std::ostream& os) const {
Eric Holkc7ac91b2021-02-04 21:44:01 +000079 StringBackend backend;
Eric Holk480d9812021-01-27 23:41:45 +000080 ReportAllMetrics(&backend);
Eric Holkc7ac91b2021-02-04 21:44:01 +000081 os << backend.GetAndResetBuffer();
Eric Holk480d9812021-01-27 23:41:45 +000082}
83
Eric Holkd91328f2021-03-17 16:21:51 -070084void ArtMetrics::Reset() {
85 beginning_timestamp_ = MilliTime();
86#define ART_METRIC(name, kind, ...) name##_.Reset();
87 ART_METRICS(ART_METRIC);
88#undef ART_METRIC
89}
90
Eric Holkc7ac91b2021-02-04 21:44:01 +000091StringBackend::StringBackend() {}
Eric Holk480d9812021-01-27 23:41:45 +000092
Eric Holkc7ac91b2021-02-04 21:44:01 +000093std::string StringBackend::GetAndResetBuffer() {
94 std::string result = os_.str();
95 os_.clear();
96 os_.str("");
97 return result;
Eric Holk480d9812021-01-27 23:41:45 +000098}
99
Eric Holkc7ac91b2021-02-04 21:44:01 +0000100void StringBackend::BeginSession(const SessionData& session_data) {
101 session_data_ = session_data;
Eric Holk480d9812021-01-27 23:41:45 +0000102}
103
Eric Holkc7ac91b2021-02-04 21:44:01 +0000104void StringBackend::BeginReport(uint64_t timestamp_since_start_ms) {
105 os_ << "\n*** ART internal metrics ***\n";
106 os_ << " Metadata:\n";
107 os_ << " timestamp_since_start_ms: " << timestamp_since_start_ms << "\n";
108 if (session_data_.has_value()) {
109 os_ << " session_id: " << session_data_->session_id << "\n";
110 os_ << " uid: " << session_data_->uid << "\n";
111 os_ << " compilation_reason: " << CompilationReasonName(session_data_->compilation_reason)
112 << "\n";
113 os_ << " compiler_filter: "
114 << (session_data_->compiler_filter.has_value()
115 ? CompilerFilter::NameOfFilter(session_data_->compiler_filter.value())
116 : "(unspecified)")
117 << "\n";
118 }
119 os_ << " Metrics:\n";
Eric Holk480d9812021-01-27 23:41:45 +0000120}
121
Eric Holkc7ac91b2021-02-04 21:44:01 +0000122void StringBackend::EndReport() { os_ << "*** Done dumping ART internal metrics ***\n"; }
123
124void StringBackend::ReportCounter(DatumId counter_type, uint64_t value) {
125 os_ << " " << DatumName(counter_type) << ": count = " << value << "\n";
126}
127
128void StringBackend::ReportHistogram(DatumId histogram_type,
Eric Holk480d9812021-01-27 23:41:45 +0000129 int64_t minimum_value_,
130 int64_t maximum_value_,
131 const std::vector<uint32_t>& buckets) {
Eric Holkc7ac91b2021-02-04 21:44:01 +0000132 os_ << " " << DatumName(histogram_type) << ": range = " << minimum_value_ << "..." << maximum_value_;
Eric Holk480d9812021-01-27 23:41:45 +0000133 if (buckets.size() > 0) {
134 os_ << ", buckets: ";
135 bool first = true;
136 for (const auto& count : buckets) {
137 if (!first) {
138 os_ << ",";
139 }
140 first = false;
141 os_ << count;
142 }
143 os_ << "\n";
144 } else {
145 os_ << ", no buckets\n";
146 }
147}
148
Eric Holkc7ac91b2021-02-04 21:44:01 +0000149LogBackend::LogBackend(android::base::LogSeverity level) : level_{level} {}
150
151void LogBackend::BeginReport(uint64_t timestamp_since_start_ms) {
152 GetAndResetBuffer();
153 StringBackend::BeginReport(timestamp_since_start_ms);
154}
155
156void LogBackend::EndReport() {
157 StringBackend::EndReport();
158 LOG_STREAM(level_) << GetAndResetBuffer();
159}
160
Greg Kaiser271662c2021-02-10 06:44:08 -0800161FileBackend::FileBackend(const std::string& filename) : filename_{filename} {}
Eric Holkc7ac91b2021-02-04 21:44:01 +0000162
163void FileBackend::BeginReport(uint64_t timestamp_since_start_ms) {
164 GetAndResetBuffer();
165 StringBackend::BeginReport(timestamp_since_start_ms);
166}
167
168void FileBackend::EndReport() {
169 StringBackend::EndReport();
170 std::string error_message;
171 auto file{
172 LockedFile::Open(filename_.c_str(), O_CREAT | O_WRONLY | O_APPEND, true, &error_message)};
173 if (file.get() == nullptr) {
174 LOG(WARNING) << "Could open metrics file '" << filename_ << "': " << error_message;
175 } else {
176 if (!android::base::WriteStringToFd(GetAndResetBuffer(), file.get()->Fd())) {
177 PLOG(WARNING) << "Error writing metrics to file";
178 }
179 }
180}
181
Eric Holk722992f2021-04-06 23:12:17 +0000182// Make sure CompilationReasonName and CompilationReasonForName are inverses.
183static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kError)) ==
184 CompilationReason::kError);
185static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kUnknown)) ==
186 CompilationReason::kUnknown);
187static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kFirstBoot)) ==
188 CompilationReason::kFirstBoot);
189static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kBootAfterOTA)) ==
190 CompilationReason::kBootAfterOTA);
191static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kPostBoot)) ==
192 CompilationReason::kPostBoot);
193static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kInstall)) ==
194 CompilationReason::kInstall);
195static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kInstallFast)) ==
196 CompilationReason::kInstallFast);
197static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kInstallBulk)) ==
198 CompilationReason::kInstallBulk);
199static_assert(
200 CompilationReasonFromName(CompilationReasonName(CompilationReason::kInstallBulkSecondary)) ==
201 CompilationReason::kInstallBulkSecondary);
202static_assert(
203 CompilationReasonFromName(CompilationReasonName(CompilationReason::kInstallBulkDowngraded)) ==
204 CompilationReason::kInstallBulkDowngraded);
205static_assert(CompilationReasonFromName(
206 CompilationReasonName(CompilationReason::kInstallBulkSecondaryDowngraded)) ==
207 CompilationReason::kInstallBulkSecondaryDowngraded);
208static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kBgDexopt)) ==
209 CompilationReason::kBgDexopt);
210static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kABOTA)) ==
211 CompilationReason::kABOTA);
212static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kInactive)) ==
213 CompilationReason::kInactive);
214static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kShared)) ==
215 CompilationReason::kShared);
216static_assert(
217 CompilationReasonFromName(CompilationReasonName(CompilationReason::kInstallWithDexMetadata)) ==
218 CompilationReason::kInstallWithDexMetadata);
Eric Holk7414ec22021-05-13 17:18:34 -0700219static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kPrebuilt)) ==
220 CompilationReason::kPrebuilt);
221static_assert(CompilationReasonFromName(CompilationReasonName(CompilationReason::kCmdLine)) ==
222 CompilationReason::kCmdLine);
Eric Holk722992f2021-04-06 23:12:17 +0000223
Eric Holk480d9812021-01-27 23:41:45 +0000224} // namespace metrics
225} // namespace art
226
227#pragma clang diagnostic pop // -Wconversion