blob: b8c2f80fea36a8b83b61972490b9b46f71dbe64f [file] [log] [blame]
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "android-base/logging.h"
#include "odr_metrics_record.h"
#include "tinyxml2.h"
#include <iosfwd>
#include <string>
namespace art {
namespace odrefresh {
namespace {
android::base::Result<int64_t> ReadInt64(tinyxml2::XMLElement* parent, const char* name) {
tinyxml2::XMLElement* element = parent->FirstChildElement(name);
if (element == nullptr) {
return Errorf("Expected Odrefresh metric {} not found", name);
}
int64_t metric;
tinyxml2::XMLError result = element->QueryInt64Text(&metric);
if (result == tinyxml2::XML_SUCCESS) {
return metric;
} else {
return Errorf("Odrefresh metric {} is not an int64", name);
}
}
android::base::Result<int32_t> ReadInt32(tinyxml2::XMLElement* parent, const char* name) {
tinyxml2::XMLElement* element = parent->FirstChildElement(name);
if (element == nullptr) {
return Errorf("Expected Odrefresh metric {} not found", name);
}
int32_t metric;
tinyxml2::XMLError result = element->QueryIntText(&metric);
if (result == tinyxml2::XML_SUCCESS) {
return metric;
} else {
return Errorf("Odrefresh metric {} is not an int32", name);
}
}
template <typename T>
void AddMetric(tinyxml2::XMLElement* parent, const char* name, const T& value) {
parent->InsertNewChildElement(name)->SetText(value);
}
} // namespace
android::base::Result<void> OdrMetricsRecord::ReadFromFile(const std::string& filename) {
tinyxml2::XMLDocument xml_document;
tinyxml2::XMLError result = xml_document.LoadFile(filename.data());
if (result != tinyxml2::XML_SUCCESS) {
return android::base::Error() << xml_document.ErrorStr();
}
tinyxml2::XMLElement* metrics = xml_document.FirstChildElement("odrefresh_metrics");
if (metrics == nullptr) {
return Errorf("odrefresh_metrics element not found in {}", filename);
}
odrefresh_metrics_version = OR_RETURN(ReadInt32(metrics, "odrefresh_metrics_version"));
if (odrefresh_metrics_version != kOdrefreshMetricsVersion) {
return Errorf("odrefresh_metrics_version {} is different than expected ({})",
odrefresh_metrics_version,
kOdrefreshMetricsVersion);
}
art_apex_version = OR_RETURN(ReadInt64(metrics, "art_apex_version"));
trigger = OR_RETURN(ReadInt32(metrics, "trigger"));
stage_reached = OR_RETURN(ReadInt32(metrics, "stage_reached"));
status = OR_RETURN(ReadInt32(metrics, "status"));
cache_space_free_start_mib = OR_RETURN(ReadInt32(metrics, "cache_space_free_start_mib"));
cache_space_free_end_mib = OR_RETURN(ReadInt32(metrics, "cache_space_free_end_mib"));
primary_bcp_compilation_millis = OR_RETURN(
ReadInt32(metrics, "primary_bcp_compilation_millis"));
secondary_bcp_compilation_millis = OR_RETURN(
ReadInt32(metrics, "secondary_bcp_compilation_millis"));
system_server_compilation_millis = OR_RETURN(
ReadInt32(metrics, "system_server_compilation_millis"));
return {};
}
android::base::Result<void> OdrMetricsRecord::WriteToFile(const std::string& filename) const {
tinyxml2::XMLDocument xml_document;
tinyxml2::XMLElement* metrics = xml_document.NewElement("odrefresh_metrics");
xml_document.InsertEndChild(metrics);
// The order here matches the field order of MetricsRecord.
AddMetric(metrics, "odrefresh_metrics_version", odrefresh_metrics_version);
AddMetric(metrics, "art_apex_version", art_apex_version);
AddMetric(metrics, "trigger", trigger);
AddMetric(metrics, "stage_reached", stage_reached);
AddMetric(metrics, "status", status);
AddMetric(metrics, "cache_space_free_start_mib", cache_space_free_start_mib);
AddMetric(metrics, "cache_space_free_end_mib", cache_space_free_end_mib);
AddMetric(metrics, "primary_bcp_compilation_millis", primary_bcp_compilation_millis);
AddMetric(metrics, "secondary_bcp_compilation_millis", secondary_bcp_compilation_millis);
AddMetric(metrics, "system_server_compilation_millis", system_server_compilation_millis);
tinyxml2::XMLError result = xml_document.SaveFile(filename.data(), /*compact=*/true);
if (result == tinyxml2::XML_SUCCESS) {
return {};
} else {
return android::base::Error() << xml_document.ErrorStr();
}
}
} // namespace odrefresh
} // namespace art