blob: c1384dd2ed1ce659739eea3bd76f07cd503f4634 [file] [log] [blame]
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_METRICS_PSI_MEMORY_PARSER_H_
#define COMPONENTS_METRICS_PSI_MEMORY_PARSER_H_
#include <string>
#include "base/gtest_prod_util.h"
#include "base/strings/string_piece.h"
namespace metrics {
// Items in internal are - as the name implies - NOT for outside consumption.
// Defined here to allow access to unit test.
namespace internal {
// Finds the bounds for a substring of |content| which is sandwiched between
// the given |prefix| and |suffix| indices. Search only considers
// the portion of the string starting from |search_start|.
// Returns false if the prefix and/or suffix are not found, true otherwise.
// |start| and |end| are output parameters populated with the indices
// for the middle string.
bool FindMiddleString(const base::StringPiece& content,
size_t search_start,
const base::StringPiece& prefix,
const base::StringPiece& suffix,
size_t* start,
size_t* end);
} // namespace internal
// Values as logged in the histogram for memory pressure.
constexpr int kMemPressureMin = 1; // As 0 is for underflow.
constexpr int kMemPressureExclusiveMax = 10000;
constexpr int kMemPressureHistogramBuckets = 100;
// Enumeration representing success and various failure modes for parsing PSI
// memory data. These values are persisted to logs. Entries should not be
// renumbered and numeric values should never be reused.
enum class ParsePSIMemStatus {
kSuccess,
kReadFileFailed,
kUnexpectedDataFormat,
kInvalidMetricFormat,
kParsePSIValueFailed,
// Magic constant used by the histogram macros.
kMaxValue = kParsePSIValueFailed,
};
// PSIMemoryParser has logic to parse results from /proc/memory/pressure
// in Linux, which can be used for memory pressure metrics.
class PSIMemoryParser {
public:
explicit PSIMemoryParser(uint32_t period);
~PSIMemoryParser();
// Parses PSI memory pressure from |content|, for the currently configured
// metrics period (10, 60 or 300 seconds).
// The some and full values are output to |metricSome| and |metricFull|,
// respectively.
// Returns status of the parse operation - ParsePSIMemStatus::kSuccess
// or error code otherwise.
ParsePSIMemStatus ParseMetrics(const base::StringPiece& content,
int* metric_some,
int* metric_full);
// Raw buffer overload
ParsePSIMemStatus ParseMetrics(const uint8_t* content,
uint32_t len,
int* metric_some,
int* metric_full);
uint32_t GetPeriod() const;
void LogParseStatus(ParsePSIMemStatus stat);
PSIMemoryParser(const PSIMemoryParser&) = delete;
PSIMemoryParser& operator=(const PSIMemoryParser&) = delete;
PSIMemoryParser() = delete;
private:
// Friend it so it can see private members for testing
friend class PSIMemoryParserTest;
FRIEND_TEST_ALL_PREFIXES(PSIMemoryParserTest, CustomInterval);
FRIEND_TEST_ALL_PREFIXES(PSIMemoryParserTest, InvalidInterval);
FRIEND_TEST_ALL_PREFIXES(PSIMemoryParserTest, InternalsA);
FRIEND_TEST_ALL_PREFIXES(PSIMemoryParserTest, InternalsB);
FRIEND_TEST_ALL_PREFIXES(PSIMemoryParserTest, InternalsC);
FRIEND_TEST_ALL_PREFIXES(PSIMemoryParserTest, InternalsD);
FRIEND_TEST_ALL_PREFIXES(PSIMemoryParserTest, InternalsE);
ParsePSIMemStatus ParseMetricsInternal(const std::string& content,
int* metric_some,
int* metric_full);
// Retrieves one metric value from |content|, for the currently configured
// metrics category (10, 60 or 300 seconds).
// Only considers the substring between |start| (inclusive) and |end|
// (exclusive).
// Returns the floating-point string representation converted into an integer
// which has the value multiplied by 100 - (10.20 = 1020), for
// histogram usage.
int GetMetricValue(const base::StringPiece& content,
size_t start,
size_t end);
std::string metric_prefix_;
uint32_t period_;
};
} // namespace metrics
#endif // COMPONENTS_METRICS_PSI_MEMORY_PARSER_H_