| Index: base/trace_event/trace_config.cc
|
| diff --git a/base/trace_event/trace_config.cc b/base/trace_event/trace_config.cc
|
| index 25a0cd6d40b5d7aee19c68a9eb06a54f2c665bd5..e4beab919ecce548214aa62b29f49d1b03a34ac5 100644
|
| --- a/base/trace_event/trace_config.cc
|
| +++ b/base/trace_event/trace_config.cc
|
| @@ -53,6 +53,11 @@ const char kModeParam[] = "mode";
|
| const char kHeapProfilerOptions[] = "heap_profiler_options";
|
| const char kBreakdownThresholdBytes[] = "breakdown_threshold_bytes";
|
|
|
| +// String parameters used to parse category event filters.
|
| +const char kEventFiltersParam[] = "event_filters";
|
| +const char kFilterPredicateParam[] = "filter_predicate";
|
| +const char kFilterArgsParam[] = "filter_args";
|
| +
|
| // Default configuration of memory dumps.
|
| const TraceConfig::MemoryDumpConfig::Trigger kDefaultHeavyMemoryDumpTrigger = {
|
| 2000, // periodic_interval_ms
|
| @@ -97,6 +102,74 @@ void TraceConfig::MemoryDumpConfig::Clear() {
|
| heap_profiler_options.Clear();
|
| }
|
|
|
| +TraceConfig::EventFilterConfig::EventFilterConfig(
|
| + const std::string& predicate_name)
|
| + : predicate_name_(predicate_name) {}
|
| +TraceConfig::EventFilterConfig::~EventFilterConfig() {}
|
| +
|
| +TraceConfig::EventFilterConfig::EventFilterConfig(const EventFilterConfig& tc)
|
| + : predicate_name_(tc.predicate_name_),
|
| + included_categories_(tc.included_categories_),
|
| + excluded_categories_(tc.excluded_categories_) {
|
| + if (tc.args_)
|
| + args_ = tc.args_->CreateDeepCopy();
|
| +}
|
| +
|
| +TraceConfig::EventFilterConfig& TraceConfig::EventFilterConfig::operator=(
|
| + const TraceConfig::EventFilterConfig& rhs) {
|
| + if (this == &rhs)
|
| + return *this;
|
| +
|
| + predicate_name_ = rhs.predicate_name_;
|
| + included_categories_ = rhs.included_categories_;
|
| + excluded_categories_ = rhs.excluded_categories_;
|
| + if (rhs.args_)
|
| + args_ = rhs.args_->CreateDeepCopy();
|
| +
|
| + return *this;
|
| +}
|
| +
|
| +void TraceConfig::EventFilterConfig::AddIncludedCategory(
|
| + const std::string& category) {
|
| + included_categories_.push_back(category);
|
| +}
|
| +
|
| +void TraceConfig::EventFilterConfig::AddExcludedCategory(
|
| + const std::string& category) {
|
| + excluded_categories_.push_back(category);
|
| +}
|
| +
|
| +void TraceConfig::EventFilterConfig::SetArgs(
|
| + std::unique_ptr<base::DictionaryValue> args) {
|
| + args_ = std::move(args);
|
| +}
|
| +
|
| +bool TraceConfig::EventFilterConfig::IsCategoryGroupEnabled(
|
| + const char* category_group_name) const {
|
| + CStringTokenizer category_group_tokens(
|
| + category_group_name, category_group_name + strlen(category_group_name),
|
| + ",");
|
| + while (category_group_tokens.GetNext()) {
|
| + std::string category_group_token = category_group_tokens.token();
|
| +
|
| + for (const auto& excluded_category : excluded_categories_) {
|
| + if (base::MatchPattern(category_group_token.c_str(),
|
| + excluded_category.c_str())) {
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + for (const auto& included_category : included_categories_) {
|
| + if (base::MatchPattern(category_group_token.c_str(),
|
| + included_category.c_str())) {
|
| + return true;
|
| + }
|
| + }
|
| + }
|
| +
|
| + return false;
|
| +}
|
| +
|
| TraceConfig::TraceConfig() {
|
| InitializeDefault();
|
| }
|
| @@ -148,7 +221,8 @@ TraceConfig::TraceConfig(const TraceConfig& tc)
|
| included_categories_(tc.included_categories_),
|
| disabled_categories_(tc.disabled_categories_),
|
| excluded_categories_(tc.excluded_categories_),
|
| - synthetic_delays_(tc.synthetic_delays_) {}
|
| + synthetic_delays_(tc.synthetic_delays_),
|
| + event_filters_(tc.event_filters_) {}
|
|
|
| TraceConfig::~TraceConfig() {
|
| }
|
| @@ -166,6 +240,7 @@ TraceConfig& TraceConfig::operator=(const TraceConfig& rhs) {
|
| disabled_categories_ = rhs.disabled_categories_;
|
| excluded_categories_ = rhs.excluded_categories_;
|
| synthetic_delays_ = rhs.synthetic_delays_;
|
| + event_filters_ = rhs.event_filters_;
|
| return *this;
|
| }
|
|
|
| @@ -304,6 +379,7 @@ void TraceConfig::Clear() {
|
| excluded_categories_.clear();
|
| synthetic_delays_.clear();
|
| memory_dump_config_.Clear();
|
| + event_filters_.clear();
|
| }
|
|
|
| void TraceConfig::InitializeDefault() {
|
| @@ -365,6 +441,10 @@ void TraceConfig::InitializeFromConfigDict(const DictionaryValue& dict) {
|
| else
|
| SetDefaultMemoryDumpConfig();
|
| }
|
| +
|
| + const base::ListValue* category_event_filters = nullptr;
|
| + if (dict.GetList(kEventFiltersParam, &category_event_filters))
|
| + SetEventFilters(*category_event_filters);
|
| }
|
|
|
| void TraceConfig::InitializeFromConfigString(const std::string& config_string) {
|
| @@ -561,6 +641,51 @@ void TraceConfig::SetDefaultMemoryDumpConfig() {
|
| memory_dump_config_.triggers.push_back(kDefaultLightMemoryDumpTrigger);
|
| }
|
|
|
| +void TraceConfig::SetEventFilters(
|
| + const base::ListValue& category_event_filters) {
|
| + event_filters_.clear();
|
| +
|
| + for (size_t i = 0; i < category_event_filters.GetSize(); ++i) {
|
| + const base::DictionaryValue* event_filter = nullptr;
|
| + if (!category_event_filters.GetDictionary(i, &event_filter))
|
| + continue;
|
| +
|
| + std::string predicate_name;
|
| + if (!event_filter->GetString(kFilterPredicateParam, &predicate_name)) {
|
| + LOG(ERROR) << "Invalid predicate name in category event filter.";
|
| + continue;
|
| + }
|
| +
|
| + EventFilterConfig new_config(predicate_name);
|
| + const base::ListValue* included_list = nullptr;
|
| + if (!event_filter->GetList(kIncludedCategoriesParam, &included_list)) {
|
| + LOG(ERROR) << "Missing included_categories in category event filter.";
|
| + continue;
|
| + }
|
| +
|
| + for (size_t i = 0; i < included_list->GetSize(); ++i) {
|
| + std::string category;
|
| + if (included_list->GetString(i, &category))
|
| + new_config.AddIncludedCategory(category);
|
| + }
|
| +
|
| + const base::ListValue* excluded_list = nullptr;
|
| + if (event_filter->GetList(kExcludedCategoriesParam, &excluded_list)) {
|
| + for (size_t i = 0; i < excluded_list->GetSize(); ++i) {
|
| + std::string category;
|
| + if (excluded_list->GetString(i, &category))
|
| + new_config.AddExcludedCategory(category);
|
| + }
|
| + }
|
| +
|
| + const base::DictionaryValue* args_dict = nullptr;
|
| + if (event_filter->GetDictionary(kFilterArgsParam, &args_dict))
|
| + new_config.SetArgs(args_dict->CreateDeepCopy());
|
| +
|
| + event_filters_.push_back(new_config);
|
| + }
|
| +}
|
| +
|
| void TraceConfig::ToDict(base::DictionaryValue& dict) const {
|
| switch (record_mode_) {
|
| case RECORD_UNTIL_FULL:
|
| @@ -602,6 +727,41 @@ void TraceConfig::ToDict(base::DictionaryValue& dict) const {
|
| AddCategoryToDict(dict, kExcludedCategoriesParam, excluded_categories_);
|
| AddCategoryToDict(dict, kSyntheticDelaysParam, synthetic_delays_);
|
|
|
| + if (!event_filters_.empty()) {
|
| + std::unique_ptr<base::ListValue> filter_list(new base::ListValue());
|
| + for (const EventFilterConfig& filter : event_filters_) {
|
| + std::unique_ptr<base::DictionaryValue> filter_dict(
|
| + new base::DictionaryValue());
|
| + filter_dict->SetString(kFilterPredicateParam, filter.predicate_name());
|
| +
|
| + std::unique_ptr<base::ListValue> included_categories_list(
|
| + new base::ListValue());
|
| + for (const std::string& included_category : filter.included_categories())
|
| + included_categories_list->AppendString(included_category);
|
| +
|
| + filter_dict->Set(kIncludedCategoriesParam,
|
| + std::move(included_categories_list));
|
| +
|
| + if (!filter.excluded_categories().empty()) {
|
| + std::unique_ptr<base::ListValue> excluded_categories_list(
|
| + new base::ListValue());
|
| + for (const std::string& excluded_category :
|
| + filter.excluded_categories())
|
| + excluded_categories_list->AppendString(excluded_category);
|
| +
|
| + filter_dict->Set(kExcludedCategoriesParam,
|
| + std::move(excluded_categories_list));
|
| + }
|
| +
|
| + if (filter.filter_args())
|
| + filter_dict->Set(kFilterArgsParam,
|
| + filter.filter_args()->CreateDeepCopy());
|
| +
|
| + filter_list->Append(std::move(filter_dict));
|
| + }
|
| + dict.Set(kEventFiltersParam, std::move(filter_list));
|
| + }
|
| +
|
| if (IsCategoryEnabled(MemoryDumpManager::kTraceCategory)) {
|
| std::unique_ptr<base::DictionaryValue> memory_dump_config(
|
| new base::DictionaryValue());
|
|
|