diff options
Diffstat (limited to 'odrefresh/odr_metrics_record.cc')
-rw-r--r-- | odrefresh/odr_metrics_record.cc | 129 |
1 files changed, 90 insertions, 39 deletions
diff --git a/odrefresh/odr_metrics_record.cc b/odrefresh/odr_metrics_record.cc index fc135d3399..b8c2f80fea 100644 --- a/odrefresh/odr_metrics_record.cc +++ b/odrefresh/odr_metrics_record.cc @@ -14,59 +14,110 @@ * limitations under the License. */ +#include "android-base/logging.h" #include "odr_metrics_record.h" +#include "tinyxml2.h" #include <iosfwd> -#include <istream> -#include <ostream> -#include <streambuf> #include <string> namespace art { namespace odrefresh { -std::istream& operator>>(std::istream& is, OdrMetricsRecord& record) { - // Block I/O related exceptions - auto saved_exceptions = is.exceptions(); - is.exceptions(std::ios_base::iostate {}); +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); + } - // The order here matches the field order of MetricsRecord. - is >> record.art_apex_version >> std::ws; - is >> record.trigger >> std::ws; - is >> record.stage_reached >> std::ws; - is >> record.status >> std::ws; - is >> record.primary_bcp_compilation_seconds >> std::ws; - is >> record.secondary_bcp_compilation_seconds >> std::ws; - is >> record.system_server_compilation_seconds >> std::ws; - is >> record.cache_space_free_start_mib >> std::ws; - is >> record.cache_space_free_end_mib >> std::ws; - - // Restore I/O related exceptions - is.exceptions(saved_exceptions); - return is; + 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 -std::ostream& operator<<(std::ostream& os, const OdrMetricsRecord& record) { - static const char kSpace = ' '; +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(); + } - // Block I/O related exceptions - auto saved_exceptions = os.exceptions(); - os.exceptions(std::ios_base::iostate {}); + 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. - os << record.art_apex_version << kSpace; - os << record.trigger << kSpace; - os << record.stage_reached << kSpace; - os << record.status << kSpace; - os << record.primary_bcp_compilation_seconds << kSpace; - os << record.secondary_bcp_compilation_seconds << kSpace; - os << record.system_server_compilation_seconds << kSpace; - os << record.cache_space_free_start_mib << kSpace; - os << record.cache_space_free_end_mib << std::endl; - - // Restore I/O related exceptions - os.exceptions(saved_exceptions); - return os; + 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 |