diff options
Diffstat (limited to 'libartbase/base/metrics/metrics_common.cc')
-rw-r--r-- | libartbase/base/metrics/metrics_common.cc | 148 |
1 files changed, 122 insertions, 26 deletions
diff --git a/libartbase/base/metrics/metrics_common.cc b/libartbase/base/metrics/metrics_common.cc index f09987ba8e..025f5eb79e 100644 --- a/libartbase/base/metrics/metrics_common.cc +++ b/libartbase/base/metrics/metrics_common.cc @@ -76,7 +76,7 @@ void ArtMetrics::ReportAllMetrics(MetricsBackend* backend) const { } void ArtMetrics::DumpForSigQuit(std::ostream& os) const { - StringBackend backend; + StringBackend backend(std::make_unique<TextFormatter>()); ReportAllMetrics(&backend); os << backend.GetAndResetBuffer(); } @@ -88,13 +88,12 @@ void ArtMetrics::Reset() { #undef ART_METRIC } -StringBackend::StringBackend() {} +StringBackend::StringBackend(std::unique_ptr<MetricsFormatter> formatter) + : formatter_(std::move(formatter)) +{} std::string StringBackend::GetAndResetBuffer() { - std::string result = os_.str(); - os_.clear(); - os_.str(""); - return result; + return formatter_->GetAndResetBuffer(); } void StringBackend::BeginOrUpdateSession(const SessionData& session_data) { @@ -102,32 +101,51 @@ void StringBackend::BeginOrUpdateSession(const SessionData& session_data) { } void StringBackend::BeginReport(uint64_t timestamp_since_start_ms) { + formatter_->FormatBeginReport(timestamp_since_start_ms, session_data_); +} + +void StringBackend::EndReport() { + formatter_->FormatEndReport(); +} + +void StringBackend::ReportCounter(DatumId counter_type, uint64_t value) { + formatter_->FormatReportCounter(counter_type, value); +} + +void StringBackend::ReportHistogram(DatumId histogram_type, + int64_t minimum_value_, + int64_t maximum_value_, + const std::vector<uint32_t>& buckets) { + formatter_->FormatReportHistogram(histogram_type, minimum_value_, maximum_value_, buckets); +} + +void TextFormatter::FormatBeginReport(uint64_t timestamp_since_start_ms, + const std::optional<SessionData>& session_data) { os_ << "\n*** ART internal metrics ***\n"; os_ << " Metadata:\n"; os_ << " timestamp_since_start_ms: " << timestamp_since_start_ms << "\n"; - if (session_data_.has_value()) { - os_ << " session_id: " << session_data_->session_id << "\n"; - os_ << " uid: " << session_data_->uid << "\n"; - os_ << " compilation_reason: " << CompilationReasonName(session_data_->compilation_reason) + if (session_data.has_value()) { + os_ << " session_id: " << session_data->session_id << "\n"; + os_ << " uid: " << session_data->uid << "\n"; + os_ << " compilation_reason: " << CompilationReasonName(session_data->compilation_reason) << "\n"; - os_ << " compiler_filter: " << CompilerFilterReportingName(session_data_->compiler_filter) + os_ << " compiler_filter: " << CompilerFilterReportingName(session_data->compiler_filter) << "\n"; } os_ << " Metrics:\n"; } -void StringBackend::EndReport() { os_ << "*** Done dumping ART internal metrics ***\n"; } - -void StringBackend::ReportCounter(DatumId counter_type, uint64_t value) { +void TextFormatter::FormatReportCounter(DatumId counter_type, uint64_t value) { os_ << " " << DatumName(counter_type) << ": count = " << value << "\n"; } -void StringBackend::ReportHistogram(DatumId histogram_type, - int64_t minimum_value_, - int64_t maximum_value_, - const std::vector<uint32_t>& buckets) { - os_ << " " << DatumName(histogram_type) << ": range = " << minimum_value_ << "..." << maximum_value_; - if (buckets.size() > 0) { +void TextFormatter::FormatReportHistogram(DatumId histogram_type, + int64_t minimum_value_, + int64_t maximum_value_, + const std::vector<uint32_t>& buckets) { + os_ << " " << DatumName(histogram_type) << ": range = " + << minimum_value_ << "..." << maximum_value_; + if (!buckets.empty()) { os_ << ", buckets: "; bool first = true; for (const auto& count : buckets) { @@ -143,22 +161,100 @@ void StringBackend::ReportHistogram(DatumId histogram_type, } } -LogBackend::LogBackend(android::base::LogSeverity level) : level_{level} {} +void TextFormatter::FormatEndReport() { + os_ << "*** Done dumping ART internal metrics ***\n"; +} + +std::string TextFormatter::GetAndResetBuffer() { + std::string result = os_.str(); + os_.clear(); + os_.str(""); + return result; +} + +void XmlFormatter::FormatBeginReport(uint64_t timestamp_millis, + const std::optional<SessionData>& session_data) { + tinyxml2::XMLElement* art_runtime_metrics = document_.NewElement("art_runtime_metrics"); + document_.InsertEndChild(art_runtime_metrics); + + art_runtime_metrics->InsertNewChildElement("version")->SetText(version.data()); + + tinyxml2::XMLElement* metadata = art_runtime_metrics->InsertNewChildElement("metadata"); + metadata->InsertNewChildElement("timestamp_since_start_ms")->SetText(timestamp_millis); + + if (session_data.has_value()) { + metadata->InsertNewChildElement("session_id")->SetText(session_data->session_id); + metadata->InsertNewChildElement("uid")->SetText(session_data->uid); + metadata + ->InsertNewChildElement("compilation_reason") + ->SetText(CompilationReasonName(session_data->compilation_reason)); + metadata + ->InsertNewChildElement("compiler_filter") + ->SetText(CompilerFilterReportingName(session_data->compiler_filter)); + } + + art_runtime_metrics->InsertNewChildElement("metrics"); +} + +void XmlFormatter::FormatReportCounter(DatumId counter_type, uint64_t value) { + tinyxml2::XMLElement* metrics = document_.RootElement()->FirstChildElement("metrics"); + + tinyxml2::XMLElement* counter = metrics->InsertNewChildElement(DatumName(counter_type).data()); + counter->InsertNewChildElement("counter_type")->SetText("count"); + counter->InsertNewChildElement("value")->SetText(value); +} + +void XmlFormatter::FormatReportHistogram(DatumId histogram_type, + int64_t low_value, + int64_t high_value, + const std::vector<uint32_t>& buckets) { + tinyxml2::XMLElement* metrics = document_.RootElement()->FirstChildElement("metrics"); + + tinyxml2::XMLElement* histogram = + metrics->InsertNewChildElement(DatumName(histogram_type).data()); + histogram->InsertNewChildElement("counter_type")->SetText("histogram"); + histogram->InsertNewChildElement("minimum_value")->SetText(low_value); + histogram->InsertNewChildElement("maximum_value")->SetText(high_value); + + tinyxml2::XMLElement* buckets_element = histogram->InsertNewChildElement("buckets"); + for (const auto& count : buckets) { + buckets_element->InsertNewChildElement("bucket")->SetText(count); + } +} + +void XmlFormatter::FormatEndReport() {} + +std::string XmlFormatter::GetAndResetBuffer() { + tinyxml2::XMLPrinter printer(/*file=*/nullptr, /*compact=*/true); + document_.Print(&printer); + std::string result = printer.CStr(); + document_.Clear(); + + return result; +} + +LogBackend::LogBackend(std::unique_ptr<MetricsFormatter> formatter, + android::base::LogSeverity level) + : StringBackend{std::move(formatter)}, level_{level} +{} void LogBackend::BeginReport(uint64_t timestamp_since_start_ms) { - GetAndResetBuffer(); + StringBackend::GetAndResetBuffer(); StringBackend::BeginReport(timestamp_since_start_ms); } void LogBackend::EndReport() { StringBackend::EndReport(); - LOG_STREAM(level_) << GetAndResetBuffer(); + LOG_STREAM(level_) << StringBackend::GetAndResetBuffer(); } -FileBackend::FileBackend(const std::string& filename) : filename_{filename} {} +FileBackend::FileBackend(std::unique_ptr<MetricsFormatter> formatter, + const std::string& filename) + : StringBackend{std::move(formatter)}, filename_{filename} +{} void FileBackend::BeginReport(uint64_t timestamp_since_start_ms) { - GetAndResetBuffer(); + StringBackend::GetAndResetBuffer(); StringBackend::BeginReport(timestamp_since_start_ms); } @@ -170,7 +266,7 @@ void FileBackend::EndReport() { if (file.get() == nullptr) { LOG(WARNING) << "Could open metrics file '" << filename_ << "': " << error_message; } else { - if (!android::base::WriteStringToFd(GetAndResetBuffer(), file.get()->Fd())) { + if (!android::base::WriteStringToFd(StringBackend::GetAndResetBuffer(), file.get()->Fd())) { PLOG(WARNING) << "Error writing metrics to file"; } } |