2 * Copyright 2014 The Chromium Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
17 * This tool is essentially an extended version of ps with JSON output.
18 * Its output is meant consumed by scripts / tools for gathering OS/ps stats.
20 * All times are expressed in ticks.
21 * All memory counters are expressed in Kb.
24 static void dump_time(void) {
25 float uptime_secs
= 0.0F
;
26 const long rate
= sysconf(_SC_CLK_TCK
);
27 FILE *f
= fopen("/proc/uptime", "r");
30 fscanf(f
, "%f", &uptime_secs
);
32 const long ticks
= (long) (rate
* uptime_secs
);
33 printf(" \"time\": { \"ticks\": %ld, \"rate\": %ld}", ticks
, rate
);
36 static void dump_cpu_stats(void) {
37 FILE *f
= fopen("/proc/stat", "r");
40 printf(" \"cpu\":\n [\n");
42 bool terminate_prev_line
= false;
46 long unsigned t_usr
= 0;
47 long unsigned t_nice
= 0;
48 long unsigned t_sys
= 0;
49 long unsigned t_idle
= 0;
50 fgets(line
, sizeof(line
), f
);
52 /* Skip the total 'cpu ' line and the other irrelevant ones. */
53 if (strncmp(line
, "cpu", 3) != 0 || line
[3] == ' ')
55 if (sscanf(line
, "%s %lu %lu %lu %lu",
56 cpu
, &t_usr
, &t_nice
, &t_sys
, &t_idle
) != 5) {
60 if (terminate_prev_line
)
62 terminate_prev_line
= true;
63 printf(" {\"usr\": %lu, \"sys\": %lu, \"idle\": %lu}",
64 t_usr
+ t_nice
, t_sys
, t_idle
);
70 static void dump_mem_stats(void) {
71 FILE *f
= fopen("/proc/meminfo", "r");
74 printf(" \"mem\":\n {\n");
76 bool terminate_prev_line
= false;
82 fgets(line
, sizeof(line
), f
);
83 if (sscanf(line
, "%s %lu %*s", key
, &value
) < 2)
86 if (terminate_prev_line
)
88 terminate_prev_line
= true;
89 printf(" \"%s\": %lu", key
, value
);
95 static void dump_proc_stats(void) {
97 DIR *d
= opendir("/proc");
101 const long kb_per_page
= sysconf(_SC_PAGESIZE
) / 1024;
102 bool terminate_prev_line
= false;
103 printf(" \"processes\":\n {\n");
104 while ((de
= readdir(d
))) {
105 if (!isdigit(de
->d_name
[0]))
107 const int pid
= atoi(de
->d_name
);
109 /* Don't print out ourselves (how civilized). */
117 /* Read full process path / package from cmdline. */
118 sprintf(fpath
, "/proc/%d/cmdline", pid
);
119 f
= fopen(fpath
, "r");
123 fgets(cmdline
, sizeof(cmdline
), f
);
126 /* Read cpu/io/mem stats. */
128 long num_threads
= 0;
129 long unsigned min_faults
= 0;
130 long unsigned maj_faults
= 0;
131 long unsigned utime
= 0;
132 long unsigned ktime
= 0;
133 long unsigned vm_rss
= 0;
134 long long unsigned start_time
= 0;
136 sprintf(fpath
, "/proc/%d/stat", pid
);
137 f
= fopen(fpath
, "r");
140 fscanf(f
, "%*d %s %*c %*d %*d %*d %*d %*d %*u %lu %*u %lu %*u %lu %lu "
141 "%*d %*d %*d %*d %ld %*d %llu %*u %ld", proc_name
, &min_faults
,
142 &maj_faults
, &utime
, &ktime
, &num_threads
, &start_time
, &vm_rss
);
145 /* Prefer the cmdline when available, since it contains the package name. */
146 char const * const cmd
= (strlen(cmdline
) > 0) ? cmdline
: proc_name
;
148 if (terminate_prev_line
)
150 terminate_prev_line
= true;
153 "\"n_threads\": %ld, "
154 "\"start_time\": %llu, "
155 "\"user_time\": %lu, "
156 "\"sys_time\": %lu, "
157 "\"min_faults\": %lu, "
158 "\"maj_faults\": %lu, "
169 vm_rss
* kb_per_page
);