Convert a single line of perf output in CSV format (using PERF_DELIMITER as a separator) to a sample.
| 352 | // Convert a single line of perf output in CSV format (using |
| 353 | // PERF_DELIMITER as a separator) to a sample. |
| 354 | static Try<Sample> parse(const string& line) |
| 355 | { |
| 356 | // We use strings::split to separate the tokens |
| 357 | // because the unit field can be empty. |
| 358 | vector<string> tokens = strings::split(line, PERF_DELIMITER); |
| 359 | |
| 360 | // A number of CSV formats are possible. Note that we do not |
| 361 | // use the kernel version when parsing because OS vendors often |
| 362 | // backport perf tool functionality into older kernel versions. |
| 363 | |
| 364 | switch (tokens.size()) { |
| 365 | // value,event,cgroup (since Linux v2.6.39) |
| 366 | case 3: |
| 367 | return Sample({tokens[0], internal::normalize(tokens[1]), tokens[2]}); |
| 368 | |
| 369 | // value,unit,event,cgroup (since Linux v3.14) |
| 370 | case 4: |
| 371 | |
| 372 | // value,unit,event,cgroup,running,measurement-ratio (since Linux v4.1) |
| 373 | case 6: |
| 374 | |
| 375 | // value,unit,event,cgroup,running,measurement-ratio, |
| 376 | // aggregate-value,aggregate-unit (since Linux v4.6) |
| 377 | case 8: |
| 378 | return Sample({tokens[0], internal::normalize(tokens[2]), tokens[3]}); |
| 379 | |
| 380 | // This is the same format as the one with 8 fields. Due to a |
| 381 | // bug 'perf stat' may print 4 CSV separators instead of 2 empty |
| 382 | // fields (https://lkml.org/lkml/2018/3/6/22). |
| 383 | case 10: |
| 384 | // Check that the last 4 fields are empty. Otherwise this is |
| 385 | // an unknown format. |
| 386 | for (int i = 6; i < 10; ++i) { |
| 387 | if (!tokens[i].empty()) { |
| 388 | return Error( |
| 389 | "Unexpected number of fields (" + stringify(tokens.size()) + |
| 390 | ")"); |
| 391 | } |
| 392 | } |
| 393 | |
| 394 | return Sample({tokens[0], internal::normalize(tokens[2]), tokens[3]}); |
| 395 | |
| 396 | // Bail out if the format is not recognized. |
| 397 | default: |
| 398 | return Error( |
| 399 | "Unexpected number of fields (" + stringify(tokens.size()) + ")"); |
| 400 | } |
| 401 | } |
| 402 | }; |
| 403 | |
| 404 |