blob: 5630a47a601747000b8ce4b9b8eae8cb37c61074 [file] [log] [blame]
// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <memory>
#include <string>
#include <base/files/file_path.h>
#include <base/macros.h>
#include <base/time/time.h>
#include <base/timer/timer.h>
#include <gtest/gtest_prod.h> // for FRIEND_TEST
namespace chromeos_metrics {
// Record for retrieving and reporting values from /proc/vmstat
struct VmstatRecord {
uint64_t page_faults_ = 0; // major faults
uint64_t file_page_faults_ = 0; // major faults for file-backed pages
uint64_t anon_page_faults_ = 0; // major faults for anonymous pages
uint64_t swap_in_ = 0; // pages swapped in
uint64_t swap_out_ = 0; // pages swapped out
// Parse cumulative vm statistics from data read from /proc/vmstat. Returns
// true for success.
bool VmStatsParseStats(const std::string& stats, struct VmstatRecord* record);
// Encapsulates the logic for writing to vmlog and rotating log files when
// necessary.
class VmlogFile {
// Creates a new VmlogFile to manage vmlog logging. Output is written to
// live_path, and rotated to rotated_path when the file would exceed max_size.
// Output files always begin with the contents of header.
VmlogFile(const base::FilePath& live_path,
const base::FilePath& rotated_path,
const uint64_t max_size,
const std::string& header);
// Writes the requested data to the vmlog log file. Returns false on failure.
bool Write(const std::string& data);
friend class VmlogWriterTest;
FRIEND_TEST(VmlogWriterTest, WriteCallbackSuccess);
base::FilePath live_path_;
base::FilePath rotated_path_;
uint64_t max_size_;
std::string header_;
uint64_t cur_size_ = 0;
int fd_ = -1;
// Reads information from /proc/vmstat periodically and writes summary data to
// vmlog. VmlogWriter manages output file and symlink creation and automatically
// rotates the underlying files to keep data fresh while keeping a small disk
// footprint.
class VmlogWriter {
VmlogWriter(const base::FilePath& vmlog_dir,
const base::TimeDelta& log_interval);
friend class VmlogWriterTest;
FRIEND_TEST(VmlogWriterTest, WriteCallbackSuccess);
// Called by the constructor to initialize internals. May schedule itself on
// valid_time_delay_timer_ if system clock doesn't look correct.
void Init(const base::FilePath& vmlog_dir,
const base::TimeDelta& log_interval);
// Invoked every log_interval by timer_, this callback parses the contents of
// /proc/vmstat and writes results to vmlog_.
void WriteCallback();
std::unique_ptr<VmlogFile> vmlog_;
int vmstat_fd_;
VmstatRecord previous_record_;
base::RepeatingTimer timer_;
base::OneShotTimer valid_time_delay_timer_;
} // namespace chromeos_metrics