| 403 | |
| 404 | |
| 405 | Try<hashmap<string, mesos::PerfStatistics>> parse( |
| 406 | const string& output) |
| 407 | { |
| 408 | hashmap<string, mesos::PerfStatistics> statistics; |
| 409 | |
| 410 | foreach (const string& line, strings::tokenize(output, "\n")) { |
| 411 | Try<Sample> sample = Sample::parse(line); |
| 412 | |
| 413 | if (sample.isError()) { |
| 414 | return Error("Failed to parse perf sample line '" + line + "': " + |
| 415 | sample.error()); |
| 416 | } |
| 417 | |
| 418 | // Some additional metrics (e.g. stalled cycles per instruction) |
| 419 | // are printed without an event. Ignore them. |
| 420 | if (sample->event.empty()) { |
| 421 | continue; |
| 422 | } |
| 423 | |
| 424 | if (!statistics.contains(sample->cgroup)) { |
| 425 | statistics.put(sample->cgroup, mesos::PerfStatistics()); |
| 426 | } |
| 427 | |
| 428 | const google::protobuf::Reflection* reflection = |
| 429 | statistics[sample->cgroup].GetReflection(); |
| 430 | const google::protobuf::FieldDescriptor* field = |
| 431 | statistics[sample->cgroup].GetDescriptor()->FindFieldByName( |
| 432 | sample->event); |
| 433 | |
| 434 | if (field == nullptr) { |
| 435 | return Error("Unexpected event '" + sample->event + "'" |
| 436 | " in perf output at line: " + line); |
| 437 | } |
| 438 | |
| 439 | if (sample->value == "<not supported>") { |
| 440 | LOG(WARNING) << "Unsupported perf counter, ignoring: " << line; |
| 441 | continue; |
| 442 | } |
| 443 | |
| 444 | switch (field->type()) { |
| 445 | case google::protobuf::FieldDescriptor::TYPE_DOUBLE: { |
| 446 | Try<double> number = (sample->value == "<not counted>") |
| 447 | ? 0 |
| 448 | : numify<double>(sample->value); |
| 449 | |
| 450 | if (number.isError()) { |
| 451 | return Error("Unable to parse perf value at line: " + line); |
| 452 | } |
| 453 | |
| 454 | reflection->SetDouble(&( |
| 455 | statistics[sample->cgroup]), field, number.get()); |
| 456 | break; |
| 457 | } |
| 458 | case google::protobuf::FieldDescriptor::TYPE_UINT64: { |
| 459 | Try<uint64_t> number = (sample->value == "<not counted>") |
| 460 | ? 0 |
| 461 | : numify<uint64_t>(sample->value); |
| 462 |
no test coverage detected