mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
193 lines
4.5 KiB
C
193 lines
4.5 KiB
C
/*
|
|
* Copyright 2014 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.
|
|
*/
|
|
|
|
#include <ctype.h>
|
|
#include <dirent.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include <unistd.h>
|
|
|
|
/*
|
|
* This tool is essentially an extended version of ps with JSON output.
|
|
* Its output is meant consumed by scripts / tools for gathering OS/ps stats.
|
|
* Output units:
|
|
* All times are expressed in ticks.
|
|
* All memory counters are expressed in Kb.
|
|
*/
|
|
|
|
static void dump_time(void) {
|
|
float uptime_secs = 0.0F;
|
|
const long rate = sysconf(_SC_CLK_TCK);
|
|
FILE *f = fopen("/proc/uptime", "r");
|
|
if (!f)
|
|
return;
|
|
fscanf(f, "%f", &uptime_secs);
|
|
fclose(f);
|
|
const long ticks = (long) (rate * uptime_secs);
|
|
printf(" \"time\": { \"ticks\": %ld, \"rate\": %ld}", ticks, rate);
|
|
}
|
|
|
|
static void dump_cpu_stats(void) {
|
|
FILE *f = fopen("/proc/stat", "r");
|
|
if (!f)
|
|
return;
|
|
printf(" \"cpu\":\n [\n");
|
|
|
|
bool terminate_prev_line = false;
|
|
while (!feof(f)) {
|
|
char line[256];
|
|
char cpu[8];
|
|
long unsigned t_usr = 0;
|
|
long unsigned t_nice = 0;
|
|
long unsigned t_sys = 0;
|
|
long unsigned t_idle = 0;
|
|
fgets(line, sizeof(line), f);
|
|
|
|
/* Skip the total 'cpu ' line and the other irrelevant ones. */
|
|
if (strncmp(line, "cpu", 3) != 0 || line[3] == ' ')
|
|
continue;
|
|
if (sscanf(line, "%s %lu %lu %lu %lu",
|
|
cpu, &t_usr, &t_nice, &t_sys, &t_idle) != 5) {
|
|
continue;
|
|
}
|
|
|
|
if (terminate_prev_line)
|
|
printf(",\n");
|
|
terminate_prev_line = true;
|
|
printf(" {\"usr\": %lu, \"sys\": %lu, \"idle\": %lu}",
|
|
t_usr + t_nice, t_sys, t_idle);
|
|
}
|
|
fclose(f);
|
|
printf("\n ]");
|
|
}
|
|
|
|
static void dump_mem_stats(void) {
|
|
FILE *f = fopen("/proc/meminfo", "r");
|
|
if (!f)
|
|
return;
|
|
printf(" \"mem\":\n {\n");
|
|
|
|
bool terminate_prev_line = false;
|
|
while (!feof(f)) {
|
|
char line[256];
|
|
char key[32];
|
|
long value = 0;
|
|
|
|
fgets(line, sizeof(line), f);
|
|
if (sscanf(line, "%s %lu %*s", key, &value) < 2)
|
|
continue;
|
|
|
|
if (terminate_prev_line)
|
|
printf(",\n");
|
|
terminate_prev_line = true;
|
|
printf(" \"%s\": %lu", key, value);
|
|
}
|
|
fclose(f);
|
|
printf("\n }");
|
|
}
|
|
|
|
static void dump_proc_stats(void) {
|
|
struct dirent *de;
|
|
DIR *d = opendir("/proc");
|
|
if (!d)
|
|
return;
|
|
|
|
const long kb_per_page = sysconf(_SC_PAGESIZE) / 1024;
|
|
bool terminate_prev_line = false;
|
|
printf(" \"processes\":\n {\n");
|
|
while ((de = readdir(d))) {
|
|
if (!isdigit(de->d_name[0]))
|
|
continue;
|
|
const int pid = atoi(de->d_name);
|
|
|
|
/* Don't print out ourselves (how civilized). */
|
|
if (pid == getpid())
|
|
continue;
|
|
|
|
char cmdline[64];
|
|
char fpath[32];
|
|
FILE *f;
|
|
|
|
/* Read full process path / package from cmdline. */
|
|
sprintf(fpath, "/proc/%d/cmdline", pid);
|
|
f = fopen(fpath, "r");
|
|
if (!f)
|
|
continue;
|
|
cmdline[0] = '\0';
|
|
fgets(cmdline, sizeof(cmdline), f);
|
|
fclose(f);
|
|
|
|
/* Read cpu/io/mem stats. */
|
|
char proc_name[256];
|
|
long num_threads = 0;
|
|
long unsigned min_faults = 0;
|
|
long unsigned maj_faults = 0;
|
|
long unsigned utime = 0;
|
|
long unsigned ktime = 0;
|
|
long unsigned vm_rss = 0;
|
|
long long unsigned start_time = 0;
|
|
|
|
sprintf(fpath, "/proc/%d/stat", pid);
|
|
f = fopen(fpath, "r");
|
|
if (!f)
|
|
continue;
|
|
fscanf(f, "%*d %s %*c %*d %*d %*d %*d %*d %*u %lu %*u %lu %*u %lu %lu "
|
|
"%*d %*d %*d %*d %ld %*d %llu %*u %ld", proc_name, &min_faults,
|
|
&maj_faults, &utime, &ktime, &num_threads, &start_time, &vm_rss);
|
|
fclose(f);
|
|
|
|
/* Prefer the cmdline when available, since it contains the package name. */
|
|
char const * const cmd = (strlen(cmdline) > 0) ? cmdline : proc_name;
|
|
|
|
if (terminate_prev_line)
|
|
printf(",\n");
|
|
terminate_prev_line = true;
|
|
printf(" \"%d\": {"
|
|
"\"name\": \"%s\", "
|
|
"\"n_threads\": %ld, "
|
|
"\"start_time\": %llu, "
|
|
"\"user_time\": %lu, "
|
|
"\"sys_time\": %lu, "
|
|
"\"min_faults\": %lu, "
|
|
"\"maj_faults\": %lu, "
|
|
"\"vm_rss\": %lu"
|
|
"}",
|
|
pid,
|
|
cmd,
|
|
num_threads,
|
|
start_time,
|
|
utime,
|
|
ktime,
|
|
min_faults,
|
|
maj_faults,
|
|
vm_rss * kb_per_page);
|
|
}
|
|
closedir(d);
|
|
printf("\n }");
|
|
}
|
|
|
|
int main()
|
|
{
|
|
printf("{\n");
|
|
|
|
dump_time();
|
|
printf(",\n");
|
|
|
|
dump_mem_stats();
|
|
printf(",\n");
|
|
|
|
dump_cpu_stats();
|
|
printf(",\n");
|
|
|
|
dump_proc_stats();
|
|
printf("\n}\n");
|
|
|
|
return 0;
|
|
}
|