blob: f9479c4be75018cd522f47b100fee9f18bbd76a1 [file] [log] [blame]
Seungjae Yoofd9a0622022-10-14 10:01:29 +09001// Copyright 2022, The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Seungjae Yoo46fc8ba2022-10-19 14:02:08 +090015use anyhow::{bail, Result};
Seungjae Yoofd9a0622022-10-14 10:01:29 +090016use libc::{sysconf, _SC_CLK_TCK};
Seungjae Yoo46fc8ba2022-10-19 14:02:08 +090017use std::fs::File;
Seungjae Yoofd9a0622022-10-14 10:01:29 +090018use std::io::{BufRead, BufReader};
19
20const MILLIS_PER_SEC: i64 = 1000;
21
22pub struct CpuTime {
23 pub user: i64,
24 pub nice: i64,
25 pub sys: i64,
26 pub idle: i64,
27}
28
29pub struct MemInfo {
30 pub total: i64,
31 pub free: i64,
32 pub available: i64,
33 pub buffer: i64,
34 pub cached: i64,
35}
36
37// Get CPU time information from /proc/stat
38//
39// /proc/stat example(omitted):
40// cpu 24790952 21104390 10771070 10480973587 1700955 0 410931 0 316532 0
41// cpu0 169636 141307 61153 81785791 9605 0 183524 0 1345 0
42// cpu1 182431 198327 68273 81431817 10445 0 32392 0 2616 0
43// cpu2 183209 174917 68591 81933935 12239 0 10042 0 2415 0
44// cpu3 183413 177758 69908 81927474 13354 0 5853 0 2491 0
45// intr 7913477443 39 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
46// ctxt 10326710014
47// btime 1664123605
48// processes 9225712
49// procs_running 1
50// procs_blocked 0
51// softirq 2683914305 14595298 304837101 1581 327291100 16397051 0 208857783 1024640365 787932 786506094
52//
53// expected output:
54// user: 24790952
55// nice: 21104390
56// sys: 10771070
57// idle: 10480973587
58pub fn get_cpu_time() -> Result<CpuTime> {
Seungjae Yoofd9a0622022-10-14 10:01:29 +090059 let mut proc_stat = BufReader::new(File::open("/proc/stat")?);
60 let mut line = String::new();
61 proc_stat.read_line(&mut line)?;
Seungjae Yoo46fc8ba2022-10-19 14:02:08 +090062 let data_list: Vec<_> = line.split_whitespace().filter_map(|s| s.parse::<i64>().ok()).collect();
63 if data_list.len() < 4 {
64 bail!("Failed to extract numeric values in /proc/stat :\n{}", line);
65 }
Seungjae Yoofd9a0622022-10-14 10:01:29 +090066
67 let ticks_per_sec = unsafe { sysconf(_SC_CLK_TCK) } as i64;
68 let cpu_time = CpuTime {
Seungjae Yoo46fc8ba2022-10-19 14:02:08 +090069 user: data_list[0] * MILLIS_PER_SEC / ticks_per_sec,
70 nice: data_list[1] * MILLIS_PER_SEC / ticks_per_sec,
71 sys: data_list[2] * MILLIS_PER_SEC / ticks_per_sec,
72 idle: data_list[3] * MILLIS_PER_SEC / ticks_per_sec,
Seungjae Yoofd9a0622022-10-14 10:01:29 +090073 };
74 Ok(cpu_time)
75}
76
77// Get memory information from /proc/meminfo
78//
79// /proc/meminfo example(omitted):
80// MemTotal: 263742736 kB
81// MemFree: 37144204 kB
82// MemAvailable: 249168700 kB
83// Buffers: 10231296 kB
84// Cached: 189502836 kB
85// SwapCached: 113848 kB
86// Active: 132266424 kB
87// Inactive: 73587504 kB
88// Active(anon): 1455240 kB
89// Inactive(anon): 6993584 kB
90// Active(file): 130811184 kB
91// Inactive(file): 66593920 kB
92// Unevictable: 56436 kB
93// Mlocked: 56436 kB
94// SwapTotal: 255123452 kB
95// SwapFree: 254499068 kB
96// Dirty: 596 kB
97// Writeback: 0 kB
98// AnonPages: 5295864 kB
99// Mapped: 3512608 kB
100//
101// expected output:
102// total: 263742736
103// free: 37144204
104// available: 249168700
105// buffer: 10231296
106// cached: 189502836
107pub fn get_mem_info() -> Result<MemInfo> {
Seungjae Yoo46fc8ba2022-10-19 14:02:08 +0900108 let mut proc_stat = BufReader::new(File::open("/proc/meminfo")?);
109 let mut lines = String::new();
110 for _ in 0..5 {
111 proc_stat.read_line(&mut lines)?;
112 }
113 let data_list: Vec<_> =
114 lines.split_whitespace().filter_map(|s| s.parse::<i64>().ok()).collect();
115 if data_list.len() != 5 {
116 bail!("Failed to extract numeric values in /proc/meminfo :\n{}", lines);
117 }
Seungjae Yoofd9a0622022-10-14 10:01:29 +0900118
119 let mem_info = MemInfo {
Seungjae Yoo46fc8ba2022-10-19 14:02:08 +0900120 total: data_list[0],
121 free: data_list[1],
122 available: data_list[2],
123 buffer: data_list[3],
124 cached: data_list[4],
Seungjae Yoofd9a0622022-10-14 10:01:29 +0900125 };
126 Ok(mem_info)
127}