OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // Dumps CPU and IO stats to a file at a regular interval. | |
6 // | |
7 // Output may be post processed by host to get top/iotop style information. | |
8 | |
9 #include <signal.h> | |
10 #include <unistd.h> | |
11 | |
12 #include <fstream> | |
13 #include <string> | |
14 #include <vector> | |
15 | |
16 #include "base/command_line.h" | |
17 #include "base/file_util.h" | |
18 #include "base/string_split.h" | |
19 | |
20 namespace { | |
21 | |
22 const char kIOStatsPath[] = "/proc/diskstats"; | |
23 const char kCPUStatsPath[] = "/proc/stat"; | |
24 | |
25 class ActivityMonitor { | |
bulach
2012/07/16 17:52:26
nit: hmm... activity has a well defined and differ
| |
26 public: | |
27 ActivityMonitor(const std::string& out_path) : | |
bulach
2012/07/16 17:52:26
nit: explicit
| |
28 out_path_(out_path), | |
29 samples_(), | |
bulach
2012/07/16 17:52:26
nit: I think this is not needed..
| |
30 record_(true) { | |
31 CHECK(!out_path_.empty()); | |
32 samples_.reserve(1024 * 1024); | |
33 } | |
34 | |
35 // Records stats continuously at |hz| cycles per second util | |
36 // StopRecordingAndDumpStats() is called. | |
37 // | |
38 // Yes, this buffers everything in memory, so it cannot be used for extended | |
39 // durations without OOM. But that beats writing during the trace which | |
40 // would affect the results. | |
41 void Start(int hz) { | |
42 const int sample_interval = 1000000 / hz; | |
43 const FilePath io_stats_path(kIOStatsPath); | |
44 const FilePath cpu_stats_path(kCPUStatsPath); | |
45 std::string out; | |
46 while (record_) { | |
47 out.clear(); | |
48 CHECK(file_util::ReadFileToString(io_stats_path, &out)); | |
49 CHECK(file_util::ReadFileToString(cpu_stats_path, &out)); | |
50 samples_.push_back(out); | |
51 usleep(sample_interval); | |
52 } | |
53 } | |
54 | |
55 // Stops recording and saves samples to file. | |
56 void StopAndDumpStats() { | |
57 record_ = false; | |
58 usleep(250 * 1000); | |
59 std::ofstream out_stream; | |
60 out_stream.open(out_path_.value().c_str(), std::ios::out); | |
61 for (std::vector<std::string>::const_iterator i = samples_.begin(); | |
62 i != samples_.end(); ++i) { | |
63 out_stream << i->c_str() << std::endl; | |
64 } | |
65 out_stream.close(); | |
66 } | |
67 | |
68 private: | |
69 const FilePath out_path_; | |
70 std::vector<std::string> samples_; | |
71 bool record_; | |
72 | |
73 DISALLOW_COPY_AND_ASSIGN(ActivityMonitor); | |
74 }; | |
75 | |
76 ActivityMonitor* gActivityMonitor = NULL; | |
bulach
2012/07/16 17:52:26
nit: g_activity_monitor
| |
77 | |
78 void StopAndDumpStats(int unused) { | |
79 printf("Stopping activity monitor\n"); | |
80 gActivityMonitor->StopAndDumpStats(); | |
81 } | |
82 | |
83 } // namespace | |
84 | |
85 int main(int argc, char** argv) { | |
86 const int kDefaultHz = 20; | |
87 | |
88 CommandLine command_line(argc, argv); | |
89 CommandLine::StringVector args = command_line.GetArgs(); | |
90 if (command_line.HasSwitch("h") || command_line.HasSwitch("help") || | |
91 args.size() != 1) { | |
92 printf("Usage: %s OUTPUT_FILE\n" | |
93 " --hz=HZ Number of samples/second. default=%d\n", | |
94 argv[0], kDefaultHz); | |
95 return 1; | |
96 } | |
97 | |
98 int hz = command_line.HasSwitch("hz") ? | |
99 atoi(command_line.GetSwitchValueNative("hz").c_str()) : | |
100 kDefaultHz; | |
101 | |
102 printf("Starting activity monitor\n"); | |
103 gActivityMonitor = new ActivityMonitor(args[0]); | |
104 signal(SIGTERM, StopAndDumpStats); | |
bulach
2012/07/16 17:52:26
uh, isn't the second param required to be a sighan
| |
105 gActivityMonitor->Start(hz); | |
106 delete gActivityMonitor; | |
107 | |
108 return 0; | |
109 } | |
OLD | NEW |