xref: /aosp_15_r20/external/cronet/components/metrics/psi_memory_parser.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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