blob: c650fdf760422880fb47a6bb11942cbf8497e265 [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) {
33#define ART_COUNTER(name) \
34 case DatumId::k##name: \
35 return #name;
36 ART_COUNTERS(ART_COUNTER)
37#undef ART_COUNTER
38
39#define ART_HISTOGRAM(name, num_buckets, low_value, high_value) \
40 case DatumId::k##name: \
41 return #name;
42 ART_HISTOGRAMS(ART_HISTOGRAM)
43#undef ART_HISTOGRAM
44
45 default:
46 LOG(FATAL) << "Unknown datum id: " << static_cast<unsigned>(datum);
47 UNREACHABLE();
48 }
49}
50
Eric Holkc7ac91b2021-02-04 21:44:01 +000051SessionData SessionData::CreateDefault() {
52#ifdef _WIN32
53 int32_t uid = kInvalidUserId; // Windows does not support getuid();
54#else
55 int32_t uid = static_cast<int32_t>(getuid());
56#endif
57
58 return SessionData{
59 .compilation_reason = CompilationReason::kUnknown,
60 .compiler_filter = std::nullopt,
61 .session_id = kInvalidSessionId,
62 .uid = uid,
63 };
64}
65
66ArtMetrics::ArtMetrics() : beginning_timestamp_ {MilliTime()}
Eric Holk480d9812021-01-27 23:41:45 +000067#define ART_COUNTER(name) \
68 , name##_ {}
69ART_COUNTERS(ART_COUNTER)
70#undef ART_COUNTER
71#define ART_HISTOGRAM(name, num_buckets, low_value, high_value) \
72 , name##_ {}
73ART_HISTOGRAMS(ART_HISTOGRAM)
74#undef ART_HISTOGRAM
75{
76}
77
78void ArtMetrics::ReportAllMetrics(MetricsBackend* backend) const {
Eric Holkc7ac91b2021-02-04 21:44:01 +000079 backend->BeginReport(MilliTime() - beginning_timestamp_);
80
Eric Holk480d9812021-01-27 23:41:45 +000081// Dump counters
82#define ART_COUNTER(name) name()->Report(backend);
83 ART_COUNTERS(ART_COUNTER)
84#undef ART_COUNTERS
85
86// Dump histograms
87#define ART_HISTOGRAM(name, num_buckets, low_value, high_value) name()->Report(backend);
88 ART_HISTOGRAMS(ART_HISTOGRAM)
89#undef ART_HISTOGRAM
Eric Holkc7ac91b2021-02-04 21:44:01 +000090
91 backend->EndReport();
Eric Holk480d9812021-01-27 23:41:45 +000092}
93
94void ArtMetrics::DumpForSigQuit(std::ostream& os) const {
Eric Holkc7ac91b2021-02-04 21:44:01 +000095 StringBackend backend;
Eric Holk480d9812021-01-27 23:41:45 +000096 ReportAllMetrics(&backend);
Eric Holkc7ac91b2021-02-04 21:44:01 +000097 os << backend.GetAndResetBuffer();
Eric Holk480d9812021-01-27 23:41:45 +000098}
99
Eric Holkc7ac91b2021-02-04 21:44:01 +0000100StringBackend::StringBackend() {}
Eric Holk480d9812021-01-27 23:41:45 +0000101
Eric Holkc7ac91b2021-02-04 21:44:01 +0000102std::string StringBackend::GetAndResetBuffer() {
103 std::string result = os_.str();
104 os_.clear();
105 os_.str("");
106 return result;
Eric Holk480d9812021-01-27 23:41:45 +0000107}
108
Eric Holkc7ac91b2021-02-04 21:44:01 +0000109void StringBackend::BeginSession(const SessionData& session_data) {
110 session_data_ = session_data;
Eric Holk480d9812021-01-27 23:41:45 +0000111}
112
Eric Holkc7ac91b2021-02-04 21:44:01 +0000113void StringBackend::BeginReport(uint64_t timestamp_since_start_ms) {
114 os_ << "\n*** ART internal metrics ***\n";
115 os_ << " Metadata:\n";
116 os_ << " timestamp_since_start_ms: " << timestamp_since_start_ms << "\n";
117 if (session_data_.has_value()) {
118 os_ << " session_id: " << session_data_->session_id << "\n";
119 os_ << " uid: " << session_data_->uid << "\n";
120 os_ << " compilation_reason: " << CompilationReasonName(session_data_->compilation_reason)
121 << "\n";
122 os_ << " compiler_filter: "
123 << (session_data_->compiler_filter.has_value()
124 ? CompilerFilter::NameOfFilter(session_data_->compiler_filter.value())
125 : "(unspecified)")
126 << "\n";
127 }
128 os_ << " Metrics:\n";
Eric Holk480d9812021-01-27 23:41:45 +0000129}
130
Eric Holkc7ac91b2021-02-04 21:44:01 +0000131void StringBackend::EndReport() { os_ << "*** Done dumping ART internal metrics ***\n"; }
132
133void StringBackend::ReportCounter(DatumId counter_type, uint64_t value) {
134 os_ << " " << DatumName(counter_type) << ": count = " << value << "\n";
135}
136
137void StringBackend::ReportHistogram(DatumId histogram_type,
Eric Holk480d9812021-01-27 23:41:45 +0000138 int64_t minimum_value_,
139 int64_t maximum_value_,
140 const std::vector<uint32_t>& buckets) {
Eric Holkc7ac91b2021-02-04 21:44:01 +0000141 os_ << " " << DatumName(histogram_type) << ": range = " << minimum_value_ << "..." << maximum_value_;
Eric Holk480d9812021-01-27 23:41:45 +0000142 if (buckets.size() > 0) {
143 os_ << ", buckets: ";
144 bool first = true;
145 for (const auto& count : buckets) {
146 if (!first) {
147 os_ << ",";
148 }
149 first = false;
150 os_ << count;
151 }
152 os_ << "\n";
153 } else {
154 os_ << ", no buckets\n";
155 }
156}
157
Eric Holkc7ac91b2021-02-04 21:44:01 +0000158LogBackend::LogBackend(android::base::LogSeverity level) : level_{level} {}
159
160void LogBackend::BeginReport(uint64_t timestamp_since_start_ms) {
161 GetAndResetBuffer();
162 StringBackend::BeginReport(timestamp_since_start_ms);
163}
164
165void LogBackend::EndReport() {
166 StringBackend::EndReport();
167 LOG_STREAM(level_) << GetAndResetBuffer();
168}
169
170FileBackend::FileBackend(std::string filename) : filename_{filename} {}
171
172void FileBackend::BeginReport(uint64_t timestamp_since_start_ms) {
173 GetAndResetBuffer();
174 StringBackend::BeginReport(timestamp_since_start_ms);
175}
176
177void FileBackend::EndReport() {
178 StringBackend::EndReport();
179 std::string error_message;
180 auto file{
181 LockedFile::Open(filename_.c_str(), O_CREAT | O_WRONLY | O_APPEND, true, &error_message)};
182 if (file.get() == nullptr) {
183 LOG(WARNING) << "Could open metrics file '" << filename_ << "': " << error_message;
184 } else {
185 if (!android::base::WriteStringToFd(GetAndResetBuffer(), file.get()->Fd())) {
186 PLOG(WARNING) << "Error writing metrics to file";
187 }
188 }
189}
190
Eric Holk480d9812021-01-27 23:41:45 +0000191} // namespace metrics
192} // namespace art
193
194#pragma clang diagnostic pop // -Wconversion