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

Unified Diff: base/trace_event/trace_log.cc

Issue 1923533004: Tracing pre-filtering (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 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 side-by-side diff with in-line comments
Download patch
« base/trace_event/trace_config_unittest.cc ('K') | « base/trace_event/trace_log.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/trace_event/trace_log.cc
diff --git a/base/trace_event/trace_log.cc b/base/trace_event/trace_log.cc
index 1a375d146a9eb20582e7948677029c93c6a1842f..25990eddceb49bc740bd8ac41af2f613924df5d1 100644
--- a/base/trace_event/trace_log.cc
+++ b/base/trace_event/trace_log.cc
@@ -16,6 +16,7 @@
#include "base/lazy_instance.h"
#include "base/location.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted_memory.h"
#include "base/memory/singleton.h"
#include "base/process/process_metrics.h"
@@ -102,6 +103,42 @@ const char* g_category_groups[MAX_CATEGORY_GROUPS] = {
// The enabled flag is char instead of bool so that the API can be used from C.
unsigned char g_category_group_enabled[MAX_CATEGORY_GROUPS] = {0};
+
+class TraceEventFilter {
+ public:
+ TraceEventFilter() {}
Primiano Tucci (use gerrit) 2016/05/11 16:11:57 I think you need a virtual dtor here (and override
oystein (OOO til 10th of July) 2016/05/20 20:03:44 Done.
+ virtual bool FilterTraceEvent(const TraceEvent& trace_event) const = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TraceEventFilter);
+};
+
+class EventNameFilter : public TraceEventFilter {
+ public:
+ EventNameFilter(const base::DictionaryValue* filter_args) {
+ const base::ListValue* whitelist = nullptr;
+ if (filter_args->GetList("event_name_whitelist", &whitelist)) {
+ for (size_t i = 0; i < whitelist->GetSize(); ++i) {
+ std::string event_name;
+ if (!whitelist->GetString(i, &event_name))
+ continue;
+
+ whitelist_[event_name] = true;
+ }
+ }
+ }
+
+ bool FilterTraceEvent(const TraceEvent& trace_event) const override {
+ return (whitelist_.find(trace_event.name()) != whitelist_.end());
Primiano Tucci (use gerrit) 2016/05/11 16:11:57 either .count(...) != 0 or ContainsKey from base/s
oystein (OOO til 10th of July) 2016/05/20 20:03:44 Done.
+ }
+
+ private:
+ std::unordered_map<std::string, bool> whitelist_;
Primiano Tucci (use gerrit) 2016/05/11 16:11:57 Not sure what the bool is for, you seem to always
oystein (OOO til 10th of July) 2016/05/20 20:03:44 Done.
+};
+
+base::LazyInstance<std::list<std::unique_ptr<TraceEventFilter>>>::Leaky
+ g_category_group_filter[MAX_CATEGORY_GROUPS] = {LAZY_INSTANCE_INITIALIZER};
+
// Indexes here have to match the g_category_groups array indexes above.
const int g_category_already_shutdown = 1;
const int g_category_categories_exhausted = 2;
@@ -434,8 +471,8 @@ const unsigned char* TraceLog::GetCategoryGroupEnabled(
return tracelog->GetCategoryGroupEnabledInternal(category_group);
}
-const char* TraceLog::GetCategoryGroupName(
- const unsigned char* category_group_enabled) {
+namespace {
+uintptr_t GetCategoryIndex(const unsigned char* category_group_enabled) {
Primiano Tucci (use gerrit) 2016/05/11 16:11:57 should this be moved to the anonymous namespace ab
oystein (OOO til 10th of July) 2016/05/20 20:03:44 Ah, done; added it in the middle for expensive whi
// Calculate the index of the category group by finding
// category_group_enabled in g_category_group_enabled array.
uintptr_t category_begin =
@@ -447,7 +484,20 @@ const char* TraceLog::GetCategoryGroupName(
<< "out of bounds category pointer";
uintptr_t category_index =
(category_ptr - category_begin) / sizeof(g_category_group_enabled[0]);
- return g_category_groups[category_index];
+
+ return category_index;
+}
+}
+
+const char* TraceLog::GetCategoryGroupName(
+ const unsigned char* category_group_enabled) {
+ return g_category_groups[GetCategoryIndex(category_group_enabled)];
+}
+
+std::list<std::unique_ptr<TraceEventFilter>>* GetCategoryGroupFilter(
+ const unsigned char* category_group_enabled) {
+ return g_category_group_filter[GetCategoryIndex(category_group_enabled)]
+ .Pointer();
}
void TraceLog::UpdateCategoryGroupEnabledFlag(size_t category_index) {
@@ -470,6 +520,28 @@ void TraceLog::UpdateCategoryGroupEnabledFlag(size_t category_index) {
}
#endif
+ if (!(g_category_group_filter[category_index] == nullptr))
Primiano Tucci (use gerrit) 2016/05/11 16:11:57 Isn't a bit more readable if here you cache once t
oystein (OOO til 10th of July) 2016/05/20 20:03:44 My idea was to avoid the Get() (and hence the Lazy
+ g_category_group_filter[category_index].Get().clear();
+
+ for (const auto& category_event_filter :
+ trace_config_.category_event_filters()) {
+ if (category_event_filter.IsCategoryGroupEnabled(category_group)) {
+ std::unique_ptr<TraceEventFilter> new_filter;
+
+ if (category_event_filter.predicate_name() ==
+ "event_whitelist_predicate") {
+ new_filter =
+ WrapUnique(new EventNameFilter(category_event_filter.args()));
+ }
+
+ if (new_filter) {
+ g_category_group_filter[category_index].Get().push_back(
+ std::move(new_filter));
+ enabled_flag |= ENABLED_FOR_FILTERING;
+ }
+ }
+ }
+
g_category_group_enabled[category_index] = enabled_flag;
}
@@ -1247,7 +1319,39 @@ TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp(
#endif // OS_WIN
std::string console_message;
- if (*category_group_enabled & ENABLED_FOR_RECORDING) {
+ if (*category_group_enabled & ENABLED_FOR_FILTERING) {
+ std::unique_ptr<TraceEvent> new_trace_event(new TraceEvent);
oystein (OOO til 10th of July) 2016/05/04 23:20:44 TODO: Figure out a way to keep this on the stack i
+ new_trace_event->Initialize(thread_id, offset_event_timestamp, thread_now,
+ phase, category_group_enabled, name, scope, id,
+ bind_id, num_args, arg_names, arg_types,
+ arg_values, convertable_values, flags);
+
+ std::list<std::unique_ptr<TraceEventFilter>>* filter_list =
Primiano Tucci (use gerrit) 2016/05/11 16:11:58 maybe that's a good case for auto? :)
oystein (OOO til 10th of July) 2016/05/20 20:03:44 Done.
+ GetCategoryGroupFilter(category_group_enabled);
+ DCHECK(filter_list);
Primiano Tucci (use gerrit) 2016/05/11 16:11:57 I think the policy in chrome is to not DCHECK for
oystein (OOO til 10th of July) 2016/05/20 20:03:44 Done.
+ DCHECK(!filter_list->empty());
+
+ bool should_add_event = false;
+ for (const auto& trace_event_filter : *filter_list) {
+ DCHECK(trace_event_filter);
Primiano Tucci (use gerrit) 2016/05/11 16:11:57 ditto here, remove this dcheck
oystein (OOO til 10th of July) 2016/05/20 20:03:44 Done.
+ if (trace_event_filter.get()->FilterTraceEvent(*new_trace_event))
+ should_add_event = true;
+ }
+
+ if (should_add_event) {
+ OptionalAutoLock lock(&lock_);
+
+ TraceEvent* trace_event = NULL;
+ if (thread_local_event_buffer) {
+ trace_event = thread_local_event_buffer->AddTraceEvent(&handle);
+ } else {
+ lock.EnsureAcquired();
Primiano Tucci (use gerrit) 2016/05/11 16:11:57 Instead of copy-pasting this logic here, which is
oystein (OOO til 10th of July) 2016/05/20 20:03:44 Done; it's a little awkward to handle all the case
+ trace_event = AddEventToThreadSharedChunkWhileLocked(&handle, true);
+ }
+
+ trace_event->MoveFrom(std::move(new_trace_event));
+ }
+ } else if (*category_group_enabled & ENABLED_FOR_RECORDING) {
OptionalAutoLock lock(&lock_);
TraceEvent* trace_event = NULL;
« base/trace_event/trace_config_unittest.cc ('K') | « base/trace_event/trace_log.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698