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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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_log.h" 5 #include "base/trace_event/trace_log.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <memory> 9 #include <memory>
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/base_switches.h" 12 #include "base/base_switches.h"
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/command_line.h" 14 #include "base/command_line.h"
15 #include "base/debug/leak_annotations.h" 15 #include "base/debug/leak_annotations.h"
16 #include "base/lazy_instance.h" 16 #include "base/lazy_instance.h"
17 #include "base/location.h" 17 #include "base/location.h"
18 #include "base/macros.h" 18 #include "base/macros.h"
19 #include "base/memory/ptr_util.h"
19 #include "base/memory/ref_counted_memory.h" 20 #include "base/memory/ref_counted_memory.h"
20 #include "base/memory/singleton.h" 21 #include "base/memory/singleton.h"
21 #include "base/process/process_metrics.h" 22 #include "base/process/process_metrics.h"
22 #include "base/stl_util.h" 23 #include "base/stl_util.h"
23 #include "base/strings/string_split.h" 24 #include "base/strings/string_split.h"
24 #include "base/strings/string_tokenizer.h" 25 #include "base/strings/string_tokenizer.h"
25 #include "base/strings/stringprintf.h" 26 #include "base/strings/stringprintf.h"
26 #include "base/sys_info.h" 27 #include "base/sys_info.h"
27 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" 28 #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
28 #include "base/thread_task_runner_handle.h" 29 #include "base/thread_task_runner_handle.h"
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 // convert internally to determine the category name from the char enabled 96 // convert internally to determine the category name from the char enabled
96 // pointer. 97 // pointer.
97 const char* g_category_groups[MAX_CATEGORY_GROUPS] = { 98 const char* g_category_groups[MAX_CATEGORY_GROUPS] = {
98 "toplevel", 99 "toplevel",
99 "tracing already shutdown", 100 "tracing already shutdown",
100 "tracing categories exhausted; must increase MAX_CATEGORY_GROUPS", 101 "tracing categories exhausted; must increase MAX_CATEGORY_GROUPS",
101 "__metadata"}; 102 "__metadata"};
102 103
103 // The enabled flag is char instead of bool so that the API can be used from C. 104 // The enabled flag is char instead of bool so that the API can be used from C.
104 unsigned char g_category_group_enabled[MAX_CATEGORY_GROUPS] = {0}; 105 unsigned char g_category_group_enabled[MAX_CATEGORY_GROUPS] = {0};
106
107 class TraceEventFilter {
108 public:
109 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.
110 virtual bool FilterTraceEvent(const TraceEvent& trace_event) const = 0;
111
112 private:
113 DISALLOW_COPY_AND_ASSIGN(TraceEventFilter);
114 };
115
116 class EventNameFilter : public TraceEventFilter {
117 public:
118 EventNameFilter(const base::DictionaryValue* filter_args) {
119 const base::ListValue* whitelist = nullptr;
120 if (filter_args->GetList("event_name_whitelist", &whitelist)) {
121 for (size_t i = 0; i < whitelist->GetSize(); ++i) {
122 std::string event_name;
123 if (!whitelist->GetString(i, &event_name))
124 continue;
125
126 whitelist_[event_name] = true;
127 }
128 }
129 }
130
131 bool FilterTraceEvent(const TraceEvent& trace_event) const override {
132 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.
133 }
134
135 private:
136 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.
137 };
138
139 base::LazyInstance<std::list<std::unique_ptr<TraceEventFilter>>>::Leaky
140 g_category_group_filter[MAX_CATEGORY_GROUPS] = {LAZY_INSTANCE_INITIALIZER};
141
105 // Indexes here have to match the g_category_groups array indexes above. 142 // Indexes here have to match the g_category_groups array indexes above.
106 const int g_category_already_shutdown = 1; 143 const int g_category_already_shutdown = 1;
107 const int g_category_categories_exhausted = 2; 144 const int g_category_categories_exhausted = 2;
108 const int g_category_metadata = 3; 145 const int g_category_metadata = 3;
109 const int g_num_builtin_categories = 4; 146 const int g_num_builtin_categories = 4;
110 // Skip default categories. 147 // Skip default categories.
111 base::subtle::AtomicWord g_category_index = g_num_builtin_categories; 148 base::subtle::AtomicWord g_category_index = g_num_builtin_categories;
112 149
113 // The name of the current thread. This is used to decide if the current 150 // The name of the current thread. This is used to decide if the current
114 // thread name has changed. We combine all the seen thread names into the 151 // thread name has changed. We combine all the seen thread names into the
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 const unsigned char* TraceLog::GetCategoryGroupEnabled( 464 const unsigned char* TraceLog::GetCategoryGroupEnabled(
428 const char* category_group) { 465 const char* category_group) {
429 TraceLog* tracelog = GetInstance(); 466 TraceLog* tracelog = GetInstance();
430 if (!tracelog) { 467 if (!tracelog) {
431 DCHECK(!g_category_group_enabled[g_category_already_shutdown]); 468 DCHECK(!g_category_group_enabled[g_category_already_shutdown]);
432 return &g_category_group_enabled[g_category_already_shutdown]; 469 return &g_category_group_enabled[g_category_already_shutdown];
433 } 470 }
434 return tracelog->GetCategoryGroupEnabledInternal(category_group); 471 return tracelog->GetCategoryGroupEnabledInternal(category_group);
435 } 472 }
436 473
437 const char* TraceLog::GetCategoryGroupName( 474 namespace {
438 const unsigned char* category_group_enabled) { 475 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
439 // Calculate the index of the category group by finding 476 // Calculate the index of the category group by finding
440 // category_group_enabled in g_category_group_enabled array. 477 // category_group_enabled in g_category_group_enabled array.
441 uintptr_t category_begin = 478 uintptr_t category_begin =
442 reinterpret_cast<uintptr_t>(g_category_group_enabled); 479 reinterpret_cast<uintptr_t>(g_category_group_enabled);
443 uintptr_t category_ptr = reinterpret_cast<uintptr_t>(category_group_enabled); 480 uintptr_t category_ptr = reinterpret_cast<uintptr_t>(category_group_enabled);
444 DCHECK(category_ptr >= category_begin && 481 DCHECK(category_ptr >= category_begin &&
445 category_ptr < reinterpret_cast<uintptr_t>(g_category_group_enabled + 482 category_ptr < reinterpret_cast<uintptr_t>(g_category_group_enabled +
446 MAX_CATEGORY_GROUPS)) 483 MAX_CATEGORY_GROUPS))
447 << "out of bounds category pointer"; 484 << "out of bounds category pointer";
448 uintptr_t category_index = 485 uintptr_t category_index =
449 (category_ptr - category_begin) / sizeof(g_category_group_enabled[0]); 486 (category_ptr - category_begin) / sizeof(g_category_group_enabled[0]);
450 return g_category_groups[category_index]; 487
488 return category_index;
489 }
490 }
491
492 const char* TraceLog::GetCategoryGroupName(
493 const unsigned char* category_group_enabled) {
494 return g_category_groups[GetCategoryIndex(category_group_enabled)];
495 }
496
497 std::list<std::unique_ptr<TraceEventFilter>>* GetCategoryGroupFilter(
498 const unsigned char* category_group_enabled) {
499 return g_category_group_filter[GetCategoryIndex(category_group_enabled)]
500 .Pointer();
451 } 501 }
452 502
453 void TraceLog::UpdateCategoryGroupEnabledFlag(size_t category_index) { 503 void TraceLog::UpdateCategoryGroupEnabledFlag(size_t category_index) {
454 unsigned char enabled_flag = 0; 504 unsigned char enabled_flag = 0;
455 const char* category_group = g_category_groups[category_index]; 505 const char* category_group = g_category_groups[category_index];
456 if (mode_ == RECORDING_MODE && 506 if (mode_ == RECORDING_MODE &&
457 trace_config_.IsCategoryGroupEnabled(category_group)) { 507 trace_config_.IsCategoryGroupEnabled(category_group)) {
458 enabled_flag |= ENABLED_FOR_RECORDING; 508 enabled_flag |= ENABLED_FOR_RECORDING;
459 } 509 }
460 510
461 if (event_callback_ && 511 if (event_callback_ &&
462 event_callback_trace_config_.IsCategoryGroupEnabled(category_group)) { 512 event_callback_trace_config_.IsCategoryGroupEnabled(category_group)) {
463 enabled_flag |= ENABLED_FOR_EVENT_CALLBACK; 513 enabled_flag |= ENABLED_FOR_EVENT_CALLBACK;
464 } 514 }
465 515
466 #if defined(OS_WIN) 516 #if defined(OS_WIN)
467 if (base::trace_event::TraceEventETWExport::IsCategoryGroupEnabled( 517 if (base::trace_event::TraceEventETWExport::IsCategoryGroupEnabled(
468 category_group)) { 518 category_group)) {
469 enabled_flag |= ENABLED_FOR_ETW_EXPORT; 519 enabled_flag |= ENABLED_FOR_ETW_EXPORT;
470 } 520 }
471 #endif 521 #endif
472 522
523 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
524 g_category_group_filter[category_index].Get().clear();
525
526 for (const auto& category_event_filter :
527 trace_config_.category_event_filters()) {
528 if (category_event_filter.IsCategoryGroupEnabled(category_group)) {
529 std::unique_ptr<TraceEventFilter> new_filter;
530
531 if (category_event_filter.predicate_name() ==
532 "event_whitelist_predicate") {
533 new_filter =
534 WrapUnique(new EventNameFilter(category_event_filter.args()));
535 }
536
537 if (new_filter) {
538 g_category_group_filter[category_index].Get().push_back(
539 std::move(new_filter));
540 enabled_flag |= ENABLED_FOR_FILTERING;
541 }
542 }
543 }
544
473 g_category_group_enabled[category_index] = enabled_flag; 545 g_category_group_enabled[category_index] = enabled_flag;
474 } 546 }
475 547
476 void TraceLog::UpdateCategoryGroupEnabledFlags() { 548 void TraceLog::UpdateCategoryGroupEnabledFlags() {
477 size_t category_index = base::subtle::NoBarrier_Load(&g_category_index); 549 size_t category_index = base::subtle::NoBarrier_Load(&g_category_index);
478 for (size_t i = 0; i < category_index; i++) 550 for (size_t i = 0; i < category_index; i++)
479 UpdateCategoryGroupEnabledFlag(i); 551 UpdateCategoryGroupEnabledFlag(i);
480 } 552 }
481 553
482 void TraceLog::UpdateSyntheticDelaysFromTraceConfig() { 554 void TraceLog::UpdateSyntheticDelaysFromTraceConfig() {
(...skipping 757 matching lines...) Expand 10 before | Expand all | Expand 10 after
1240 #if defined(OS_WIN) 1312 #if defined(OS_WIN)
1241 // This is done sooner rather than later, to avoid creating the event and 1313 // This is done sooner rather than later, to avoid creating the event and
1242 // acquiring the lock, which is not needed for ETW as it's already threadsafe. 1314 // acquiring the lock, which is not needed for ETW as it's already threadsafe.
1243 if (*category_group_enabled & ENABLED_FOR_ETW_EXPORT) 1315 if (*category_group_enabled & ENABLED_FOR_ETW_EXPORT)
1244 TraceEventETWExport::AddEvent(phase, category_group_enabled, name, id, 1316 TraceEventETWExport::AddEvent(phase, category_group_enabled, name, id,
1245 num_args, arg_names, arg_types, arg_values, 1317 num_args, arg_names, arg_types, arg_values,
1246 convertable_values); 1318 convertable_values);
1247 #endif // OS_WIN 1319 #endif // OS_WIN
1248 1320
1249 std::string console_message; 1321 std::string console_message;
1250 if (*category_group_enabled & ENABLED_FOR_RECORDING) { 1322 if (*category_group_enabled & ENABLED_FOR_FILTERING) {
1323 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
1324 new_trace_event->Initialize(thread_id, offset_event_timestamp, thread_now,
1325 phase, category_group_enabled, name, scope, id,
1326 bind_id, num_args, arg_names, arg_types,
1327 arg_values, convertable_values, flags);
1328
1329 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.
1330 GetCategoryGroupFilter(category_group_enabled);
1331 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.
1332 DCHECK(!filter_list->empty());
1333
1334 bool should_add_event = false;
1335 for (const auto& trace_event_filter : *filter_list) {
1336 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.
1337 if (trace_event_filter.get()->FilterTraceEvent(*new_trace_event))
1338 should_add_event = true;
1339 }
1340
1341 if (should_add_event) {
1342 OptionalAutoLock lock(&lock_);
1343
1344 TraceEvent* trace_event = NULL;
1345 if (thread_local_event_buffer) {
1346 trace_event = thread_local_event_buffer->AddTraceEvent(&handle);
1347 } else {
1348 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
1349 trace_event = AddEventToThreadSharedChunkWhileLocked(&handle, true);
1350 }
1351
1352 trace_event->MoveFrom(std::move(new_trace_event));
1353 }
1354 } else if (*category_group_enabled & ENABLED_FOR_RECORDING) {
1251 OptionalAutoLock lock(&lock_); 1355 OptionalAutoLock lock(&lock_);
1252 1356
1253 TraceEvent* trace_event = NULL; 1357 TraceEvent* trace_event = NULL;
1254 if (thread_local_event_buffer) { 1358 if (thread_local_event_buffer) {
1255 trace_event = thread_local_event_buffer->AddTraceEvent(&handle); 1359 trace_event = thread_local_event_buffer->AddTraceEvent(&handle);
1256 } else { 1360 } else {
1257 lock.EnsureAcquired(); 1361 lock.EnsureAcquired();
1258 trace_event = AddEventToThreadSharedChunkWhileLocked(&handle, true); 1362 trace_event = AddEventToThreadSharedChunkWhileLocked(&handle, true);
1259 } 1363 }
1260 1364
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after
1742 } 1846 }
1743 1847
1744 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { 1848 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() {
1745 if (*category_group_enabled_) { 1849 if (*category_group_enabled_) {
1746 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, name_, 1850 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, name_,
1747 event_handle_); 1851 event_handle_);
1748 } 1852 }
1749 } 1853 }
1750 1854
1751 } // namespace trace_event_internal 1855 } // namespace trace_event_internal
OLDNEW
« 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