| // Copyright 2015 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef BASE_TRACE_EVENT_TRACE_LOG_H_ |
| #define BASE_TRACE_EVENT_TRACE_LOG_H_ |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| #include <atomic> |
| #include <map> |
| #include <memory> |
| #include <string> |
| #include <unordered_map> |
| #include <vector> |
| |
| #include "base/base_export.h" |
| #include "base/containers/stack.h" |
| #include "base/gtest_prod_util.h" |
| #include "base/memory/scoped_refptr.h" |
| #include "base/no_destructor.h" |
| #include "base/task/single_thread_task_runner.h" |
| #include "base/threading/platform_thread.h" |
| #include "base/time/time_override.h" |
| #include "base/trace_event/category_registry.h" |
| #include "base/trace_event/memory_dump_provider.h" |
| #include "base/trace_event/trace_config.h" |
| #include "base/trace_event/trace_event_impl.h" |
| #include "build/build_config.h" |
| #include "third_party/abseil-cpp/absl/types/optional.h" |
| |
| #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) |
| #include "third_party/perfetto/include/perfetto/tracing/core/trace_config.h" |
| |
| namespace perfetto { |
| namespace trace_processor { |
| class TraceProcessorStorage; |
| } // namespace trace_processor |
| } // namespace perfetto |
| |
| #endif // BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) |
| |
| namespace base { |
| class RefCountedString; |
| |
| namespace tracing { |
| class PerfettoPlatform; |
| } // namespace tracing |
| |
| namespace trace_event { |
| |
| struct TraceCategory; |
| class TraceBuffer; |
| class TraceBufferChunk; |
| class TraceEvent; |
| class TraceEventMemoryOverhead; |
| class JsonStringOutputWriter; |
| |
| struct BASE_EXPORT TraceLogStatus { |
| TraceLogStatus(); |
| ~TraceLogStatus(); |
| uint32_t event_capacity; |
| uint32_t event_count; |
| }; |
| |
| class BASE_EXPORT TraceLog : |
| #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) |
| public perfetto::TrackEventSessionObserver, |
| #endif // BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) |
| public MemoryDumpProvider { |
| public: |
| class ThreadLocalEventBuffer; |
| |
| // Argument passed to TraceLog::SetEnabled. |
| enum Mode : uint8_t { |
| // Enables normal tracing (recording trace events in the trace buffer). |
| // This is the only tracing mode supported now. |
| // TODO(khokhlov): Clean up all uses of tracing mode and remove this enum |
| // completely. |
| RECORDING_MODE = 1 << 0, |
| }; |
| |
| static TraceLog* GetInstance(); |
| |
| TraceLog(const TraceLog&) = delete; |
| TraceLog& operator=(const TraceLog&) = delete; |
| |
| // Retrieves a copy (for thread-safety) of the current TraceConfig. |
| TraceConfig GetCurrentTraceConfig() const; |
| |
| // Initializes the thread-local event buffer, if not already initialized and |
| // if the current thread supports that (has a message loop). |
| void InitializeThreadLocalEventBufferIfSupported(); |
| |
| // See TraceConfig comments for details on how to control which categories |
| // will be traced. Only RECORDING_MODE is supported. |
| void SetEnabled(const TraceConfig& trace_config, uint8_t modes_to_enable); |
| |
| #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) |
| // Enable tracing using a customized Perfetto trace config. This allows, for |
| // example, enabling additional data sources and enabling protobuf output |
| // instead of the legacy JSON trace format. |
| void SetEnabled(const TraceConfig& trace_config, |
| const perfetto::TraceConfig& perfetto_config); |
| #endif |
| |
| // Disables tracing for all categories. Only RECORDING_MODE is supported. |
| void SetDisabled(); |
| void SetDisabled(uint8_t modes_to_disable); |
| |
| // Returns true if TraceLog is enabled on recording mode. |
| // Note: Returns false even if FILTERING_MODE is enabled. |
| bool IsEnabled() { |
| #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) |
| // In SDK build we return true as soon as the datasource has been set up and |
| // we know the config. This doesn't necessarily mean that the tracing has |
| // already started. |
| // Note that TrackEvent::IsEnabled() can be true even earlier, before the |
| // OnSetup call, so we can't guarantee that we know the config by the time |
| // TrackEvent::IsEnabled() is true. |
| AutoLock lock(track_event_lock_); |
| return track_event_enabled_; |
| #else // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) |
| AutoLock lock(lock_); |
| return enabled_; |
| #endif // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) |
| } |
| |
| // The number of times we have begun recording traces. If tracing is off, |
| // returns -1. If tracing is on, then it returns the number of times we have |
| // recorded a trace. By watching for this number to increment, you can |
| // passively discover when a new trace has begun. This is then used to |
| // implement the TRACE_EVENT_IS_NEW_TRACE() primitive. |
| int GetNumTracesRecorded(); |
| |
| // Enabled state listeners give a callback when tracing is enabled or |
| // disabled. This can be used to tie into other library's tracing systems |
| // on-demand. |
| class BASE_EXPORT EnabledStateObserver { |
| public: |
| virtual ~EnabledStateObserver() = default; |
| |
| // Called just after the tracing system becomes enabled, outside of the |
| // |lock_|. TraceLog::IsEnabled() is true at this point. |
| virtual void OnTraceLogEnabled() = 0; |
| |
| // Called just after the tracing system disables, outside of the |lock_|. |
| // TraceLog::IsEnabled() is false at this point. |
| virtual void OnTraceLogDisabled() = 0; |
| }; |
| // Adds an observer. Cannot be called from within the observer callback. |
| void AddEnabledStateObserver(EnabledStateObserver* listener); |
| // Removes an observer. Cannot be called from within the observer callback. |
| void RemoveEnabledStateObserver(EnabledStateObserver* listener); |
| // Adds an observer that is owned by TraceLog. This is useful for agents that |
| // implement tracing feature that needs to stay alive as long as TraceLog |
| // does. |
| void AddOwnedEnabledStateObserver( |
| std::unique_ptr<EnabledStateObserver> listener); |
| bool HasEnabledStateObserver(EnabledStateObserver* listener) const; |
| |
| // Asynchronous enabled state listeners. When tracing is enabled or disabled, |
| // for each observer, a task for invoking its appropriate callback is posted |
| // to the thread from which AddAsyncEnabledStateObserver() was called. This |
| // allows the observer to be safely destroyed, provided that it happens on the |
| // same thread that invoked AddAsyncEnabledStateObserver(). |
| class BASE_EXPORT AsyncEnabledStateObserver { |
| public: |
| virtual ~AsyncEnabledStateObserver() = default; |
| |
| // Posted just after the tracing system becomes enabled, outside |lock_|. |
| // TraceLog::IsEnabled() is true at this point. |
| virtual void OnTraceLogEnabled() = 0; |
| |
| // Posted just after the tracing system becomes disabled, outside |lock_|. |
| // TraceLog::IsEnabled() is false at this point. |
| virtual void OnTraceLogDisabled() = 0; |
| }; |
| // TODO(oysteine): This API originally needed to use WeakPtrs as the observer |
| // list was copied under the global trace lock, but iterated over outside of |
| // that lock so that observers could add tracing. The list is now protected by |
| // its own lock, so this can be changed to a raw ptr. |
| void AddAsyncEnabledStateObserver( |
| WeakPtr<AsyncEnabledStateObserver> listener); |
| void RemoveAsyncEnabledStateObserver(AsyncEnabledStateObserver* listener); |
| bool HasAsyncEnabledStateObserver(AsyncEnabledStateObserver* listener) const; |
| |
| // Observers that are notified when incremental state is cleared. This only |
| // happens when tracing using the perfetto backend. |
| class BASE_EXPORT IncrementalStateObserver { |
| public: |
| virtual ~IncrementalStateObserver() = default; |
| |
| // Called just after the tracing system has cleared incremental state, while |
| // a tracing session is active. |
| virtual void OnIncrementalStateCleared() = 0; |
| }; |
| // Adds an observer. Cannot be called from within the observer callback. |
| void AddIncrementalStateObserver(IncrementalStateObserver* listener); |
| // Removes an observer. Cannot be called from within the observer callback. |
| void RemoveIncrementalStateObserver(IncrementalStateObserver* listener); |
| |
| TraceLogStatus GetStatus() const; |
| |
| #if !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) |
| bool BufferIsFull() const; |
| #endif // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) |
| |
| // Computes an estimate of the size of the TraceLog including all the retained |
| // objects. |
| void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead); |
| |
| void SetArgumentFilterPredicate( |
| const ArgumentFilterPredicate& argument_filter_predicate); |
| ArgumentFilterPredicate GetArgumentFilterPredicate() const; |
| |
| void SetMetadataFilterPredicate( |
| const MetadataFilterPredicate& metadata_filter_predicate); |
| MetadataFilterPredicate GetMetadataFilterPredicate() const; |
| |
| void SetRecordHostAppPackageName(bool record_host_app_package_name); |
| bool ShouldRecordHostAppPackageName() const; |
| |
| // Flush all collected events to the given output callback. The callback will |
| // be called one or more times either synchronously or asynchronously from |
| // the current thread with IPC-bite-size chunks. The string format is |
| // undefined. Use TraceResultBuffer to convert one or more trace strings to |
| // JSON. The callback can be null if the caller doesn't want any data. |
| // Due to the implementation of thread-local buffers, flush can't be |
| // done when tracing is enabled. If called when tracing is enabled, the |
| // callback will be called directly with (empty_string, false) to indicate |
| // the end of this unsuccessful flush. Flush does the serialization |
| // on the same thread if the caller doesn't set use_worker_thread explicitly. |
| using OutputCallback = |
| base::RepeatingCallback<void(const scoped_refptr<base::RefCountedString>&, |
| bool has_more_events)>; |
| void Flush(const OutputCallback& cb, bool use_worker_thread = false); |
| |
| // Cancels tracing and discards collected data. |
| void CancelTracing(const OutputCallback& cb); |
| |
| using AddTraceEventOverrideFunction = void (*)(TraceEvent*, |
| bool thread_will_flush, |
| TraceEventHandle* handle); |
| using OnFlushFunction = void (*)(); |
| using UpdateDurationFunction = |
| void (*)(const unsigned char* category_group_enabled, |
| const char* name, |
| TraceEventHandle handle, |
| PlatformThreadId thread_id, |
| bool explicit_timestamps, |
| const TimeTicks& now, |
| const ThreadTicks& thread_now); |
| // The callbacks will be called up until the point where the flush is |
| // finished, i.e. must be callable until OutputCallback is called with |
| // has_more_events==false. |
| void SetAddTraceEventOverrides( |
| const AddTraceEventOverrideFunction& add_event_override, |
| const OnFlushFunction& on_flush_callback, |
| const UpdateDurationFunction& update_duration_callback); |
| |
| // Called by TRACE_EVENT* macros, don't call this directly. |
| // The name parameter is a category group for example: |
| // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent") |
| static const unsigned char* GetCategoryGroupEnabled(const char* name); |
| static const char* GetCategoryGroupName( |
| const unsigned char* category_group_enabled); |
| static constexpr const unsigned char* GetBuiltinCategoryEnabled( |
| const char* name) { |
| TraceCategory* builtin_category = |
| CategoryRegistry::GetBuiltinCategoryByName(name); |
| if (builtin_category) |
| return builtin_category->state_ptr(); |
| return nullptr; |
| } |
| |
| // Called by TRACE_EVENT* macros, don't call this directly. |
| // If |copy| is set, |name|, |arg_name1| and |arg_name2| will be deep copied |
| // into the event; see "Memory scoping note" and TRACE_EVENT_COPY_XXX above. |
| bool ShouldAddAfterUpdatingState(char phase, |
| const unsigned char* category_group_enabled, |
| const char* name, |
| uint64_t id, |
| PlatformThreadId thread_id, |
| TraceArguments* args); |
| TraceEventHandle AddTraceEvent(char phase, |
| const unsigned char* category_group_enabled, |
| const char* name, |
| const char* scope, |
| uint64_t id, |
| TraceArguments* args, |
| unsigned int flags); |
| TraceEventHandle AddTraceEventWithBindId( |
| char phase, |
| const unsigned char* category_group_enabled, |
| const char* name, |
| const char* scope, |
| uint64_t id, |
| uint64_t bind_id, |
| TraceArguments* args, |
| unsigned int flags); |
| TraceEventHandle AddTraceEventWithProcessId( |
| char phase, |
| const unsigned char* category_group_enabled, |
| const char* name, |
| const char* scope, |
| uint64_t id, |
| ProcessId process_id, |
| TraceArguments* args, |
| unsigned int flags); |
| TraceEventHandle AddTraceEventWithThreadIdAndTimestamp( |
| char phase, |
| const unsigned char* category_group_enabled, |
| const char* name, |
| const char* scope, |
| uint64_t id, |
| PlatformThreadId thread_id, |
| const TimeTicks& timestamp, |
| TraceArguments* args, |
| unsigned int flags); |
| TraceEventHandle AddTraceEventWithThreadIdAndTimestamp( |
| char phase, |
| const unsigned char* category_group_enabled, |
| const char* name, |
| const char* scope, |
| uint64_t id, |
| uint64_t bind_id, |
| PlatformThreadId thread_id, |
| const TimeTicks& timestamp, |
| TraceArguments* args, |
| unsigned int flags); |
| TraceEventHandle AddTraceEventWithThreadIdAndTimestamps( |
| char phase, |
| const unsigned char* category_group_enabled, |
| const char* name, |
| const char* scope, |
| uint64_t id, |
| uint64_t bind_id, |
| PlatformThreadId thread_id, |
| const TimeTicks& timestamp, |
| const ThreadTicks& thread_timestamp, |
| TraceArguments* args, |
| unsigned int flags); |
| |
| // Adds a metadata event that will be written when the trace log is flushed. |
| void AddMetadataEvent(const unsigned char* category_group_enabled, |
| const char* name, |
| TraceArguments* args, |
| unsigned int flags); |
| |
| void UpdateTraceEventDuration(const unsigned char* category_group_enabled, |
| const char* name, |
| TraceEventHandle handle); |
| |
| void UpdateTraceEventDurationExplicit( |
| const unsigned char* category_group_enabled, |
| const char* name, |
| TraceEventHandle handle, |
| PlatformThreadId thread_id, |
| bool explicit_timestamps, |
| const TimeTicks& now, |
| const ThreadTicks& thread_now); |
| |
| ProcessId process_id() const { return process_id_; } |
| |
| std::unordered_map<int, std::string> process_labels() const { |
| AutoLock lock(lock_); |
| return process_labels_; |
| } |
| |
| uint64_t MangleEventId(uint64_t id); |
| |
| // Exposed for unittesting: |
| // Allows clearing up our singleton instance. |
| static void ResetForTesting(); |
| |
| // Allow tests to inspect TraceEvents. |
| TraceEvent* GetEventByHandle(TraceEventHandle handle); |
| |
| void SetProcessID(ProcessId process_id); |
| |
| // Process sort indices, if set, override the order of a process will appear |
| // relative to other processes in the trace viewer. Processes are sorted first |
| // on their sort index, ascending, then by their name, and then tid. |
| void SetProcessSortIndex(int sort_index); |
| |
| // Helper function to set process_name in base::CurrentProcess. |
| void OnSetProcessName(const std::string& process_name); |
| |
| // Processes can have labels in addition to their names. Use labels, for |
| // instance, to list out the web page titles that a process is handling. |
| void UpdateProcessLabel(int label_id, const std::string& current_label); |
| void RemoveProcessLabel(int label_id); |
| |
| // Thread sort indices, if set, override the order of a thread will appear |
| // within its process in the trace viewer. Threads are sorted first on their |
| // sort index, ascending, then by their name, and then tid. |
| void SetThreadSortIndex(PlatformThreadId thread_id, int sort_index); |
| |
| #if !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) |
| // Allow setting an offset between the current TimeTicks time and the time |
| // that should be reported. |
| void SetTimeOffset(TimeDelta offset); |
| #endif // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) |
| |
| size_t GetObserverCountForTest() const; |
| |
| // Call this method if the current thread may block the message loop to |
| // prevent the thread from using the thread-local buffer because the thread |
| // may not handle the flush request in time causing lost of unflushed events. |
| void SetCurrentThreadBlocksMessageLoop(); |
| |
| #if BUILDFLAG(IS_WIN) |
| // This function is called by the ETW exporting module whenever the ETW |
| // keyword (flags) changes. This keyword indicates which categories should be |
| // exported, so whenever it changes, we adjust accordingly. |
| void UpdateETWCategoryGroupEnabledFlags(); |
| #endif |
| |
| // Replaces |logged_events_| with a new TraceBuffer for testing. |
| void SetTraceBufferForTesting(std::unique_ptr<TraceBuffer> trace_buffer); |
| |
| #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) |
| perfetto::DataSourceConfig GetCurrentTrackEventDataSourceConfig() const; |
| void InitializePerfettoIfNeeded(); |
| void SetEnabledImpl(const TraceConfig& trace_config, |
| const perfetto::TraceConfig& perfetto_config); |
| |
| // perfetto::TrackEventSessionObserver implementation. |
| void OnSetup(const perfetto::DataSourceBase::SetupArgs&) override; |
| void OnStart(const perfetto::DataSourceBase::StartArgs&) override; |
| void OnStop(const perfetto::DataSourceBase::StopArgs&) override; |
| #endif // BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) |
| |
| // Called by the perfetto backend just after incremental state was cleared. |
| void OnIncrementalStateCleared(); |
| |
| private: |
| typedef unsigned int InternalTraceOptions; |
| |
| FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, |
| TraceBufferRingBufferGetReturnChunk); |
| FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, |
| TraceBufferRingBufferHalfIteration); |
| FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, |
| TraceBufferRingBufferFullIteration); |
| FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, TraceBufferVectorReportFull); |
| FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, |
| ConvertTraceConfigToInternalOptions); |
| FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, |
| TraceRecordAsMuchAsPossibleMode); |
| FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, ConfigTraceBufferLimit); |
| |
| friend class base::NoDestructor<TraceLog>; |
| |
| // MemoryDumpProvider implementation. |
| bool OnMemoryDump(const MemoryDumpArgs& args, |
| ProcessMemoryDump* pmd) override; |
| |
| // Enable/disable each category group based on the current mode_, |
| // category_filter_ and event_filters_enabled_. |
| // Enable the category group in the recording mode if category_filter_ matches |
| // the category group, is not null. |
| void UpdateCategoryRegistry(); |
| void UpdateCategoryState(TraceCategory* category); |
| |
| InternalTraceOptions GetInternalOptionsFromTraceConfig( |
| const TraceConfig& config); |
| |
| class OptionalAutoLock; |
| struct RegisteredAsyncObserver; |
| |
| explicit TraceLog(int generation); |
| ~TraceLog() override; |
| void AddMetadataEventsWhileLocked() EXCLUSIVE_LOCKS_REQUIRED(lock_); |
| template <typename T> |
| void AddMetadataEventWhileLocked(PlatformThreadId thread_id, |
| const char* metadata_name, |
| const char* arg_name, |
| const T& value) |
| EXCLUSIVE_LOCKS_REQUIRED(lock_); |
| |
| InternalTraceOptions trace_options() const { |
| return trace_options_.load(std::memory_order_relaxed); |
| } |
| |
| TraceBuffer* trace_buffer() const { return logged_events_.get(); } |
| TraceBuffer* CreateTraceBuffer(); |
| |
| std::string EventToConsoleMessage(char phase, |
| const TimeTicks& timestamp, |
| TraceEvent* trace_event); |
| |
| TraceEvent* AddEventToThreadSharedChunkWhileLocked(TraceEventHandle* handle, |
| bool check_buffer_is_full) |
| EXCLUSIVE_LOCKS_REQUIRED(lock_); |
| void CheckIfBufferIsFullWhileLocked() EXCLUSIVE_LOCKS_REQUIRED(lock_); |
| void SetDisabledWhileLocked(uint8_t modes) EXCLUSIVE_LOCKS_REQUIRED(lock_); |
| |
| TraceEvent* GetEventByHandleInternal(TraceEventHandle handle, |
| OptionalAutoLock* lock); |
| |
| void FlushInternal(const OutputCallback& cb, |
| bool use_worker_thread, |
| bool discard_events); |
| |
| #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) |
| tracing::PerfettoPlatform* GetOrCreatePerfettoPlatform(); |
| void OnTraceData(const char* data, size_t size, bool has_more); |
| #endif // BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) |
| |
| // |generation| is used in the following callbacks to check if the callback |
| // is called for the flush of the current |logged_events_|. |
| void FlushCurrentThread(int generation, bool discard_events); |
| // Usually it runs on a different thread. |
| static void ConvertTraceEventsToTraceFormat( |
| std::unique_ptr<TraceBuffer> logged_events, |
| const TraceLog::OutputCallback& flush_output_callback, |
| const ArgumentFilterPredicate& argument_filter_predicate); |
| void FinishFlush(int generation, bool discard_events); |
| void OnFlushTimeout(int generation, bool discard_events); |
| |
| int generation() const { |
| return generation_.load(std::memory_order_relaxed); |
| } |
| bool CheckGeneration(int generation) const { |
| return generation == this->generation(); |
| } |
| void UseNextTraceBuffer(); |
| |
| TimeTicks OffsetNow() const { |
| // This should be TRACE_TIME_TICKS_NOW but include order makes that hard. |
| return OffsetTimestamp(base::subtle::TimeTicksNowIgnoringOverride()); |
| } |
| TimeTicks OffsetTimestamp(const TimeTicks& timestamp) const { |
| return timestamp - time_offset_; |
| } |
| |
| // Internal representation of trace options since we store the currently used |
| // trace option as an AtomicWord. |
| static const InternalTraceOptions kInternalNone; |
| static const InternalTraceOptions kInternalRecordUntilFull; |
| static const InternalTraceOptions kInternalRecordContinuously; |
| static const InternalTraceOptions kInternalEchoToConsole; |
| static const InternalTraceOptions kInternalRecordAsMuchAsPossible; |
| static const InternalTraceOptions kInternalEnableArgumentFilter; |
| |
| // This lock protects TraceLog member accesses (except for members protected |
| // by thread_info_lock_) from arbitrary threads. |
| mutable Lock lock_; |
| Lock thread_info_lock_; |
| bool enabled_{false}; |
| int num_traces_recorded_{0}; |
| std::unique_ptr<TraceBuffer> logged_events_; |
| std::vector<std::unique_ptr<TraceEvent>> metadata_events_; |
| |
| // The lock protects observers access. |
| mutable Lock observers_lock_; |
| bool dispatching_to_observers_ = false; |
| std::vector<EnabledStateObserver*> enabled_state_observers_ |
| GUARDED_BY(observers_lock_); |
| std::map<AsyncEnabledStateObserver*, RegisteredAsyncObserver> async_observers_ |
| GUARDED_BY(observers_lock_); |
| // Manages ownership of the owned observers. The owned observers will also be |
| // added to |enabled_state_observers_|. |
| std::vector<std::unique_ptr<EnabledStateObserver>> |
| owned_enabled_state_observer_copy_ GUARDED_BY(observers_lock_); |
| std::vector<IncrementalStateObserver*> incremental_state_observers_ |
| GUARDED_BY(observers_lock_); |
| |
| std::unordered_map<int, std::string> process_labels_; |
| int process_sort_index_; |
| std::unordered_map<PlatformThreadId, int> thread_sort_indices_; |
| std::unordered_map<PlatformThreadId, std::string> thread_names_ |
| GUARDED_BY(thread_info_lock_); |
| |
| // The following two maps are used only when ECHO_TO_CONSOLE. |
| std::unordered_map<PlatformThreadId, base::stack<TimeTicks>> |
| thread_event_start_times_ GUARDED_BY(thread_info_lock_); |
| std::unordered_map<std::string, size_t> thread_colors_ |
| GUARDED_BY(thread_info_lock_); |
| |
| TimeTicks buffer_limit_reached_timestamp_; |
| |
| // XORed with TraceID to make it unlikely to collide with other processes. |
| uint64_t process_id_hash_; |
| |
| ProcessId process_id_; |
| |
| TimeDelta time_offset_; |
| |
| std::atomic<InternalTraceOptions> trace_options_; |
| |
| TraceConfig trace_config_; |
| |
| // Contains task runners for the threads that have had at least one event |
| // added into the local event buffer. |
| std::unordered_map<PlatformThreadId, scoped_refptr<SingleThreadTaskRunner>> |
| thread_task_runners_; |
| |
| // For events which can't be added into the thread local buffer, e.g. events |
| // from threads without a message loop. |
| std::unique_ptr<TraceBufferChunk> thread_shared_chunk_; |
| size_t thread_shared_chunk_index_; |
| |
| // Set when asynchronous Flush is in progress. |
| OutputCallback flush_output_callback_; |
| scoped_refptr<SequencedTaskRunner> flush_task_runner_; |
| ArgumentFilterPredicate argument_filter_predicate_; |
| MetadataFilterPredicate metadata_filter_predicate_; |
| bool record_host_app_package_name_{false}; |
| std::atomic<int> generation_; |
| bool use_worker_thread_; |
| std::atomic<AddTraceEventOverrideFunction> add_trace_event_override_{nullptr}; |
| std::atomic<OnFlushFunction> on_flush_override_{nullptr}; |
| std::atomic<UpdateDurationFunction> update_duration_override_{nullptr}; |
| |
| #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) |
| std::unique_ptr<::base::tracing::PerfettoPlatform> perfetto_platform_; |
| std::unique_ptr<perfetto::TracingSession> tracing_session_; |
| perfetto::TraceConfig perfetto_config_; |
| perfetto::DataSourceConfig track_event_config_ GUARDED_BY(track_event_lock_); |
| bool track_event_enabled_ GUARDED_BY(track_event_lock_) = false; |
| mutable Lock track_event_lock_; |
| #if !BUILDFLAG(IS_NACL) |
| std::unique_ptr<perfetto::trace_processor::TraceProcessorStorage> |
| trace_processor_; |
| std::unique_ptr<JsonStringOutputWriter> json_output_writer_; |
| OutputCallback proto_output_callback_; |
| #endif // !BUILDFLAG(IS_NACL) |
| #endif // BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) |
| |
| #if BUILDFLAG(IS_ANDROID) |
| absl::optional<TraceConfig> atrace_startup_config_; |
| #endif |
| }; |
| |
| } // namespace trace_event |
| } // namespace base |
| |
| #endif // BASE_TRACE_EVENT_TRACE_LOG_H_ |