| 256 | |
| 257 | |
| 258 | Future<hashmap<string, mesos::PerfStatistics>> sample( |
| 259 | const set<string>& events, |
| 260 | const set<string>& cgroups, |
| 261 | const Duration& duration) |
| 262 | { |
| 263 | // Is this a no-op? |
| 264 | if (cgroups.empty()) { |
| 265 | return hashmap<string, mesos::PerfStatistics>(); |
| 266 | } |
| 267 | |
| 268 | vector<string> argv = { |
| 269 | "stat", |
| 270 | |
| 271 | // System-wide collection from all CPUs. |
| 272 | "--all-cpus", |
| 273 | |
| 274 | // Print counts using a CSV-style output to make it easy to import |
| 275 | // directly into spreadsheets. Columns are separated by the string |
| 276 | // specified in PERF_DELIMITER. |
| 277 | "--field-separator", PERF_DELIMITER, |
| 278 | |
| 279 | // Ensure all output goes to stdout. |
| 280 | "--log-fd", "1" |
| 281 | }; |
| 282 | |
| 283 | // Add all pairwise combinations of event and cgroup. |
| 284 | foreach (const string& event, events) { |
| 285 | foreach (const string& cgroup, cgroups) { |
| 286 | argv.push_back("--event"); |
| 287 | argv.push_back(event); |
| 288 | argv.push_back("--cgroup"); |
| 289 | argv.push_back(cgroup); |
| 290 | } |
| 291 | } |
| 292 | |
| 293 | argv.push_back("--"); |
| 294 | argv.push_back("sleep"); |
| 295 | argv.push_back(stringify(duration.secs())); |
| 296 | |
| 297 | Time start = Clock::now(); |
| 298 | |
| 299 | internal::Perf* perf = new internal::Perf(argv); |
| 300 | Future<string> output = perf->output(); |
| 301 | spawn(perf, true); |
| 302 | |
| 303 | // TODO(pbrett): Don't wait for these forever! |
| 304 | return output |
| 305 | .then([start, duration](const string output) |
| 306 | -> Future<hashmap<string, mesos::PerfStatistics>> { |
| 307 | Try<hashmap<string, mesos::PerfStatistics>> result = |
| 308 | perf::parse(output); |
| 309 | |
| 310 | if (result.isError()) { |
| 311 | return Failure("Failed to parse perf sample: " + result.error()); |
| 312 | } |
| 313 | |
| 314 | foreachvalue (mesos::PerfStatistics& statistics, result.get()) { |
| 315 | statistics.set_timestamp(start.secs()); |