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

Side by Side Diff: base/trace_event/trace_event_impl.cc

Issue 1115023003: [Startup Tracing] The TraceConfig class [STALE] (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 months 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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/trace_event/trace_event_impl.h" 5 #include "base/trace_event/trace_event_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 9
10 #include "base/base_switches.h" 10 #include "base/base_switches.h"
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/debug/leak_annotations.h" 13 #include "base/debug/leak_annotations.h"
14 #include "base/format_macros.h" 14 #include "base/format_macros.h"
15 #include "base/json/json_reader.h"
16 #include "base/json/json_writer.h"
15 #include "base/json/string_escape.h" 17 #include "base/json/string_escape.h"
16 #include "base/lazy_instance.h" 18 #include "base/lazy_instance.h"
17 #include "base/location.h" 19 #include "base/location.h"
18 #include "base/memory/singleton.h" 20 #include "base/memory/singleton.h"
19 #include "base/process/process_metrics.h" 21 #include "base/process/process_metrics.h"
20 #include "base/stl_util.h" 22 #include "base/stl_util.h"
21 #include "base/strings/string_number_conversions.h" 23 #include "base/strings/string_number_conversions.h"
22 #include "base/strings/string_split.h" 24 #include "base/strings/string_split.h"
23 #include "base/strings/string_tokenizer.h" 25 #include "base/strings/string_tokenizer.h"
24 #include "base/strings/string_util.h" 26 #include "base/strings/string_util.h"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 const int kOverheadReportThresholdInMicroseconds = 50; 64 const int kOverheadReportThresholdInMicroseconds = 50;
63 65
64 // String options that can be used to initialize TraceOptions. 66 // String options that can be used to initialize TraceOptions.
65 const char kRecordUntilFull[] = "record-until-full"; 67 const char kRecordUntilFull[] = "record-until-full";
66 const char kRecordContinuously[] = "record-continuously"; 68 const char kRecordContinuously[] = "record-continuously";
67 const char kRecordAsMuchAsPossible[] = "record-as-much-as-possible"; 69 const char kRecordAsMuchAsPossible[] = "record-as-much-as-possible";
68 const char kTraceToConsole[] = "trace-to-console"; 70 const char kTraceToConsole[] = "trace-to-console";
69 const char kEnableSampling[] = "enable-sampling"; 71 const char kEnableSampling[] = "enable-sampling";
70 const char kEnableSystrace[] = "enable-systrace"; 72 const char kEnableSystrace[] = "enable-systrace";
71 73
74 // String parameters that can be used to parse the trace config string.
75 const char kRecordModeParam[] = "record_mode";
76 const char kEnableSamplingParam[] = "enable_sampling";
77 const char kEnableSystraceParam[] = "enable_systrace";
78 const char kIncludedCategoriesParam[] = "included_categories";
79 const char kDisabledCategoriesParam[] = "disabled_categories";
80 const char kExcludedCategoriesParam[] = "excluded_categories";
81 const char kSyntheticDelaysParam[] = "synthetic_delays";
82
72 // Controls the number of trace events we will buffer in-memory 83 // Controls the number of trace events we will buffer in-memory
73 // before throwing them away. 84 // before throwing them away.
74 const size_t kTraceBufferChunkSize = TraceBufferChunk::kTraceBufferChunkSize; 85 const size_t kTraceBufferChunkSize = TraceBufferChunk::kTraceBufferChunkSize;
75 const size_t kTraceEventVectorBigBufferChunks = 86 const size_t kTraceEventVectorBigBufferChunks =
76 512000000 / kTraceBufferChunkSize; 87 512000000 / kTraceBufferChunkSize;
77 const size_t kTraceEventVectorBufferChunks = 256000 / kTraceBufferChunkSize; 88 const size_t kTraceEventVectorBufferChunks = 256000 / kTraceBufferChunkSize;
78 const size_t kTraceEventRingBufferChunks = kTraceEventVectorBufferChunks / 4; 89 const size_t kTraceEventRingBufferChunks = kTraceEventVectorBufferChunks / 4;
79 const size_t kTraceEventBufferSizeInBytes = 100 * 1024; 90 const size_t kTraceEventBufferSizeInBytes = 100 * 1024;
80 // Can store results for 30 seconds with 1 ms sampling interval. 91 // Can store results for 30 seconds with 1 ms sampling interval.
81 const size_t kMonitorTraceEventBufferChunks = 30000 / kTraceBufferChunkSize; 92 const size_t kMonitorTraceEventBufferChunks = 30000 / kTraceBufferChunkSize;
(...skipping 2298 matching lines...) Expand 10 before | Expand all | Expand 10 after
2380 void TraceLog::SetCurrentThreadBlocksMessageLoop() { 2391 void TraceLog::SetCurrentThreadBlocksMessageLoop() {
2381 thread_blocks_message_loop_.Set(true); 2392 thread_blocks_message_loop_.Set(true);
2382 if (thread_local_event_buffer_.Get()) { 2393 if (thread_local_event_buffer_.Get()) {
2383 // This will flush the thread local buffer. 2394 // This will flush the thread local buffer.
2384 delete thread_local_event_buffer_.Get(); 2395 delete thread_local_event_buffer_.Get();
2385 } 2396 }
2386 } 2397 }
2387 2398
2388 bool CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace( 2399 bool CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace(
2389 const std::string& str) { 2400 const std::string& str) {
2390 return str.empty() || 2401 return TraceConfig::IsEmptyOrContainsLeadingOrTrailingWhitespace(str);
2391 str.at(0) == ' ' ||
2392 str.at(str.length() - 1) == ' ';
2393 } 2402 }
2394 2403
2395 CategoryFilter::CategoryFilter(const std::string& filter_string) { 2404 CategoryFilter::CategoryFilter(const std::string& filter_string)
2396 if (!filter_string.empty()) 2405 : config_(new TraceConfig(filter_string, "")) {
2397 Initialize(filter_string);
2398 else
2399 Initialize(CategoryFilter::kDefaultCategoryFilterString);
2400 } 2406 }
2401 2407
2402 CategoryFilter::CategoryFilter() { 2408 CategoryFilter::CategoryFilter()
2403 Initialize(CategoryFilter::kDefaultCategoryFilterString); 2409 : config_(new TraceConfig()) {
2404 } 2410 }
2405 2411
2406 CategoryFilter::CategoryFilter(const CategoryFilter& cf) 2412 CategoryFilter::CategoryFilter(const CategoryFilter& cf)
2407 : included_(cf.included_), 2413 : config_(new TraceConfig(*(cf.config_))) {
2408 disabled_(cf.disabled_),
2409 excluded_(cf.excluded_),
2410 delays_(cf.delays_) {
2411 } 2414 }
2412 2415
2413 CategoryFilter::~CategoryFilter() { 2416 CategoryFilter::~CategoryFilter() {
2414 } 2417 }
2415 2418
2416 CategoryFilter& CategoryFilter::operator=(const CategoryFilter& rhs) { 2419 CategoryFilter& CategoryFilter::operator=(const CategoryFilter& rhs) {
2417 if (this == &rhs) 2420 if (this == &rhs)
2418 return *this; 2421 return *this;
2419 2422
2420 included_ = rhs.included_; 2423 config_.reset(new TraceConfig(*(rhs.config_)));
2421 disabled_ = rhs.disabled_;
2422 excluded_ = rhs.excluded_;
2423 delays_ = rhs.delays_;
2424 return *this; 2424 return *this;
2425 } 2425 }
2426 2426
2427 void CategoryFilter::Initialize(const std::string& filter_string) {
2428 // Tokenize list of categories, delimited by ','.
2429 StringTokenizer tokens(filter_string, ",");
2430 // Add each token to the appropriate list (included_,excluded_).
2431 while (tokens.GetNext()) {
2432 std::string category = tokens.token();
2433 // Ignore empty categories.
2434 if (category.empty())
2435 continue;
2436 // Synthetic delays are of the form 'DELAY(delay;option;option;...)'.
2437 if (category.find(kSyntheticDelayCategoryFilterPrefix) == 0 &&
2438 category.at(category.size() - 1) == ')') {
2439 category = category.substr(
2440 strlen(kSyntheticDelayCategoryFilterPrefix),
2441 category.size() - strlen(kSyntheticDelayCategoryFilterPrefix) - 1);
2442 size_t name_length = category.find(';');
2443 if (name_length != std::string::npos && name_length > 0 &&
2444 name_length != category.size() - 1) {
2445 delays_.push_back(category);
2446 }
2447 } else if (category.at(0) == '-') {
2448 // Excluded categories start with '-'.
2449 // Remove '-' from category string.
2450 category = category.substr(1);
2451 excluded_.push_back(category);
2452 } else if (category.compare(0, strlen(TRACE_DISABLED_BY_DEFAULT("")),
2453 TRACE_DISABLED_BY_DEFAULT("")) == 0) {
2454 disabled_.push_back(category);
2455 } else {
2456 included_.push_back(category);
2457 }
2458 }
2459 }
2460
2461 void CategoryFilter::WriteString(const StringList& values, 2427 void CategoryFilter::WriteString(const StringList& values,
2462 std::string* out, 2428 std::string* out,
2463 bool included) const { 2429 bool included) const {
2464 bool prepend_comma = !out->empty(); 2430 bool prepend_comma = !out->empty();
2465 int token_cnt = 0; 2431 int token_cnt = 0;
2466 for (StringList::const_iterator ci = values.begin(); 2432 for (StringList::const_iterator ci = values.begin();
2467 ci != values.end(); ++ci) { 2433 ci != values.end(); ++ci) {
2468 if (token_cnt > 0 || prepend_comma) 2434 if (token_cnt > 0 || prepend_comma)
2469 StringAppendF(out, ","); 2435 StringAppendF(out, ",");
2470 StringAppendF(out, "%s%s", (included ? "" : "-"), ci->c_str()); 2436 StringAppendF(out, "%s%s", (included ? "" : "-"), ci->c_str());
(...skipping 10 matching lines...) Expand all
2481 if (token_cnt > 0 || prepend_comma) 2447 if (token_cnt > 0 || prepend_comma)
2482 StringAppendF(out, ","); 2448 StringAppendF(out, ",");
2483 StringAppendF(out, "%s%s)", kSyntheticDelayCategoryFilterPrefix, 2449 StringAppendF(out, "%s%s)", kSyntheticDelayCategoryFilterPrefix,
2484 ci->c_str()); 2450 ci->c_str());
2485 ++token_cnt; 2451 ++token_cnt;
2486 } 2452 }
2487 } 2453 }
2488 2454
2489 std::string CategoryFilter::ToString() const { 2455 std::string CategoryFilter::ToString() const {
2490 std::string filter_string; 2456 std::string filter_string;
2491 WriteString(included_, &filter_string, true); 2457 WriteString(config_->included_categories_, &filter_string, true);
2492 WriteString(disabled_, &filter_string, true); 2458 WriteString(config_->disabled_categories_, &filter_string, true);
2493 WriteString(excluded_, &filter_string, false); 2459 WriteString(config_->excluded_categories_, &filter_string, false);
2494 WriteString(delays_, &filter_string); 2460 WriteString(config_->synthetic_delays_, &filter_string);
2495 return filter_string; 2461 return filter_string;
2496 } 2462 }
2497 2463
2498 bool CategoryFilter::IsCategoryGroupEnabled( 2464 bool CategoryFilter::IsCategoryGroupEnabled(
2499 const char* category_group_name) const { 2465 const char* category_group_name) const {
2466 return config_->IsCategoryGroupEnabled(category_group_name);
2467 }
2468
2469 bool CategoryFilter::IsCategoryEnabled(const char* category_name) const {
2470 return config_->IsCategoryEnabled(category_name);
2471 }
2472
2473 bool CategoryFilter::HasIncludedPatterns() const {
2474 return config_->HasIncludedPatterns();
2475 }
2476
2477 void CategoryFilter::Merge(const CategoryFilter& nested_filter) {
2478 config_->Merge(*(nested_filter.config_));
2479 }
2480
2481 void CategoryFilter::Clear() {
2482 config_->included_categories_.clear();
2483 config_->disabled_categories_.clear();
2484 config_->excluded_categories_.clear();
2485 }
2486
2487 const CategoryFilter::StringList&
2488 CategoryFilter::GetSyntheticDelayValues() const {
2489 return config_->GetSyntheticDelayValues();
2490 }
2491
2492 ////////////////////////////////////////////////////////////////////////////////
2493 //
2494 // TraceConfig
2495 //
2496 ////////////////////////////////////////////////////////////////////////////////
2497
2498 TraceConfig::TraceConfig() {
2499 Initialize(TraceConfig::kDefaultTraceConfigString);
2500 }
2501
2502 TraceConfig::TraceConfig(const CategoryFilter& cf,
2503 const TraceOptions& options) {
2504 record_mode_ = options.record_mode;
2505 enable_sampling_ = options.enable_sampling;
2506 enable_systrace_ = options.enable_systrace;
2507
2508 included_categories_ = cf.config_->included_categories_;
2509 disabled_categories_ = cf.config_->disabled_categories_;
2510 excluded_categories_ = cf.config_->excluded_categories_;
2511 synthetic_delays_ = cf.config_->synthetic_delays_;
2512 }
2513
2514 TraceConfig::TraceConfig(const std::string& category_filter_string,
2515 const std::string& trace_options_string) {
2516 if (!category_filter_string.empty()) {
2517 // Tokenize list of categories, delimited by ','.
2518 StringTokenizer tokens(category_filter_string, ",");
nednguyen 2015/05/11 17:59:28 nits: you want to be consistent about using single
Zhen Wang 2015/05/13 00:01:10 Use SplitString now.
2519 // Add each token to the appropriate list (included_,excluded_).
2520 while (tokens.GetNext()) {
2521 std::string category = tokens.token();
2522 // Ignore empty categories.
2523 if (category.empty())
2524 continue;
2525 // Synthetic delays are of the form 'DELAY(delay;option;option;...)'.
nednguyen 2015/05/11 17:59:28 What about cases like ' Delay(delay; option; opt
Zhen Wang 2015/05/13 00:01:10 Use SplitString now to get leading-and-trailing-sp
2526 if (category.find(kSyntheticDelayCategoryFilterPrefix) == 0 &&
2527 category.at(category.size() - 1) == ')') {
2528 category = category.substr(
2529 strlen(kSyntheticDelayCategoryFilterPrefix),
2530 category.size() - strlen(kSyntheticDelayCategoryFilterPrefix) - 1);
2531 size_t name_length = category.find(';');
2532 if (name_length != std::string::npos && name_length > 0 &&
2533 name_length != category.size() - 1) {
2534 synthetic_delays_.push_back(category);
2535 }
2536 } else if (category.at(0) == '-') {
2537 // Excluded categories start with '-'.
2538 // Remove '-' from category string.
2539 category = category.substr(1);
2540 excluded_categories_.push_back(category);
2541 } else if (category.compare(0, strlen(TRACE_DISABLED_BY_DEFAULT("")),
2542 TRACE_DISABLED_BY_DEFAULT("")) == 0) {
2543 disabled_categories_.push_back(category);
2544 } else {
2545 included_categories_.push_back(category);
2546 }
2547 }
2548 } else {
2549 Initialize(TraceConfig::kDefaultTraceConfigString);
2550 }
2551
2552 record_mode_ = RECORD_UNTIL_FULL;
2553 enable_sampling_ = false;
2554 enable_systrace_ = false;
2555 if(!trace_options_string.empty()) {
2556 std::vector<std::string> split;
2557 std::vector<std::string>::iterator iter;
2558 base::SplitString(trace_options_string, ',', &split);
nednguyen 2015/05/11 17:59:28 while use StringTokenizer above but use SplitStrin
Zhen Wang 2015/05/13 00:01:10 Updated above with SplitString, so that leading an
2559 for (iter = split.begin(); iter != split.end(); ++iter) {
2560 if (*iter == kRecordUntilFull) {
2561 record_mode_ = RECORD_UNTIL_FULL;
2562 } else if (*iter == kRecordContinuously) {
2563 record_mode_ = RECORD_CONTINUOUSLY;
2564 } else if (*iter == kTraceToConsole) {
2565 record_mode_ = ECHO_TO_CONSOLE;
2566 } else if (*iter == kRecordAsMuchAsPossible) {
2567 record_mode_ = RECORD_AS_MUCH_AS_POSSIBLE;
2568 } else if (*iter == kEnableSampling) {
2569 enable_sampling_ = true;
2570 } else if (*iter == kEnableSystrace) {
2571 enable_systrace_ = true;
2572 }
2573 }
2574 }
2575 }
2576
2577 TraceConfig::TraceConfig(const std::string& config_string) {
2578 if (!config_string.empty())
2579 Initialize(config_string);
2580 else
2581 Initialize(TraceConfig::kDefaultTraceConfigString);
2582 }
2583
2584 TraceConfig::TraceConfig(const TraceConfig& tc)
2585 : record_mode_(tc.record_mode_),
2586 enable_sampling_(tc.enable_sampling_),
2587 enable_systrace_(tc.enable_systrace_),
2588 included_categories_(tc.included_categories_),
2589 disabled_categories_(tc.disabled_categories_),
2590 excluded_categories_(tc.excluded_categories_),
2591 synthetic_delays_(tc.synthetic_delays_) {
2592 }
2593
2594 TraceConfig::~TraceConfig() {
2595 }
2596
2597 TraceConfig& TraceConfig::operator=(const TraceConfig& rhs) {
2598 if (this == &rhs)
2599 return *this;
2600
2601 record_mode_ = rhs.record_mode_;
2602 enable_sampling_ = rhs.enable_sampling_;
2603 enable_systrace_ = rhs.enable_systrace_;
2604 included_categories_ = rhs.included_categories_;
2605 disabled_categories_ = rhs.disabled_categories_;
2606 excluded_categories_ = rhs.excluded_categories_;
2607 synthetic_delays_ = rhs.synthetic_delays_;
2608 return *this;
2609 }
2610
2611 const TraceConfig::StringList& TraceConfig::GetSyntheticDelayValues() const {
2612 return synthetic_delays_;
2613 }
2614
2615 void TraceConfig::ToCategoryFilter(CategoryFilter& cf) const {
2616 cf.config_.reset(new TraceConfig(*this));
2617 }
2618
2619 void TraceConfig::ToTraceOptions(TraceOptions& options) const {
2620 options.record_mode = record_mode_;
2621 options.enable_sampling = enable_sampling_;
2622 options.enable_systrace = enable_systrace_;
2623 }
2624
2625 void TraceConfig::ToDict(base::DictionaryValue& dict) const {
2626 switch (record_mode_) {
2627 case RECORD_UNTIL_FULL:
2628 dict.SetString(kRecordModeParam, kRecordUntilFull);
2629 break;
2630 case RECORD_CONTINUOUSLY:
2631 dict.SetString(kRecordModeParam, kRecordContinuously);
2632 break;
2633 case ECHO_TO_CONSOLE:
2634 dict.SetString(kRecordModeParam, kTraceToConsole);
2635 break;
2636 case RECORD_AS_MUCH_AS_POSSIBLE:
2637 dict.SetString(kRecordModeParam, kRecordAsMuchAsPossible);
2638 break;
2639 default:
2640 NOTREACHED();
2641 }
2642
2643 if (enable_sampling_)
2644 dict.SetBoolean(kEnableSamplingParam, true);
2645 else
2646 dict.SetBoolean(kEnableSamplingParam, false);
2647
2648 if (enable_systrace_)
2649 dict.SetBoolean(kEnableSystraceParam, true);
2650 else
2651 dict.SetBoolean(kEnableSystraceParam, false);
2652
2653 AddCategoryToDict(dict, kIncludedCategoriesParam, included_categories_);
2654 AddCategoryToDict(dict, kDisabledCategoriesParam, disabled_categories_);
2655 AddCategoryToDict(dict, kExcludedCategoriesParam, excluded_categories_);
2656 AddCategoryToDict(dict, kSyntheticDelaysParam, synthetic_delays_);
2657 }
2658
2659 std::string TraceConfig::ToString() const {
2660 base::DictionaryValue dict;
2661 ToDict(dict);
2662
2663 std::string json;
2664 base::JSONWriter::Write(&dict, &json);
2665
2666 return json;
2667 }
2668
2669 std::string TraceConfig::ToCategoryFilterString() const {
2670 CategoryFilter cf;
2671 ToCategoryFilter(cf);
2672 return cf.ToString();
2673 }
2674
2675 std::string TraceConfig::ToTraceOptionsString() const {
2676 TraceOptions to;
2677 ToTraceOptions(to);
2678 return to.ToString();
2679 }
2680
2681 void TraceConfig::AddCategoryToDict(base::DictionaryValue& dict,
2682 const char* param,
2683 const StringList& categories) const {
2684 if (categories.empty())
2685 return;
2686
2687 scoped_ptr<base::ListValue> list(new base::ListValue());
2688 for (StringList::const_iterator ci = categories.begin();
2689 ci != categories.end();
2690 ++ci) {
2691 list->AppendString(*ci);
2692 }
2693
2694 dict.Set(param, list.Pass());
2695 }
2696
2697 void TraceConfig::Merge(const TraceConfig& config) {
2698 if (record_mode_ != config.record_mode_
2699 || enable_sampling_ != config.enable_sampling_
2700 || enable_systrace_ != config.enable_systrace_) {
2701 DLOG(ERROR) << "Attempting to merge trace config with a different "
2702 << "set of options.";
2703 }
2704
2705 // Keep included patterns only if both filters have an included entry.
2706 // Otherwise, one of the filter was specifying "*" and we want to honor the
2707 // broadest filter.
2708 if (HasIncludedPatterns() && config.HasIncludedPatterns()) {
2709 included_categories_.insert(included_categories_.end(),
2710 config.included_categories_.begin(),
2711 config.included_categories_.end());
2712 } else {
2713 included_categories_.clear();
2714 }
2715
2716 disabled_categories_.insert(disabled_categories_.end(),
2717 config.disabled_categories_.begin(),
2718 config.disabled_categories_.end());
2719 excluded_categories_.insert(excluded_categories_.end(),
2720 config.excluded_categories_.begin(),
2721 config.excluded_categories_.end());
2722 synthetic_delays_.insert(synthetic_delays_.end(),
2723 config.synthetic_delays_.begin(),
2724 config.synthetic_delays_.end());
2725 }
2726
2727 void TraceConfig::Clear() {
2728 record_mode_ = RECORD_UNTIL_FULL;
2729 enable_sampling_ = false;
2730 enable_systrace_ = false;
2731 included_categories_.clear();
2732 disabled_categories_.clear();
2733 excluded_categories_.clear();
2734 synthetic_delays_.clear();
2735 }
2736
2737
2738 void TraceConfig::Initialize(const std::string& config_string) {
dsinclair 2015/05/08 17:44:49 Can you move this up to just below the constructor
Zhen Wang 2015/05/13 00:01:10 Done.
2739 scoped_ptr<base::Value> value(base::JSONReader::Read(config_string));
2740 if (!value || !value->IsType(base::Value::TYPE_DICTIONARY))
2741 return;
2742 scoped_ptr<base::DictionaryValue> dict(
2743 static_cast<base::DictionaryValue*>(value.release()));
2744
2745 std::string record_mode;
2746 if (dict->GetString(kRecordModeParam, &record_mode)) {
2747 if (record_mode == kRecordUntilFull) {
2748 record_mode_ = RECORD_UNTIL_FULL;
2749 } else if (record_mode == kRecordContinuously) {
2750 record_mode_ = RECORD_CONTINUOUSLY;
2751 } else if (record_mode == kTraceToConsole) {
2752 record_mode_ = ECHO_TO_CONSOLE;
2753 } else if (record_mode == kRecordAsMuchAsPossible) {
2754 record_mode_ = RECORD_AS_MUCH_AS_POSSIBLE;
2755 }
2756 } else {
2757 record_mode_ = RECORD_UNTIL_FULL;
2758 }
2759
2760 if (!dict->GetBoolean(kEnableSamplingParam, &enable_sampling_))
2761 enable_sampling_ = false;
2762 if (!dict->GetBoolean(kEnableSystraceParam, &enable_systrace_))
2763 enable_systrace_ = false;
2764
2765 base::ListValue* category_list = NULL;
2766 if (dict->GetList(kIncludedCategoriesParam, &category_list))
2767 SetCategoriesFromList(included_categories_, *category_list);
2768 if (dict->GetList(kDisabledCategoriesParam, &category_list))
2769 SetCategoriesFromList(disabled_categories_, *category_list);
2770 if (dict->GetList(kExcludedCategoriesParam, &category_list))
2771 SetCategoriesFromList(excluded_categories_, *category_list);
2772 if (dict->GetList(kSyntheticDelaysParam, &category_list))
2773 SetCategoriesFromList(synthetic_delays_, *category_list);
2774 }
2775
2776 void TraceConfig::SetCategoriesFromList(StringList& categories,
2777 const base::ListValue& list) {
2778 categories.clear();
2779 for (size_t i = 0; i < list.GetSize(); ++i) {
2780 std::string category;
2781 if (list.GetString(i, &category))
2782 categories.push_back(category);
2783 }
2784 }
2785
2786 bool TraceConfig::IsCategoryGroupEnabled(
2787 const char* category_group_name) const {
2500 // TraceLog should call this method only as part of enabling/disabling 2788 // TraceLog should call this method only as part of enabling/disabling
2501 // categories. 2789 // categories.
2502 2790
2503 bool had_enabled_by_default = false; 2791 bool had_enabled_by_default = false;
2504 DCHECK(category_group_name); 2792 DCHECK(category_group_name);
2505 CStringTokenizer category_group_tokens( 2793 CStringTokenizer category_group_tokens(
2506 category_group_name, category_group_name + strlen(category_group_name), 2794 category_group_name, category_group_name + strlen(category_group_name),
2507 ","); 2795 ",");
2508 while (category_group_tokens.GetNext()) { 2796 while (category_group_tokens.GetNext()) {
2509 std::string category_group_token = category_group_tokens.token(); 2797 std::string category_group_token = category_group_tokens.token();
2510 // Don't allow empty tokens, nor tokens with leading or trailing space. 2798 // Don't allow empty tokens, nor tokens with leading or trailing space.
2511 DCHECK(!CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace( 2799 DCHECK(!TraceConfig::IsEmptyOrContainsLeadingOrTrailingWhitespace(
2512 category_group_token)) 2800 category_group_token))
2513 << "Disallowed category string"; 2801 << "Disallowed category string";
2514 if (IsCategoryEnabled(category_group_token.c_str())) { 2802 if (IsCategoryEnabled(category_group_token.c_str())) {
2515 return true; 2803 return true;
2516 } 2804 }
2517 if (!MatchPattern(category_group_token.c_str(), 2805 if (!MatchPattern(category_group_token.c_str(),
2518 TRACE_DISABLED_BY_DEFAULT("*"))) 2806 TRACE_DISABLED_BY_DEFAULT("*")))
2519 had_enabled_by_default = true; 2807 had_enabled_by_default = true;
2520 } 2808 }
2521 // Do a second pass to check for explicitly disabled categories 2809 // Do a second pass to check for explicitly disabled categories
2522 // (those explicitly enabled have priority due to first pass). 2810 // (those explicitly enabled have priority due to first pass).
2523 category_group_tokens.Reset(); 2811 category_group_tokens.Reset();
2524 bool category_group_disabled = false; 2812 bool category_group_disabled = false;
2525 while (category_group_tokens.GetNext()) { 2813 while (category_group_tokens.GetNext()) {
2526 std::string category_group_token = category_group_tokens.token(); 2814 std::string category_group_token = category_group_tokens.token();
2527 for (StringList::const_iterator ci = excluded_.begin(); 2815 for (StringList::const_iterator ci = excluded_categories_.begin();
2528 ci != excluded_.end(); ++ci) { 2816 ci != excluded_categories_.end();
2817 ++ci) {
2529 if (MatchPattern(category_group_token.c_str(), ci->c_str())) { 2818 if (MatchPattern(category_group_token.c_str(), ci->c_str())) {
2530 // Current token of category_group_name is present in excluded_list. 2819 // Current token of category_group_name is present in excluded_list.
2531 // Flag the exclusion and proceed further to check if any of the 2820 // Flag the exclusion and proceed further to check if any of the
2532 // remaining categories of category_group_name is not present in the 2821 // remaining categories of category_group_name is not present in the
2533 // excluded_ list. 2822 // excluded_ list.
2534 category_group_disabled = true; 2823 category_group_disabled = true;
2535 break; 2824 break;
2536 } 2825 }
2537 // One of the category of category_group_name is not present in 2826 // One of the category of category_group_name is not present in
2538 // excluded_ list. So, it has to be included_ list. Enable the 2827 // excluded_ list. So, it has to be included_ list. Enable the
2539 // category_group_name for recording. 2828 // category_group_name for recording.
2540 category_group_disabled = false; 2829 category_group_disabled = false;
2541 } 2830 }
2542 // One of the categories present in category_group_name is not present in 2831 // One of the categories present in category_group_name is not present in
2543 // excluded_ list. Implies this category_group_name group can be enabled 2832 // excluded_ list. Implies this category_group_name group can be enabled
2544 // for recording, since one of its groups is enabled for recording. 2833 // for recording, since one of its groups is enabled for recording.
2545 if (!category_group_disabled) 2834 if (!category_group_disabled)
2546 break; 2835 break;
2547 } 2836 }
2548 // If the category group is not excluded, and there are no included patterns 2837 // If the category group is not excluded, and there are no included patterns
2549 // we consider this category group enabled, as long as it had categories 2838 // we consider this category group enabled, as long as it had categories
2550 // other than disabled-by-default. 2839 // other than disabled-by-default.
2551 return !category_group_disabled && 2840 return !category_group_disabled &&
2552 included_.empty() && had_enabled_by_default; 2841 included_categories_.empty() && had_enabled_by_default;
2553 } 2842 }
2554 2843
2555 bool CategoryFilter::IsCategoryEnabled(const char* category_name) const { 2844 bool TraceConfig::IsCategoryEnabled(const char* category_name) const {
2556 StringList::const_iterator ci; 2845 StringList::const_iterator ci;
2557 2846
2558 // Check the disabled- filters and the disabled-* wildcard first so that a 2847 // Check the disabled- filters and the disabled-* wildcard first so that a
2559 // "*" filter does not include the disabled. 2848 // "*" filter does not include the disabled.
2560 for (ci = disabled_.begin(); ci != disabled_.end(); ++ci) { 2849 for (ci = disabled_categories_.begin();
2850 ci != disabled_categories_.end();
2851 ++ci) {
2561 if (MatchPattern(category_name, ci->c_str())) 2852 if (MatchPattern(category_name, ci->c_str()))
2562 return true; 2853 return true;
2563 } 2854 }
2564 2855
2565 if (MatchPattern(category_name, TRACE_DISABLED_BY_DEFAULT("*"))) 2856 if (MatchPattern(category_name, TRACE_DISABLED_BY_DEFAULT("*")))
2566 return false; 2857 return false;
2567 2858
2568 for (ci = included_.begin(); ci != included_.end(); ++ci) { 2859 for (ci = included_categories_.begin();
2860 ci != included_categories_.end();
2861 ++ci) {
2569 if (MatchPattern(category_name, ci->c_str())) 2862 if (MatchPattern(category_name, ci->c_str()))
2570 return true; 2863 return true;
2571 } 2864 }
2572 2865
2573 return false; 2866 return false;
2574 } 2867 }
2575 2868
2576 bool CategoryFilter::HasIncludedPatterns() const { 2869 bool TraceConfig::IsEmptyOrContainsLeadingOrTrailingWhitespace(
2577 return !included_.empty(); 2870 const std::string& str) {
2871 return str.empty() ||
2872 str.at(0) == ' ' ||
2873 str.at(str.length() - 1) == ' ';
2578 } 2874 }
2579 2875
2580 void CategoryFilter::Merge(const CategoryFilter& nested_filter) { 2876 bool TraceConfig::HasIncludedPatterns() const {
2581 // Keep included patterns only if both filters have an included entry. 2877 return !included_categories_.empty();
2582 // Otherwise, one of the filter was specifying "*" and we want to honour the
2583 // broadest filter.
2584 if (HasIncludedPatterns() && nested_filter.HasIncludedPatterns()) {
2585 included_.insert(included_.end(),
2586 nested_filter.included_.begin(),
2587 nested_filter.included_.end());
2588 } else {
2589 included_.clear();
2590 }
2591
2592 disabled_.insert(disabled_.end(),
2593 nested_filter.disabled_.begin(),
2594 nested_filter.disabled_.end());
2595 excluded_.insert(excluded_.end(),
2596 nested_filter.excluded_.begin(),
2597 nested_filter.excluded_.end());
2598 delays_.insert(delays_.end(),
2599 nested_filter.delays_.begin(),
2600 nested_filter.delays_.end());
2601 }
2602
2603 void CategoryFilter::Clear() {
2604 included_.clear();
2605 disabled_.clear();
2606 excluded_.clear();
2607 }
2608
2609 const CategoryFilter::StringList&
2610 CategoryFilter::GetSyntheticDelayValues() const {
2611 return delays_;
2612 } 2878 }
2613 2879
2614 } // namespace trace_event 2880 } // namespace trace_event
2615 } // namespace base 2881 } // namespace base
2616 2882
2617 namespace trace_event_internal { 2883 namespace trace_event_internal {
2618 2884
2619 ScopedTraceBinaryEfficient::ScopedTraceBinaryEfficient( 2885 ScopedTraceBinaryEfficient::ScopedTraceBinaryEfficient(
2620 const char* category_group, const char* name) { 2886 const char* category_group, const char* name) {
2621 // The single atom works because for now the category_group can only be "gpu". 2887 // The single atom works because for now the category_group can only be "gpu".
(...skipping 14 matching lines...) Expand all
2636 } 2902 }
2637 2903
2638 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { 2904 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() {
2639 if (*category_group_enabled_) { 2905 if (*category_group_enabled_) {
2640 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, 2906 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_,
2641 name_, event_handle_); 2907 name_, event_handle_);
2642 } 2908 }
2643 } 2909 }
2644 2910
2645 } // namespace trace_event_internal 2911 } // namespace trace_event_internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698