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

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: review fix 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 InitializeDefault();
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 std::vector<std::string> split;
2518 std::vector<std::string>::iterator iter;
2519 base::SplitString(category_filter_string, ',', &split);
2520 for (iter = split.begin(); iter != split.end(); ++iter) {
2521 std::string category = *iter;
2522 // Ignore empty categories.
2523 if (category.empty())
2524 continue;
2525 // Synthetic delays are of the form 'DELAY(delay;option;option;...)'.
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("")),
nednguyen 2015/05/13 18:16:32 nits: '' instead of ""?
Zhen Wang 2015/05/13 20:59:17 I think the macro requires a string to do string c
2542 TRACE_DISABLED_BY_DEFAULT("")) == 0) {
2543 disabled_categories_.push_back(category);
2544 } else {
2545 included_categories_.push_back(category);
2546 }
2547 }
2548 }
2549
2550 record_mode_ = RECORD_UNTIL_FULL;
2551 enable_sampling_ = false;
2552 enable_systrace_ = false;
2553 if(!trace_options_string.empty()) {
2554 std::vector<std::string> split;
2555 std::vector<std::string>::iterator iter;
2556 base::SplitString(trace_options_string, ',', &split);
2557 for (iter = split.begin(); iter != split.end(); ++iter) {
2558 if (*iter == kRecordUntilFull) {
2559 record_mode_ = RECORD_UNTIL_FULL;
2560 } else if (*iter == kRecordContinuously) {
2561 record_mode_ = RECORD_CONTINUOUSLY;
2562 } else if (*iter == kTraceToConsole) {
2563 record_mode_ = ECHO_TO_CONSOLE;
2564 } else if (*iter == kRecordAsMuchAsPossible) {
2565 record_mode_ = RECORD_AS_MUCH_AS_POSSIBLE;
2566 } else if (*iter == kEnableSampling) {
2567 enable_sampling_ = true;
2568 } else if (*iter == kEnableSystrace) {
2569 enable_systrace_ = true;
2570 }
2571 }
2572 }
2573 }
2574
2575 TraceConfig::TraceConfig(const std::string& config_string) {
2576 if (!config_string.empty())
2577 Initialize(config_string);
2578 else
2579 InitializeDefault();
2580 }
2581
2582 TraceConfig::TraceConfig(const TraceConfig& tc)
2583 : record_mode_(tc.record_mode_),
2584 enable_sampling_(tc.enable_sampling_),
2585 enable_systrace_(tc.enable_systrace_),
2586 included_categories_(tc.included_categories_),
2587 disabled_categories_(tc.disabled_categories_),
2588 excluded_categories_(tc.excluded_categories_),
2589 synthetic_delays_(tc.synthetic_delays_) {
2590 }
2591
2592 TraceConfig::~TraceConfig() {
2593 }
2594
2595 TraceConfig& TraceConfig::operator=(const TraceConfig& rhs) {
2596 if (this == &rhs)
2597 return *this;
2598
2599 record_mode_ = rhs.record_mode_;
2600 enable_sampling_ = rhs.enable_sampling_;
2601 enable_systrace_ = rhs.enable_systrace_;
2602 included_categories_ = rhs.included_categories_;
2603 disabled_categories_ = rhs.disabled_categories_;
2604 excluded_categories_ = rhs.excluded_categories_;
2605 synthetic_delays_ = rhs.synthetic_delays_;
2606 return *this;
2607 }
2608
2609 void TraceConfig::Initialize(const std::string& config_string) {
2610 scoped_ptr<base::Value> value(base::JSONReader::Read(config_string));
2611 if (!value || !value->IsType(base::Value::TYPE_DICTIONARY)) {
2612 InitializeDefault();
2613 return;
2614 }
2615 scoped_ptr<base::DictionaryValue> dict(
2616 static_cast<base::DictionaryValue*>(value.release()));
2617
2618 record_mode_ = RECORD_UNTIL_FULL;
2619 std::string record_mode;
2620 if (dict->GetString(kRecordModeParam, &record_mode)) {
2621 if (record_mode == kRecordUntilFull) {
2622 record_mode_ = RECORD_UNTIL_FULL;
2623 } else if (record_mode == kRecordContinuously) {
2624 record_mode_ = RECORD_CONTINUOUSLY;
2625 } else if (record_mode == kTraceToConsole) {
2626 record_mode_ = ECHO_TO_CONSOLE;
2627 } else if (record_mode == kRecordAsMuchAsPossible) {
2628 record_mode_ = RECORD_AS_MUCH_AS_POSSIBLE;
2629 }
2630 }
2631
2632 if (!dict->GetBoolean(kEnableSamplingParam, &enable_sampling_))
2633 enable_sampling_ = false;
2634 if (!dict->GetBoolean(kEnableSystraceParam, &enable_systrace_))
2635 enable_systrace_ = false;
2636
2637 base::ListValue* category_list = NULL;
2638 if (dict->GetList(kIncludedCategoriesParam, &category_list))
2639 SetCategoriesFromList(included_categories_, *category_list);
2640 if (dict->GetList(kDisabledCategoriesParam, &category_list))
2641 SetCategoriesFromList(disabled_categories_, *category_list);
2642 if (dict->GetList(kExcludedCategoriesParam, &category_list))
2643 SetCategoriesFromList(excluded_categories_, *category_list);
2644 if (dict->GetList(kSyntheticDelaysParam, &category_list))
2645 SetCategoriesFromList(synthetic_delays_, *category_list);
2646 }
2647
2648 void TraceConfig::InitializeDefault() {
2649 record_mode_ = RECORD_UNTIL_FULL;
2650 enable_sampling_ = false;
2651 enable_systrace_ = false;
2652 excluded_categories_.push_back("*Debug");
2653 excluded_categories_.push_back("*Test");
2654 }
2655
2656 const TraceConfig::StringList& TraceConfig::GetSyntheticDelayValues() const {
2657 return synthetic_delays_;
2658 }
2659
2660 void TraceConfig::ToDict(base::DictionaryValue& dict) const {
2661 switch (record_mode_) {
2662 case RECORD_UNTIL_FULL:
2663 dict.SetString(kRecordModeParam, kRecordUntilFull);
2664 break;
2665 case RECORD_CONTINUOUSLY:
2666 dict.SetString(kRecordModeParam, kRecordContinuously);
2667 break;
2668 case ECHO_TO_CONSOLE:
2669 dict.SetString(kRecordModeParam, kTraceToConsole);
2670 break;
2671 case RECORD_AS_MUCH_AS_POSSIBLE:
2672 dict.SetString(kRecordModeParam, kRecordAsMuchAsPossible);
2673 break;
2674 default:
2675 NOTREACHED();
2676 }
2677
2678 if (enable_sampling_)
2679 dict.SetBoolean(kEnableSamplingParam, true);
2680 else
2681 dict.SetBoolean(kEnableSamplingParam, false);
2682
2683 if (enable_systrace_)
2684 dict.SetBoolean(kEnableSystraceParam, true);
2685 else
2686 dict.SetBoolean(kEnableSystraceParam, false);
2687
2688 AddCategoryToDict(dict, kIncludedCategoriesParam, included_categories_);
2689 AddCategoryToDict(dict, kDisabledCategoriesParam, disabled_categories_);
2690 AddCategoryToDict(dict, kExcludedCategoriesParam, excluded_categories_);
2691 AddCategoryToDict(dict, kSyntheticDelaysParam, synthetic_delays_);
2692 }
2693
2694 std::string TraceConfig::ToString() const {
2695 base::DictionaryValue dict;
2696 ToDict(dict);
2697
2698 std::string json;
2699 base::JSONWriter::Write(&dict, &json);
2700
2701 return json;
2702 }
2703
2704 std::string TraceConfig::ToCategoryFilterString() const {
2705 CategoryFilter cf;
2706 cf.config_.reset(new TraceConfig(*this));
2707 return cf.ToString();
2708 }
2709
2710 std::string TraceConfig::ToTraceOptionsString() const {
2711 TraceOptions to;
2712 to.record_mode = record_mode_;
2713 to.enable_sampling = enable_sampling_;
2714 to.enable_systrace = enable_systrace_;
2715 return to.ToString();
2716 }
2717
2718 void TraceConfig::AddCategoryToDict(base::DictionaryValue& dict,
2719 const char* param,
2720 const StringList& categories) const {
2721 if (categories.empty())
2722 return;
2723
2724 scoped_ptr<base::ListValue> list(new base::ListValue());
2725 for (StringList::const_iterator ci = categories.begin();
2726 ci != categories.end();
2727 ++ci) {
2728 list->AppendString(*ci);
2729 }
2730
2731 dict.Set(param, list.Pass());
2732 }
2733
2734 void TraceConfig::Merge(const TraceConfig& config) {
2735 if (record_mode_ != config.record_mode_
2736 || enable_sampling_ != config.enable_sampling_
2737 || enable_systrace_ != config.enable_systrace_) {
2738 DLOG(ERROR) << "Attempting to merge trace config with a different "
2739 << "set of options.";
2740 }
2741
2742 // Keep included patterns only if both filters have an included entry.
2743 // Otherwise, one of the filter was specifying "*" and we want to honor the
2744 // broadest filter.
2745 if (HasIncludedPatterns() && config.HasIncludedPatterns()) {
2746 included_categories_.insert(included_categories_.end(),
2747 config.included_categories_.begin(),
2748 config.included_categories_.end());
2749 } else {
2750 included_categories_.clear();
2751 }
2752
2753 disabled_categories_.insert(disabled_categories_.end(),
2754 config.disabled_categories_.begin(),
2755 config.disabled_categories_.end());
2756 excluded_categories_.insert(excluded_categories_.end(),
2757 config.excluded_categories_.begin(),
2758 config.excluded_categories_.end());
2759 synthetic_delays_.insert(synthetic_delays_.end(),
2760 config.synthetic_delays_.begin(),
2761 config.synthetic_delays_.end());
2762 }
2763
2764 void TraceConfig::Clear() {
2765 record_mode_ = RECORD_UNTIL_FULL;
2766 enable_sampling_ = false;
2767 enable_systrace_ = false;
2768 included_categories_.clear();
2769 disabled_categories_.clear();
2770 excluded_categories_.clear();
2771 synthetic_delays_.clear();
2772 }
2773
2774 void TraceConfig::SetCategoriesFromList(StringList& categories,
2775 const base::ListValue& list) {
2776 categories.clear();
2777 for (size_t i = 0; i < list.GetSize(); ++i) {
2778 std::string category;
2779 if (list.GetString(i, &category))
2780 categories.push_back(category);
2781 }
2782 }
2783
2784 bool TraceConfig::IsCategoryGroupEnabled(
2785 const char* category_group_name) const {
2500 // TraceLog should call this method only as part of enabling/disabling 2786 // TraceLog should call this method only as part of enabling/disabling
2501 // categories. 2787 // categories.
2502 2788
2503 bool had_enabled_by_default = false; 2789 bool had_enabled_by_default = false;
2504 DCHECK(category_group_name); 2790 DCHECK(category_group_name);
2505 CStringTokenizer category_group_tokens( 2791 CStringTokenizer category_group_tokens(
2506 category_group_name, category_group_name + strlen(category_group_name), 2792 category_group_name, category_group_name + strlen(category_group_name),
2507 ","); 2793 ",");
2508 while (category_group_tokens.GetNext()) { 2794 while (category_group_tokens.GetNext()) {
2509 std::string category_group_token = category_group_tokens.token(); 2795 std::string category_group_token = category_group_tokens.token();
2510 // Don't allow empty tokens, nor tokens with leading or trailing space. 2796 // Don't allow empty tokens, nor tokens with leading or trailing space.
2511 DCHECK(!CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace( 2797 DCHECK(!TraceConfig::IsEmptyOrContainsLeadingOrTrailingWhitespace(
2512 category_group_token)) 2798 category_group_token))
2513 << "Disallowed category string"; 2799 << "Disallowed category string";
2514 if (IsCategoryEnabled(category_group_token.c_str())) { 2800 if (IsCategoryEnabled(category_group_token.c_str())) {
2515 return true; 2801 return true;
2516 } 2802 }
2517 if (!MatchPattern(category_group_token.c_str(), 2803 if (!MatchPattern(category_group_token.c_str(),
2518 TRACE_DISABLED_BY_DEFAULT("*"))) 2804 TRACE_DISABLED_BY_DEFAULT("*")))
2519 had_enabled_by_default = true; 2805 had_enabled_by_default = true;
2520 } 2806 }
2521 // Do a second pass to check for explicitly disabled categories 2807 // Do a second pass to check for explicitly disabled categories
2522 // (those explicitly enabled have priority due to first pass). 2808 // (those explicitly enabled have priority due to first pass).
2523 category_group_tokens.Reset(); 2809 category_group_tokens.Reset();
2524 bool category_group_disabled = false; 2810 bool category_group_disabled = false;
2525 while (category_group_tokens.GetNext()) { 2811 while (category_group_tokens.GetNext()) {
2526 std::string category_group_token = category_group_tokens.token(); 2812 std::string category_group_token = category_group_tokens.token();
2527 for (StringList::const_iterator ci = excluded_.begin(); 2813 for (StringList::const_iterator ci = excluded_categories_.begin();
2528 ci != excluded_.end(); ++ci) { 2814 ci != excluded_categories_.end();
2815 ++ci) {
2529 if (MatchPattern(category_group_token.c_str(), ci->c_str())) { 2816 if (MatchPattern(category_group_token.c_str(), ci->c_str())) {
2530 // Current token of category_group_name is present in excluded_list. 2817 // Current token of category_group_name is present in excluded_list.
2531 // Flag the exclusion and proceed further to check if any of the 2818 // Flag the exclusion and proceed further to check if any of the
2532 // remaining categories of category_group_name is not present in the 2819 // remaining categories of category_group_name is not present in the
2533 // excluded_ list. 2820 // excluded_ list.
2534 category_group_disabled = true; 2821 category_group_disabled = true;
2535 break; 2822 break;
2536 } 2823 }
2537 // One of the category of category_group_name is not present in 2824 // One of the category of category_group_name is not present in
2538 // excluded_ list. So, it has to be included_ list. Enable the 2825 // excluded_ list. So, it has to be included_ list. Enable the
2539 // category_group_name for recording. 2826 // category_group_name for recording.
2540 category_group_disabled = false; 2827 category_group_disabled = false;
2541 } 2828 }
2542 // One of the categories present in category_group_name is not present in 2829 // 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 2830 // excluded_ list. Implies this category_group_name group can be enabled
2544 // for recording, since one of its groups is enabled for recording. 2831 // for recording, since one of its groups is enabled for recording.
2545 if (!category_group_disabled) 2832 if (!category_group_disabled)
2546 break; 2833 break;
2547 } 2834 }
2548 // If the category group is not excluded, and there are no included patterns 2835 // 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 2836 // we consider this category group enabled, as long as it had categories
2550 // other than disabled-by-default. 2837 // other than disabled-by-default.
2551 return !category_group_disabled && 2838 return !category_group_disabled &&
2552 included_.empty() && had_enabled_by_default; 2839 included_categories_.empty() && had_enabled_by_default;
2553 } 2840 }
2554 2841
2555 bool CategoryFilter::IsCategoryEnabled(const char* category_name) const { 2842 bool TraceConfig::IsCategoryEnabled(const char* category_name) const {
2556 StringList::const_iterator ci; 2843 StringList::const_iterator ci;
2557 2844
2558 // Check the disabled- filters and the disabled-* wildcard first so that a 2845 // Check the disabled- filters and the disabled-* wildcard first so that a
2559 // "*" filter does not include the disabled. 2846 // "*" filter does not include the disabled.
2560 for (ci = disabled_.begin(); ci != disabled_.end(); ++ci) { 2847 for (ci = disabled_categories_.begin();
2848 ci != disabled_categories_.end();
2849 ++ci) {
2561 if (MatchPattern(category_name, ci->c_str())) 2850 if (MatchPattern(category_name, ci->c_str()))
2562 return true; 2851 return true;
2563 } 2852 }
2564 2853
2565 if (MatchPattern(category_name, TRACE_DISABLED_BY_DEFAULT("*"))) 2854 if (MatchPattern(category_name, TRACE_DISABLED_BY_DEFAULT("*")))
2566 return false; 2855 return false;
2567 2856
2568 for (ci = included_.begin(); ci != included_.end(); ++ci) { 2857 for (ci = included_categories_.begin();
2858 ci != included_categories_.end();
2859 ++ci) {
2569 if (MatchPattern(category_name, ci->c_str())) 2860 if (MatchPattern(category_name, ci->c_str()))
2570 return true; 2861 return true;
2571 } 2862 }
2572 2863
2573 return false; 2864 return false;
2574 } 2865 }
2575 2866
2576 bool CategoryFilter::HasIncludedPatterns() const { 2867 bool TraceConfig::IsEmptyOrContainsLeadingOrTrailingWhitespace(
2577 return !included_.empty(); 2868 const std::string& str) {
2869 return str.empty() ||
2870 str.at(0) == ' ' ||
2871 str.at(str.length() - 1) == ' ';
2578 } 2872 }
2579 2873
2580 void CategoryFilter::Merge(const CategoryFilter& nested_filter) { 2874 bool TraceConfig::HasIncludedPatterns() const {
2581 // Keep included patterns only if both filters have an included entry. 2875 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 } 2876 }
2613 2877
2614 } // namespace trace_event 2878 } // namespace trace_event
2615 } // namespace base 2879 } // namespace base
2616 2880
2617 namespace trace_event_internal { 2881 namespace trace_event_internal {
2618 2882
2619 ScopedTraceBinaryEfficient::ScopedTraceBinaryEfficient( 2883 ScopedTraceBinaryEfficient::ScopedTraceBinaryEfficient(
2620 const char* category_group, const char* name) { 2884 const char* category_group, const char* name) {
2621 // The single atom works because for now the category_group can only be "gpu". 2885 // The single atom works because for now the category_group can only be "gpu".
(...skipping 14 matching lines...) Expand all
2636 } 2900 }
2637 2901
2638 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { 2902 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() {
2639 if (*category_group_enabled_) { 2903 if (*category_group_enabled_) {
2640 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, 2904 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_,
2641 name_, event_handle_); 2905 name_, event_handle_);
2642 } 2906 }
2643 } 2907 }
2644 2908
2645 } // namespace trace_event_internal 2909 } // namespace trace_event_internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698