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

Side by Side Diff: base/trace_event/trace_log.cc

Issue 2323483005: [tracing] Add filtering mode in TraceLog (Closed)
Patch Set: Nit. Created 4 years, 2 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
« base/trace_event/trace_log.h ('K') | « base/trace_event/trace_log.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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>
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 TraceLogStatus::TraceLogStatus() : event_capacity(0), event_count(0) {} 455 TraceLogStatus::TraceLogStatus() : event_capacity(0), event_count(0) {}
456 456
457 TraceLogStatus::~TraceLogStatus() {} 457 TraceLogStatus::~TraceLogStatus() {}
458 458
459 // static 459 // static
460 TraceLog* TraceLog::GetInstance() { 460 TraceLog* TraceLog::GetInstance() {
461 return Singleton<TraceLog, LeakySingletonTraits<TraceLog>>::get(); 461 return Singleton<TraceLog, LeakySingletonTraits<TraceLog>>::get();
462 } 462 }
463 463
464 TraceLog::TraceLog() 464 TraceLog::TraceLog()
465 : mode_(DISABLED), 465 : enabled_modes_(0),
466 num_traces_recorded_(0), 466 num_traces_recorded_(0),
467 event_callback_(0), 467 event_callback_(0),
468 dispatching_to_observer_list_(false), 468 dispatching_to_observer_list_(false),
469 process_sort_index_(0), 469 process_sort_index_(0),
470 process_id_hash_(0), 470 process_id_hash_(0),
471 process_id_(0), 471 process_id_(0),
472 watch_category_(0), 472 watch_category_(0),
473 trace_options_(kInternalRecordUntilFull), 473 trace_options_(kInternalRecordUntilFull),
474 trace_config_(TraceConfig()), 474 trace_config_(TraceConfig()),
475 event_callback_trace_config_(TraceConfig()), 475 event_callback_trace_config_(TraceConfig()),
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 } 553 }
554 554
555 const char* TraceLog::GetCategoryGroupName( 555 const char* TraceLog::GetCategoryGroupName(
556 const unsigned char* category_group_enabled) { 556 const unsigned char* category_group_enabled) {
557 return g_category_groups[GetCategoryIndex(category_group_enabled)]; 557 return g_category_groups[GetCategoryIndex(category_group_enabled)];
558 } 558 }
559 559
560 void TraceLog::UpdateCategoryGroupEnabledFlag(size_t category_index) { 560 void TraceLog::UpdateCategoryGroupEnabledFlag(size_t category_index) {
561 unsigned char enabled_flag = 0; 561 unsigned char enabled_flag = 0;
562 const char* category_group = g_category_groups[category_index]; 562 const char* category_group = g_category_groups[category_index];
563 if (mode_ == RECORDING_MODE && 563 if (enabled_modes_ & RECORDING_MODE &&
564 trace_config_.IsCategoryGroupEnabled(category_group)) { 564 trace_config_.IsCategoryGroupEnabled(category_group)) {
565 enabled_flag |= ENABLED_FOR_RECORDING; 565 enabled_flag |= ENABLED_FOR_RECORDING;
566 } 566 }
567 567
568 if (event_callback_ && 568 if (event_callback_ &&
569 event_callback_trace_config_.IsCategoryGroupEnabled(category_group)) { 569 event_callback_trace_config_.IsCategoryGroupEnabled(category_group)) {
570 enabled_flag |= ENABLED_FOR_EVENT_CALLBACK; 570 enabled_flag |= ENABLED_FOR_EVENT_CALLBACK;
571 } 571 }
572 572
573 #if defined(OS_WIN) 573 #if defined(OS_WIN)
574 if (base::trace_event::TraceEventETWExport::IsCategoryGroupEnabled( 574 if (base::trace_event::TraceEventETWExport::IsCategoryGroupEnabled(
575 category_group)) { 575 category_group)) {
576 enabled_flag |= ENABLED_FOR_ETW_EXPORT; 576 enabled_flag |= ENABLED_FOR_ETW_EXPORT;
577 } 577 }
578 #endif 578 #endif
579 579
580 // TODO(primiano): this is a temporary workaround for catapult:#2341, 580 // TODO(primiano): this is a temporary workaround for catapult:#2341,
581 // to guarantee that metadata events are always added even if the category 581 // to guarantee that metadata events are always added even if the category
582 // filter is "-*". See crbug.com/618054 for more details and long-term fix. 582 // filter is "-*". See crbug.com/618054 for more details and long-term fix.
583 if (mode_ == RECORDING_MODE && !strcmp(category_group, "__metadata")) 583 if (enabled_modes_ & RECORDING_MODE && !strcmp(category_group, "__metadata"))
584 enabled_flag |= ENABLED_FOR_RECORDING; 584 enabled_flag |= ENABLED_FOR_RECORDING;
585 585
586 uint32_t enabled_filters_bitmap = 0; 586 uint32_t enabled_filters_bitmap = 0;
587 int index = 0; 587 int index = 0;
588 for (const auto& event_filter : trace_config_.event_filters()) { 588 for (const auto& event_filter : enabled_event_filters_) {
589 if (event_filter.IsCategoryGroupEnabled(category_group)) { 589 if (event_filter.IsCategoryGroupEnabled(category_group)) {
590 enabled_flag |= ENABLED_FOR_FILTERING; 590 enabled_flag |= ENABLED_FOR_FILTERING;
591 DCHECK(g_category_group_filters.Get()[index]); 591 DCHECK(g_category_group_filters.Get()[index]);
592 enabled_filters_bitmap |= 1 << index; 592 enabled_filters_bitmap |= 1 << index;
593 } 593 }
594 if (index++ >= MAX_TRACE_EVENT_FILTERS) { 594 if (index++ >= MAX_TRACE_EVENT_FILTERS) {
595 NOTREACHED(); 595 NOTREACHED();
596 break; 596 break;
597 } 597 }
598 } 598 }
599 g_category_group_filters_enabled[category_index] = enabled_filters_bitmap; 599 g_category_group_filters_enabled[category_index] = enabled_filters_bitmap;
600 600
601 g_category_group_enabled[category_index] = enabled_flag; 601 g_category_group_enabled[category_index] = enabled_flag;
602 } 602 }
603 603
604 void TraceLog::UpdateCategoryGroupEnabledFlags() { 604 void TraceLog::UpdateCategoryGroupEnabledFlags() {
605 CreateFiltersForTraceConfig(); 605 CreateFiltersForTraceConfig();
606 size_t category_index = base::subtle::NoBarrier_Load(&g_category_index); 606 size_t category_index = base::subtle::NoBarrier_Load(&g_category_index);
607 for (size_t i = 0; i < category_index; i++) 607 for (size_t i = 0; i < category_index; i++)
608 UpdateCategoryGroupEnabledFlag(i); 608 UpdateCategoryGroupEnabledFlag(i);
609 } 609 }
610 610
611 void TraceLog::CreateFiltersForTraceConfig() { 611 void TraceLog::CreateFiltersForTraceConfig() {
612 if (!(enabled_modes_ & FILTERING_MODE))
613 return;
614
612 // Filters were already added and tracing could be enabled. Filters list 615 // Filters were already added and tracing could be enabled. Filters list
613 // cannot be changed when trace events are using them. 616 // cannot be changed when trace events are using them.
614 if (g_category_group_filters.Get().size()) 617 if (g_category_group_filters.Get().size())
615 return; 618 return;
616 619
617 for (auto& event_filter : trace_config_.event_filters()) { 620 for (auto& event_filter : enabled_event_filters_) {
618 if (g_category_group_filters.Get().size() >= MAX_TRACE_EVENT_FILTERS) { 621 if (g_category_group_filters.Get().size() >= MAX_TRACE_EVENT_FILTERS) {
619 NOTREACHED() 622 NOTREACHED()
620 << "Too many trace event filters installed in the current session"; 623 << "Too many trace event filters installed in the current session";
621 break; 624 break;
622 } 625 }
623 626
624 std::unique_ptr<TraceEventFilter> new_filter; 627 std::unique_ptr<TraceEventFilter> new_filter;
625 if (event_filter.predicate_name() == 628 if (event_filter.predicate_name() ==
626 TraceEventFilter::kEventWhitelistPredicate) { 629 TraceEventFilter::kEventWhitelistPredicate) {
627 new_filter = MakeUnique<EventNameFilter>(event_filter.filter_args()); 630 new_filter = MakeUnique<EventNameFilter>(event_filter.filter_args());
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 } 723 }
721 724
722 void TraceLog::GetKnownCategoryGroups( 725 void TraceLog::GetKnownCategoryGroups(
723 std::vector<std::string>* category_groups) { 726 std::vector<std::string>* category_groups) {
724 AutoLock lock(lock_); 727 AutoLock lock(lock_);
725 size_t category_index = base::subtle::NoBarrier_Load(&g_category_index); 728 size_t category_index = base::subtle::NoBarrier_Load(&g_category_index);
726 for (size_t i = kNumBuiltinCategories; i < category_index; i++) 729 for (size_t i = kNumBuiltinCategories; i < category_index; i++)
727 category_groups->push_back(g_category_groups[i]); 730 category_groups->push_back(g_category_groups[i]);
728 } 731 }
729 732
730 void TraceLog::SetEnabled(const TraceConfig& trace_config, Mode mode) { 733 void TraceLog::SetEnabled(const TraceConfig& trace_config, uint8_t modes) {
731 std::vector<EnabledStateObserver*> observer_list; 734 std::vector<EnabledStateObserver*> observer_list;
732 std::map<AsyncEnabledStateObserver*, RegisteredAsyncObserver> observer_map; 735 std::map<AsyncEnabledStateObserver*, RegisteredAsyncObserver> observer_map;
733 { 736 {
734 AutoLock lock(lock_); 737 AutoLock lock(lock_);
735 738
736 // Can't enable tracing when Flush() is in progress. 739 // Can't enable tracing when Flush() is in progress.
737 DCHECK(!flush_task_runner_); 740 DCHECK(!flush_task_runner_);
738 741
739 InternalTraceOptions new_options = 742 InternalTraceOptions new_options =
740 GetInternalOptionsFromTraceConfig(trace_config); 743 GetInternalOptionsFromTraceConfig(trace_config);
741 744
742 InternalTraceOptions old_options = trace_options(); 745 InternalTraceOptions old_options = trace_options();
743 746
744 if (IsEnabled()) {
745 if (new_options != old_options) {
746 DLOG(ERROR) << "Attempting to re-enable tracing with a different "
747 << "set of options.";
748 }
749
750 if (mode != mode_) {
751 DLOG(ERROR) << "Attempting to re-enable tracing with a different mode.";
752 }
753
754 DCHECK(!trace_config.event_filters().size())
755 << "Adding new filters while tracing was already enabled is not "
756 "supported.";
757
758 trace_config_.Merge(trace_config);
759 UpdateCategoryGroupEnabledFlags();
760 return;
761 }
762
763 if (dispatching_to_observer_list_) { 747 if (dispatching_to_observer_list_) {
764 DLOG(ERROR) 748 NOTREACHED()
765 << "Cannot manipulate TraceLog::Enabled state from an observer."; 749 << "Cannot manipulate TraceLog::Enabled state from an observer.";
766 return; 750 return;
767 } 751 }
768 752
769 mode_ = mode; 753 // Clear all filters from previous tracing session. These filters are not
754 // cleared at the end of tracing because some threads which hit trace event
755 // when disabling, could try to use the filters.
756 if (!enabled_modes_)
757 g_category_group_filters.Get().clear();
758
759 // Update trace config for recording.
760 const bool already_recording = enabled_modes_ & RECORDING_MODE;
761 if (modes & RECORDING_MODE) {
762 if (already_recording) {
763 // TODO(ssid): Stop suporting enabling of RECODING_MODE when already
764 // enabled crbug.com/625170.
765 DCHECK_EQ(new_options, old_options) << "Attempting to re-enable "
766 "tracing with a different set "
767 "of options.";
768 trace_config_.Merge(trace_config);
769 } else {
770 trace_config_ = trace_config;
771 }
772 }
773
774 // Update event filters.
775 if (modes & FILTERING_MODE) {
776 DCHECK(!trace_config.event_filters().empty())
777 << "Attempting to enable filtering without any filters";
778 DCHECK(enabled_event_filters_.empty()) << "Attempting to re-enable "
779 "filtering when filters are "
780 "already enabled.";
781
782 // Use the given event filters only if filtering was not enabled.
783 if (enabled_event_filters_.empty())
784 enabled_event_filters_ = trace_config.event_filters();
785 }
786 // Keep the |trace_config_| updated with only enabled filters in case anyone
787 // tries to read it using |GetCurrentTraceConfig| (even if filters are
788 // empty).
789 trace_config_.SetEventFilters(enabled_event_filters_);
790
791 enabled_modes_ |= modes;
792 UpdateCategoryGroupEnabledFlags();
793
794 // Do not notify observers or create trace buffer if only enabled for
795 // filtering or if recording was already enabled.
796 if (!(modes & RECORDING_MODE) || already_recording)
797 return;
770 798
771 if (new_options != old_options) { 799 if (new_options != old_options) {
772 subtle::NoBarrier_Store(&trace_options_, new_options); 800 subtle::NoBarrier_Store(&trace_options_, new_options);
773 UseNextTraceBuffer(); 801 UseNextTraceBuffer();
774 } 802 }
775 803
776 num_traces_recorded_++; 804 num_traces_recorded_++;
777 805
778 // Clear all filters from previous tracing session. These filters are not
779 // cleared at the end of tracing because some threads which hit trace event
780 // when disabling, could try to use the filters.
781 g_category_group_filters.Get().clear();
782
783 trace_config_ = TraceConfig(trace_config);
784 UpdateCategoryGroupEnabledFlags(); 806 UpdateCategoryGroupEnabledFlags();
785 UpdateSyntheticDelaysFromTraceConfig(); 807 UpdateSyntheticDelaysFromTraceConfig();
786 808
787 dispatching_to_observer_list_ = true; 809 dispatching_to_observer_list_ = true;
788 observer_list = enabled_state_observer_list_; 810 observer_list = enabled_state_observer_list_;
789 observer_map = async_observers_; 811 observer_map = async_observers_;
790 } 812 }
791 // Notify observers outside the lock in case they trigger trace events. 813 // Notify observers outside the lock in case they trigger trace events.
792 for (EnabledStateObserver* observer : observer_list) 814 for (EnabledStateObserver* observer : observer_list)
793 observer->OnTraceLogEnabled(); 815 observer->OnTraceLogEnabled();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
830 return kInternalNone; 852 return kInternalNone;
831 } 853 }
832 854
833 TraceConfig TraceLog::GetCurrentTraceConfig() const { 855 TraceConfig TraceLog::GetCurrentTraceConfig() const {
834 AutoLock lock(lock_); 856 AutoLock lock(lock_);
835 return trace_config_; 857 return trace_config_;
836 } 858 }
837 859
838 void TraceLog::SetDisabled() { 860 void TraceLog::SetDisabled() {
839 AutoLock lock(lock_); 861 AutoLock lock(lock_);
840 SetDisabledWhileLocked(); 862 SetDisabledWhileLocked(RECORDING_MODE);
841 } 863 }
842 864
843 void TraceLog::SetDisabledWhileLocked() { 865 void TraceLog::SetDisabled(uint8_t modes) {
866 AutoLock lock(lock_);
867 SetDisabledWhileLocked(modes);
868 }
869
870 void TraceLog::SetDisabledWhileLocked(uint8_t modes) {
Primiano Tucci (use gerrit) 2016/10/13 19:11:24 nit: probably a bit easier to read if this var is
ssid 2016/10/13 19:39:36 Done.
844 lock_.AssertAcquired(); 871 lock_.AssertAcquired();
845 872
846 if (!IsEnabled()) 873 if (!(enabled_modes_ & modes))
847 return; 874 return;
848 875
849 if (dispatching_to_observer_list_) { 876 if (dispatching_to_observer_list_) {
850 DLOG(ERROR) 877 NOTREACHED()
851 << "Cannot manipulate TraceLog::Enabled state from an observer."; 878 << "Cannot manipulate TraceLog::Enabled state from an observer.";
852 return; 879 return;
853 } 880 }
854 881
855 mode_ = DISABLED; 882 bool is_recording_mode_disabled =
883 (enabled_modes_ & RECORDING_MODE) && (modes & RECORDING_MODE);
884 enabled_modes_ &= ~modes;
856 885
857 trace_config_.Clear(); 886 if (modes & FILTERING_MODE)
858 subtle::NoBarrier_Store(&watch_category_, 0); 887 enabled_event_filters_.clear();
859 watch_event_name_.clear(); 888
889 if (modes & RECORDING_MODE) {
890 trace_config_.Clear();
891
892 subtle::NoBarrier_Store(&watch_category_, 0);
893 watch_event_name_.clear();
894 }
895
860 UpdateCategoryGroupEnabledFlags(); 896 UpdateCategoryGroupEnabledFlags();
897
898 // Add metadata events and notify observers only if recording mode was
899 // disabled now.
900 if (!is_recording_mode_disabled)
901 return;
902
861 AddMetadataEventsWhileLocked(); 903 AddMetadataEventsWhileLocked();
862 904
863 // Remove metadata events so they will not get added to a subsequent trace. 905 // Remove metadata events so they will not get added to a subsequent trace.
864 metadata_events_.clear(); 906 metadata_events_.clear();
865 907
866 dispatching_to_observer_list_ = true; 908 dispatching_to_observer_list_ = true;
867 std::vector<EnabledStateObserver*> observer_list = 909 std::vector<EnabledStateObserver*> observer_list =
868 enabled_state_observer_list_; 910 enabled_state_observer_list_;
869 std::map<AsyncEnabledStateObserver*, RegisteredAsyncObserver> observer_map = 911 std::map<AsyncEnabledStateObserver*, RegisteredAsyncObserver> observer_map =
870 async_observers_; 912 async_observers_;
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
950 } 992 }
951 return trace_event; 993 return trace_event;
952 } 994 }
953 995
954 void TraceLog::CheckIfBufferIsFullWhileLocked() { 996 void TraceLog::CheckIfBufferIsFullWhileLocked() {
955 lock_.AssertAcquired(); 997 lock_.AssertAcquired();
956 if (logged_events_->IsFull()) { 998 if (logged_events_->IsFull()) {
957 if (buffer_limit_reached_timestamp_.is_null()) { 999 if (buffer_limit_reached_timestamp_.is_null()) {
958 buffer_limit_reached_timestamp_ = OffsetNow(); 1000 buffer_limit_reached_timestamp_ = OffsetNow();
959 } 1001 }
960 SetDisabledWhileLocked(); 1002 SetDisabledWhileLocked(RECORDING_MODE);
961 } 1003 }
962 } 1004 }
963 1005
964 void TraceLog::SetEventCallbackEnabled(const TraceConfig& trace_config, 1006 void TraceLog::SetEventCallbackEnabled(const TraceConfig& trace_config,
965 EventCallback cb) { 1007 EventCallback cb) {
966 AutoLock lock(lock_); 1008 AutoLock lock(lock_);
967 subtle::NoBarrier_Store(&event_callback_, 1009 subtle::NoBarrier_Store(&event_callback_,
968 reinterpret_cast<subtle::AtomicWord>(cb)); 1010 reinterpret_cast<subtle::AtomicWord>(cb));
969 event_callback_trace_config_ = trace_config; 1011 event_callback_trace_config_ = trace_config;
970 UpdateCategoryGroupEnabledFlags(); 1012 UpdateCategoryGroupEnabledFlags();
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
1337 if (flags & TRACE_EVENT_FLAG_MANGLE_ID) { 1379 if (flags & TRACE_EVENT_FLAG_MANGLE_ID) {
1338 if ((flags & TRACE_EVENT_FLAG_FLOW_IN) || 1380 if ((flags & TRACE_EVENT_FLAG_FLOW_IN) ||
1339 (flags & TRACE_EVENT_FLAG_FLOW_OUT)) 1381 (flags & TRACE_EVENT_FLAG_FLOW_OUT))
1340 bind_id = MangleEventId(bind_id); 1382 bind_id = MangleEventId(bind_id);
1341 id = MangleEventId(id); 1383 id = MangleEventId(id);
1342 } 1384 }
1343 1385
1344 TimeTicks offset_event_timestamp = OffsetTimestamp(timestamp); 1386 TimeTicks offset_event_timestamp = OffsetTimestamp(timestamp);
1345 ThreadTicks thread_now = ThreadNow(); 1387 ThreadTicks thread_now = ThreadNow();
1346 1388
1347 // |thread_local_event_buffer_| can be null if the current thread doesn't have 1389 ThreadLocalEventBuffer* thread_local_event_buffer = nullptr;
1348 // a message loop or the message loop is blocked. 1390 if (enabled_modes_ & RECORDING_MODE) {
1349 InitializeThreadLocalEventBufferIfSupported(); 1391 // |thread_local_event_buffer_| can be null if the current thread doesn't
1350 auto* thread_local_event_buffer = thread_local_event_buffer_.Get(); 1392 // have a message loop or the message loop is blocked.
1393 InitializeThreadLocalEventBufferIfSupported();
1394 thread_local_event_buffer = thread_local_event_buffer_.Get();
1395 }
1351 1396
1352 // Check and update the current thread name only if the event is for the 1397 // Check and update the current thread name only if the event is for the
1353 // current thread to avoid locks in most cases. 1398 // current thread to avoid locks in most cases.
1354 if (thread_id == static_cast<int>(PlatformThread::CurrentId())) { 1399 if (thread_id == static_cast<int>(PlatformThread::CurrentId())) {
1355 const char* new_name = 1400 const char* new_name =
1356 ThreadIdNameManager::GetInstance()->GetName(thread_id); 1401 ThreadIdNameManager::GetInstance()->GetName(thread_id);
1357 // Check if the thread name has been set or changed since the previous 1402 // Check if the thread name has been set or changed since the previous
1358 // call (if any), but don't bother if the new name is empty. Note this will 1403 // call (if any), but don't bother if the new name is empty. Note this will
1359 // not detect a thread name change within the same char* buffer address: we 1404 // not detect a thread name change within the same char* buffer address: we
1360 // favor common case performance over corner case correctness. 1405 // favor common case performance over corner case correctness.
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after
1925 } 1970 }
1926 1971
1927 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { 1972 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() {
1928 if (*category_group_enabled_) { 1973 if (*category_group_enabled_) {
1929 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, name_, 1974 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, name_,
1930 event_handle_); 1975 event_handle_);
1931 } 1976 }
1932 } 1977 }
1933 1978
1934 } // namespace trace_event_internal 1979 } // namespace trace_event_internal
OLDNEW
« base/trace_event/trace_log.h ('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