1 // Copyright 2021 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef COMPONENTS_METRICS_PSI_MEMORY_PARSER_H_ 6 #define COMPONENTS_METRICS_PSI_MEMORY_PARSER_H_ 7 8 #include <cstdint> 9 #include <string> 10 11 #include "base/gtest_prod_util.h" 12 #include "base/strings/string_piece.h" 13 14 namespace metrics { 15 16 // Items in internal are - as the name implies - NOT for outside consumption. 17 // Defined here to allow access to unit test. 18 namespace internal { 19 20 // Finds the bounds for a substring of |content| which is sandwiched between 21 // the given |prefix| and |suffix| indices. Search only considers 22 // the portion of the string starting from |search_start|. 23 // Returns false if the prefix and/or suffix are not found, true otherwise. 24 // |start| and |end| are output parameters populated with the indices 25 // for the middle string. 26 bool FindMiddleString(const base::StringPiece& content, 27 size_t search_start, 28 const base::StringPiece& prefix, 29 const base::StringPiece& suffix, 30 size_t* start, 31 size_t* end); 32 33 } // namespace internal 34 35 // Values as logged in the histogram for memory pressure. 36 constexpr int kMemPressureMin = 1; // As 0 is for underflow. 37 constexpr int kMemPressureExclusiveMax = 10000; 38 constexpr int kMemPressureHistogramBuckets = 100; 39 40 // Enumeration representing success and various failure modes for parsing PSI 41 // memory data. These values are persisted to logs. Entries should not be 42 // renumbered and numeric values should never be reused. 43 enum class ParsePSIMemStatus { 44 kSuccess, 45 kReadFileFailed, 46 kUnexpectedDataFormat, 47 kInvalidMetricFormat, 48 kParsePSIValueFailed, 49 // Magic constant used by the histogram macros. 50 kMaxValue = kParsePSIValueFailed, 51 }; 52 53 // PSIMemoryParser has logic to parse results from /proc/memory/pressure 54 // in Linux, which can be used for memory pressure metrics. 55 class PSIMemoryParser { 56 public: 57 explicit PSIMemoryParser(uint32_t period); 58 ~PSIMemoryParser(); 59 60 // Parses PSI memory pressure from |content|, for the currently configured 61 // metrics period (10, 60 or 300 seconds). 62 // The some and full values are output to |metricSome| and |metricFull|, 63 // respectively. 64 // Returns status of the parse operation - ParsePSIMemStatus::kSuccess 65 // or error code otherwise. 66 ParsePSIMemStatus ParseMetrics(const base::StringPiece& content, 67 int* metric_some, 68 int* metric_full); 69 70 // Raw buffer overload 71 ParsePSIMemStatus ParseMetrics(const uint8_t* content, 72 uint32_t len, 73 int* metric_some, 74 int* metric_full); 75 76 uint32_t GetPeriod() const; 77 void LogParseStatus(ParsePSIMemStatus stat); 78 79 PSIMemoryParser(const PSIMemoryParser&) = delete; 80 PSIMemoryParser& operator=(const PSIMemoryParser&) = delete; 81 PSIMemoryParser() = delete; 82 83 private: 84 // Friend it so it can see private members for testing 85 friend class PSIMemoryParserTest; 86 FRIEND_TEST_ALL_PREFIXES(PSIMemoryParserTest, CustomInterval); 87 FRIEND_TEST_ALL_PREFIXES(PSIMemoryParserTest, InvalidInterval); 88 FRIEND_TEST_ALL_PREFIXES(PSIMemoryParserTest, InternalsA); 89 FRIEND_TEST_ALL_PREFIXES(PSIMemoryParserTest, InternalsB); 90 FRIEND_TEST_ALL_PREFIXES(PSIMemoryParserTest, InternalsC); 91 FRIEND_TEST_ALL_PREFIXES(PSIMemoryParserTest, InternalsD); 92 FRIEND_TEST_ALL_PREFIXES(PSIMemoryParserTest, InternalsE); 93 94 ParsePSIMemStatus ParseMetricsInternal(const std::string& content, 95 int* metric_some, 96 int* metric_full); 97 98 // Retrieves one metric value from |content|, for the currently configured 99 // metrics category (10, 60 or 300 seconds). 100 // Only considers the substring between |start| (inclusive) and |end| 101 // (exclusive). 102 // Returns the floating-point string representation converted into an integer 103 // which has the value multiplied by 100 - (10.20 = 1020), for 104 // histogram usage. 105 int GetMetricValue(const base::StringPiece& content, 106 size_t start, 107 size_t end); 108 109 std::string metric_prefix_; 110 uint32_t period_; 111 }; 112 113 } // namespace metrics 114 115 #endif // COMPONENTS_METRICS_PSI_MEMORY_PARSER_H_ 116