| Index: base/trace_event/trace_config.cc
|
| diff --git a/base/trace_event/trace_config.cc b/base/trace_event/trace_config.cc
|
| index b343ea00bc5b033163319d915a3ef3e8e31787ae..988f73a0343e4b35b6048521bb6ead3702a0a3b6 100644
|
| --- a/base/trace_event/trace_config.cc
|
| +++ b/base/trace_event/trace_config.cc
|
| @@ -55,6 +55,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
|
| @@ -68,6 +73,7 @@ class ConvertableTraceConfigToTraceFormat
|
| public:
|
| explicit ConvertableTraceConfigToTraceFormat(const TraceConfig& trace_config)
|
| : trace_config_(trace_config) {}
|
| +
|
| ~ConvertableTraceConfigToTraceFormat() override {}
|
|
|
| void AppendAsTraceFormat(std::string* out) const override {
|
| @@ -115,6 +121,69 @@ 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) {
|
| + *this = tc;
|
| +}
|
| +
|
| +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, excluded_category)) {
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + for (const auto& included_category : included_categories_) {
|
| + if (base::MatchPattern(category_group_token, included_category)) {
|
| + return true;
|
| + }
|
| + }
|
| + }
|
| +
|
| + return false;
|
| +}
|
| +
|
| TraceConfig::TraceConfig() {
|
| InitializeDefault();
|
| }
|
| @@ -166,7 +235,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() {
|
| }
|
| @@ -184,6 +254,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;
|
| }
|
|
|
| @@ -314,6 +385,7 @@ void TraceConfig::Clear() {
|
| excluded_categories_.clear();
|
| synthetic_delays_.clear();
|
| memory_dump_config_.Clear();
|
| + event_filters_.clear();
|
| }
|
|
|
| void TraceConfig::InitializeDefault() {
|
| @@ -361,6 +433,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(StringPiece config_string) {
|
| @@ -555,6 +631,50 @@ void TraceConfig::SetDefaultMemoryDumpConfig() {
|
| memory_dump_config_.allowed_dump_modes = GetDefaultAllowedMemoryDumpModes();
|
| }
|
|
|
| +void TraceConfig::SetEventFilters(
|
| + const base::ListValue& category_event_filters) {
|
| + event_filters_.clear();
|
| +
|
| + for (size_t event_filter_index = 0;
|
| + event_filter_index < category_event_filters.GetSize();
|
| + ++event_filter_index) {
|
| + const base::DictionaryValue* event_filter = nullptr;
|
| + if (!category_event_filters.GetDictionary(event_filter_index,
|
| + &event_filter))
|
| + continue;
|
| +
|
| + std::string predicate_name;
|
| + CHECK(event_filter->GetString(kFilterPredicateParam, &predicate_name))
|
| + << "Invalid predicate name in category event filter.";
|
| +
|
| + EventFilterConfig new_config(predicate_name);
|
| + const base::ListValue* included_list = nullptr;
|
| + CHECK(event_filter->GetList(kIncludedCategoriesParam, &included_list))
|
| + << "Missing included_categories in category event filter.";
|
| +
|
| + 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);
|
| + }
|
| +}
|
| +
|
| std::unique_ptr<DictionaryValue> TraceConfig::ToDict() const {
|
| auto dict = MakeUnique<DictionaryValue>();
|
| switch (record_mode_) {
|
| @@ -586,6 +706,41 @@ std::unique_ptr<DictionaryValue> TraceConfig::ToDict() const {
|
| AddCategoryToDict(dict.get(), kExcludedCategoriesParam, excluded_categories_);
|
| AddCategoryToDict(dict.get(), 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)) {
|
| auto allowed_modes = MakeUnique<ListValue>();
|
| for (auto dump_mode : memory_dump_config_.allowed_dump_modes)
|
|
|