Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(239)

Side by Side Diff: base/test/trace_event_analyzer.cc

Issue 8682027: Add TraceAnalyzer support for START/FINISH events and JSON error logging (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/test/trace_event_analyzer.h ('k') | base/test/trace_event_analyzer_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/test/trace_event_analyzer.h" 5 #include "base/test/trace_event_analyzer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <math.h> 8 #include <math.h>
9 9
10 #include "base/json/json_reader.h" 10 #include "base/json/json_reader.h"
11 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
12 #include "base/values.h" 12 #include "base/values.h"
13 13
14 namespace trace_analyzer { 14 namespace trace_analyzer {
15 15
16 // TraceEvent 16 // TraceEvent
17 17
18 TraceEvent::TraceEvent() 18 TraceEvent::TraceEvent()
19 : thread(0, 0), 19 : thread(0, 0),
20 timestamp(0), 20 timestamp(0),
21 phase(TRACE_EVENT_PHASE_BEGIN), 21 phase(TRACE_EVENT_PHASE_BEGIN),
22 other_event(NULL) { 22 other_event(NULL) {
23 } 23 }
24 24
25 TraceEvent::~TraceEvent() { 25 TraceEvent::~TraceEvent() {
26 } 26 }
27 27
28 bool TraceEvent::SetFromJSON(const base::Value* event_value) { 28 bool TraceEvent::SetFromJSON(const base::Value* event_value) {
29 if (event_value->GetType() != base::Value::TYPE_DICTIONARY) 29 if (event_value->GetType() != base::Value::TYPE_DICTIONARY) {
30 LOG(ERROR) << "Value must be TYPE_DICTIONARY";
30 return false; 31 return false;
32 }
31 const base::DictionaryValue* dictionary = 33 const base::DictionaryValue* dictionary =
32 static_cast<const base::DictionaryValue*>(event_value); 34 static_cast<const base::DictionaryValue*>(event_value);
33 35
34 std::string phase_str; 36 std::string phase_str;
35 base::DictionaryValue* args = NULL; 37 base::DictionaryValue* args = NULL;
36 38
37 if (dictionary->GetInteger("pid", &thread.process_id) && 39 if (!dictionary->GetString("ph", &phase_str)) {
38 dictionary->GetInteger("tid", &thread.thread_id) && 40 LOG(ERROR) << "ph is missing from TraceEvent JSON";
39 dictionary->GetDouble("ts", &timestamp) && 41 return false;
40 dictionary->GetString("cat", &category) && 42 }
41 dictionary->GetString("name", &name) &&
42 dictionary->GetString("ph", &phase_str) &&
43 dictionary->GetDictionary("args", &args)) {
44 43
45 phase = base::debug::TraceEvent::GetPhase(phase_str.c_str()); 44 phase = base::debug::TraceEvent::GetPhase(phase_str.c_str());
46 45
47 // For each argument, copy the type and create a trace_analyzer::TraceValue. 46 bool require_origin = (phase != TRACE_EVENT_PHASE_METADATA);
48 base::DictionaryValue::key_iterator keyi = args->begin_keys(); 47 bool require_id = (phase == TRACE_EVENT_PHASE_START ||
49 for (; keyi != args->end_keys(); ++keyi) { 48 phase == TRACE_EVENT_PHASE_FINISH);
50 std::string str; 49
51 bool boolean = false; 50 if (require_origin && !dictionary->GetInteger("pid", &thread.process_id)) {
52 int int_num = 0; 51 LOG(ERROR) << "pid is missing from TraceEvent JSON";
53 double double_num = 0.0; 52 return false;
54 Value* value = NULL; 53 }
55 if (args->GetWithoutPathExpansion(*keyi, &value)) { 54 if (require_origin && !dictionary->GetInteger("tid", &thread.thread_id)) {
56 if (value->GetAsString(&str)) 55 LOG(ERROR) << "tid is missing from TraceEvent JSON";
57 arg_strings[*keyi] = str; 56 return false;
58 else if (value->GetAsInteger(&int_num)) 57 }
59 arg_numbers[*keyi] = static_cast<double>(int_num); 58 if (require_origin && !dictionary->GetDouble("ts", &timestamp)) {
60 else if (value->GetAsBoolean(&boolean)) 59 LOG(ERROR) << "ts is missing from TraceEvent JSON";
61 arg_numbers[*keyi] = static_cast<double>(boolean ? 1 : 0); 60 return false;
62 else if (value->GetAsDouble(&double_num)) 61 }
63 arg_numbers[*keyi] = double_num; 62 if (!dictionary->GetString("cat", &category)) {
64 else 63 LOG(ERROR) << "cat is missing from TraceEvent JSON";
65 return false; // Invalid trace event JSON format. 64 return false;
65 }
66 if (!dictionary->GetString("name", &name)) {
67 LOG(ERROR) << "name is missing from TraceEvent JSON";
68 return false;
69 }
70 if (!dictionary->GetDictionary("args", &args)) {
71 LOG(ERROR) << "args is missing from TraceEvent JSON";
72 return false;
73 }
74 if (require_id && !dictionary->GetString("id", &id)) {
75 LOG(ERROR) << "id is missing from START/FINISH TraceEvent JSON";
76 return false;
77 }
78
79 // For each argument, copy the type and create a trace_analyzer::TraceValue.
80 base::DictionaryValue::key_iterator keyi = args->begin_keys();
81 for (; keyi != args->end_keys(); ++keyi) {
82 std::string str;
83 bool boolean = false;
84 int int_num = 0;
85 double double_num = 0.0;
86 Value* value = NULL;
87 if (args->GetWithoutPathExpansion(*keyi, &value)) {
88 if (value->GetAsString(&str))
89 arg_strings[*keyi] = str;
90 else if (value->GetAsInteger(&int_num))
91 arg_numbers[*keyi] = static_cast<double>(int_num);
92 else if (value->GetAsBoolean(&boolean))
93 arg_numbers[*keyi] = static_cast<double>(boolean ? 1 : 0);
94 else if (value->GetAsDouble(&double_num))
95 arg_numbers[*keyi] = double_num;
96 else {
97 LOG(ERROR) << "Value type of argument is not supported: " <<
98 static_cast<int>(value->GetType());
99 return false; // Invalid trace event JSON format.
66 } 100 }
67 } 101 }
68
69 return true;
70 } 102 }
71 103
72 return false; 104 return true;
73 } 105 }
74 106
75 double TraceEvent::GetAbsTimeToOtherEvent() const { 107 double TraceEvent::GetAbsTimeToOtherEvent() const {
76 return fabs(other_event->timestamp - timestamp); 108 return fabs(other_event->timestamp - timestamp);
77 } 109 }
78 110
79 bool TraceEvent::GetArgAsString(const std::string& name, 111 bool TraceEvent::GetArgAsString(const std::string& name,
80 std::string* arg) const { 112 std::string* arg) const {
81 std::map<std::string, std::string>::const_iterator i = arg_strings.find(name); 113 std::map<std::string, std::string>::const_iterator i = arg_strings.find(name);
82 if (i != arg_strings.end()) { 114 if (i != arg_strings.end()) {
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 } 461 }
430 case EVENT_PHASE: 462 case EVENT_PHASE:
431 case OTHER_PHASE: 463 case OTHER_PHASE:
432 return static_cast<double>(the_event->phase); 464 return static_cast<double>(the_event->phase);
433 case EVENT_CATEGORY: 465 case EVENT_CATEGORY:
434 case OTHER_CATEGORY: 466 case OTHER_CATEGORY:
435 return the_event->category; 467 return the_event->category;
436 case EVENT_NAME: 468 case EVENT_NAME:
437 case OTHER_NAME: 469 case OTHER_NAME:
438 return the_event->name; 470 return the_event->name;
471 case EVENT_ID:
472 case OTHER_ID:
473 return the_event->id;
439 case EVENT_HAS_STRING_ARG: 474 case EVENT_HAS_STRING_ARG:
440 case OTHER_HAS_STRING_ARG: 475 case OTHER_HAS_STRING_ARG:
441 return (the_event->HasStringArg(string_) ? 1.0 : 0.0); 476 return (the_event->HasStringArg(string_) ? 1.0 : 0.0);
442 case EVENT_HAS_NUMBER_ARG: 477 case EVENT_HAS_NUMBER_ARG:
443 case OTHER_HAS_NUMBER_ARG: 478 case OTHER_HAS_NUMBER_ARG:
444 return (the_event->HasNumberArg(string_) ? 1.0 : 0.0); 479 return (the_event->HasNumberArg(string_) ? 1.0 : 0.0);
445 case EVENT_ARG: 480 case EVENT_ARG:
446 case OTHER_ARG: 481 case OTHER_ARG:
447 { 482 {
448 // Search for the argument name and return its value if found. 483 // Search for the argument name and return its value if found.
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 if (!ParseEventsFromJson(json_events, &raw_events_)) 669 if (!ParseEventsFromJson(json_events, &raw_events_))
635 return false; 670 return false;
636 std::stable_sort(raw_events_.begin(), raw_events_.end()); 671 std::stable_sort(raw_events_.begin(), raw_events_.end());
637 ParseMetadata(); 672 ParseMetadata();
638 return true; 673 return true;
639 } 674 }
640 675
641 void TraceAnalyzer::AssociateBeginEndEvents() { 676 void TraceAnalyzer::AssociateBeginEndEvents() {
642 using namespace trace_analyzer; 677 using namespace trace_analyzer;
643 678
644 Query begin(Query(EVENT_PHASE) == 679 Query begin(Query(EVENT_PHASE) == Query::Phase(TRACE_EVENT_PHASE_BEGIN));
645 Query::Phase(TRACE_EVENT_PHASE_BEGIN)); 680 Query end(Query(EVENT_PHASE) == Query::Phase(TRACE_EVENT_PHASE_END));
646 Query end(Query(EVENT_PHASE) ==
647 Query::Phase(TRACE_EVENT_PHASE_END));
648 Query match(Query(EVENT_NAME) == Query(OTHER_NAME) && 681 Query match(Query(EVENT_NAME) == Query(OTHER_NAME) &&
649 Query(EVENT_CATEGORY) == Query(OTHER_CATEGORY) && 682 Query(EVENT_CATEGORY) == Query(OTHER_CATEGORY) &&
650 Query(EVENT_TID) == Query(OTHER_TID) && 683 Query(EVENT_TID) == Query(OTHER_TID) &&
651 Query(EVENT_PID) == Query(OTHER_PID)); 684 Query(EVENT_PID) == Query(OTHER_PID));
652 685
653 AssociateEvents(begin, end, match); 686 AssociateEvents(begin, end, match);
654 } 687 }
655 688
689 void TraceAnalyzer::AssociateStartFinishEvents() {
690 using namespace trace_analyzer;
691
692 Query begin(Query(EVENT_PHASE) == Query::Phase(TRACE_EVENT_PHASE_START));
693 Query end(Query(EVENT_PHASE) == Query::Phase(TRACE_EVENT_PHASE_FINISH));
694 Query match(Query(EVENT_NAME) == Query(OTHER_NAME) &&
695 Query(EVENT_CATEGORY) == Query(OTHER_CATEGORY) &&
696 Query(EVENT_ID) == Query(OTHER_ID));
697
698 AssociateEvents(begin, end, match);
699 }
700
656 void TraceAnalyzer::AssociateEvents(const Query& first, 701 void TraceAnalyzer::AssociateEvents(const Query& first,
657 const Query& second, 702 const Query& second,
658 const Query& match) { 703 const Query& match) {
659 DCHECK(allow_assocation_changes_) << "AssociateEvents not allowed after " 704 DCHECK(allow_assocation_changes_) << "AssociateEvents not allowed after "
660 "FindEvents"; 705 "FindEvents";
661 706
662 // Search for matching begin/end event pairs. When a matching end is found, 707 // Search for matching begin/end event pairs. When a matching end is found,
663 // it is associated with the begin event. 708 // it is associated with the begin event.
664 std::vector<TraceEvent*> begin_stack; 709 std::vector<TraceEvent*> begin_stack;
665 for (size_t event_index = 0; event_index < raw_events_.size(); 710 for (size_t event_index = 0; event_index < raw_events_.size();
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 continue; 767 continue;
723 std::map<std::string, std::string>::const_iterator string_it = 768 std::map<std::string, std::string>::const_iterator string_it =
724 this_event.arg_strings.find("name"); 769 this_event.arg_strings.find("name");
725 if (string_it != this_event.arg_strings.end()) 770 if (string_it != this_event.arg_strings.end())
726 thread_names_[this_event.thread] = string_it->second; 771 thread_names_[this_event.thread] = string_it->second;
727 } 772 }
728 } 773 }
729 774
730 } // namespace trace_analyzer 775 } // namespace trace_analyzer
731 776
OLDNEW
« no previous file with comments | « base/test/trace_event_analyzer.h ('k') | base/test/trace_event_analyzer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698