1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #ifndef BASE_DEBUG_TRACE_EVENT_IMPL_H_
7 #define BASE_DEBUG_TRACE_EVENT_IMPL_H_
13 #include "base/atomicops.h"
14 #include "base/callback.h"
15 #include "base/containers/hash_tables.h"
16 #include "base/gtest_prod_util.h"
17 #include "base/memory/ref_counted_memory.h"
18 #include "base/memory/scoped_vector.h"
19 #include "base/observer_list.h"
20 #include "base/strings/string_util.h"
21 #include "base/synchronization/condition_variable.h"
22 #include "base/synchronization/lock.h"
23 #include "base/threading/thread.h"
24 #include "base/threading/thread_local.h"
25 #include "base/timer/timer.h"
27 // Older style trace macros with explicit id and extra data
28 // Only these macros result in publishing data to ETW as currently implemented.
29 #define TRACE_EVENT_BEGIN_ETW(name, id, extra) \
30 base::debug::TraceLog::AddTraceEventEtw( \
31 TRACE_EVENT_PHASE_BEGIN, \
32 name, reinterpret_cast<const void*>(id), extra)
34 #define TRACE_EVENT_END_ETW(name, id, extra) \
35 base::debug::TraceLog::AddTraceEventEtw( \
36 TRACE_EVENT_PHASE_END, \
37 name, reinterpret_cast<const void*>(id), extra)
39 #define TRACE_EVENT_INSTANT_ETW(name, id, extra) \
40 base::debug::TraceLog::AddTraceEventEtw( \
41 TRACE_EVENT_PHASE_INSTANT, \
42 name, reinterpret_cast<const void*>(id), extra)
44 template <typename Type
>
45 struct DefaultSingletonTraits
;
47 #if defined(COMPILER_GCC)
48 namespace BASE_HASH_NAMESPACE
{
50 struct hash
<base::MessageLoop
*> {
51 std::size_t operator()(base::MessageLoop
* value
) const {
52 return reinterpret_cast<std::size_t>(value
);
55 } // BASE_HASH_NAMESPACE
65 // For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided
66 // class must implement this interface.
67 class ConvertableToTraceFormat
{
69 virtual ~ConvertableToTraceFormat() {}
71 // Append the class info to the provided |out| string. The appended
72 // data must be a valid JSON object. Strings must be properly quoted, and
73 // escaped. There is no processing applied to the content after it is
75 virtual void AppendAsTraceFormat(std::string
* out
) const = 0;
78 const int kTraceMaxNumArgs
= 2;
80 // Output records are "Events" and can be obtained via the
81 // OutputCallback whenever the tracing system decides to flush. This
82 // can happen at any time, on any thread, or you can programmatically
83 // force it to happen.
84 class BASE_EXPORT TraceEvent
{
88 unsigned long long as_uint
;
91 const void* as_pointer
;
92 const char* as_string
;
96 TraceEvent(int thread_id
,
98 TimeTicks thread_timestamp
,
100 const unsigned char* category_group_enabled
,
102 unsigned long long id
,
104 const char** arg_names
,
105 const unsigned char* arg_types
,
106 const unsigned long long* arg_values
,
107 scoped_ptr
<ConvertableToTraceFormat
> convertable_values
[],
108 unsigned char flags
);
109 TraceEvent(const TraceEvent
& other
);
110 TraceEvent
& operator=(const TraceEvent
& other
);
113 // Serialize event data to JSON
114 static void AppendEventsAsJSON(const std::vector
<TraceEvent
>& events
,
118 void AppendAsJSON(std::string
* out
) const;
119 void AppendPrettyPrinted(std::ostringstream
* out
) const;
121 static void AppendValueAsJSON(unsigned char type
,
125 TimeTicks
timestamp() const { return timestamp_
; }
126 TimeTicks
thread_timestamp() const { return thread_timestamp_
; }
127 char phase() const { return phase_
; }
128 int thread_id() const { return thread_id_
; }
130 // Exposed for unittesting:
132 const base::RefCountedString
* parameter_copy_storage() const {
133 return parameter_copy_storage_
.get();
136 const unsigned char* category_group_enabled() const {
137 return category_group_enabled_
;
140 const char* name() const { return name_
; }
143 // Note: these are ordered by size (largest first) for optimal packing.
144 TimeTicks timestamp_
;
145 TimeTicks thread_timestamp_
;
146 // id_ can be used to store phase-specific data.
147 unsigned long long id_
;
148 TraceValue arg_values_
[kTraceMaxNumArgs
];
149 const char* arg_names_
[kTraceMaxNumArgs
];
150 scoped_ptr
<ConvertableToTraceFormat
> convertable_values_
[kTraceMaxNumArgs
];
151 const unsigned char* category_group_enabled_
;
153 scoped_refptr
<base::RefCountedString
> parameter_copy_storage_
;
156 unsigned char flags_
;
157 unsigned char arg_types_
[kTraceMaxNumArgs
];
160 // TraceBuffer holds the events as they are collected.
161 class BASE_EXPORT TraceBuffer
{
163 virtual ~TraceBuffer() {}
165 virtual void AddEvent(const TraceEvent
& event
) = 0;
166 virtual bool HasMoreEvents() const = 0;
167 virtual const TraceEvent
& NextEvent() = 0;
168 virtual bool IsFull() const = 0;
169 virtual size_t CountEnabledByName(const unsigned char* category
,
170 const std::string
& event_name
) const = 0;
171 virtual size_t Size() const = 0;
172 virtual size_t Capacity() const = 0;
173 virtual const TraceEvent
& GetEventAt(size_t index
) const = 0;
176 // TraceResultBuffer collects and converts trace fragments returned by TraceLog
178 class BASE_EXPORT TraceResultBuffer
{
180 typedef base::Callback
<void(const std::string
&)> OutputCallback
;
182 // If you don't need to stream JSON chunks out efficiently, and just want to
183 // get a complete JSON string after calling Finish, use this struct to collect
184 // JSON trace output.
185 struct BASE_EXPORT SimpleOutput
{
186 OutputCallback
GetCallback();
187 void Append(const std::string
& json_string
);
189 // Do what you want with the json_output_ string after calling
190 // TraceResultBuffer::Finish.
191 std::string json_output
;
195 ~TraceResultBuffer();
197 // Set callback. The callback will be called during Start with the initial
198 // JSON output and during AddFragment and Finish with following JSON output
199 // chunks. The callback target must live past the last calls to
200 // TraceResultBuffer::Start/AddFragment/Finish.
201 void SetOutputCallback(const OutputCallback
& json_chunk_callback
);
203 // Start JSON output. This resets all internal state, so you can reuse
204 // the TraceResultBuffer by calling Start.
207 // Call AddFragment 0 or more times to add trace fragments from TraceLog.
208 void AddFragment(const std::string
& trace_fragment
);
210 // When all fragments have been added, call Finish to complete the JSON
215 OutputCallback output_callback_
;
219 class BASE_EXPORT CategoryFilter
{
221 // The default category filter, used when none is provided.
222 // Allows all categories through, except if they end in the suffix 'Debug' or
224 static const char* kDefaultCategoryFilterString
;
226 // |filter_string| is a comma-delimited list of category wildcards.
227 // A category can have an optional '-' prefix to make it an excluded category.
228 // All the same rules apply above, so for example, having both included and
229 // excluded categories in the same list would not be supported.
231 // Example: CategoryFilter"test_MyTest*");
232 // Example: CategoryFilter("test_MyTest*,test_OtherStuff");
233 // Example: CategoryFilter("-excluded_category1,-excluded_category2");
234 // Example: CategoryFilter("-*,webkit"); would disable everything but webkit.
235 // Example: CategoryFilter("-webkit"); would enable everything but webkit.
236 explicit CategoryFilter(const std::string
& filter_string
);
238 CategoryFilter(const CategoryFilter
& cf
);
242 CategoryFilter
& operator=(const CategoryFilter
& rhs
);
244 // Writes the string representation of the CategoryFilter. This is a comma
245 // separated string, similar in nature to the one used to determine
246 // enabled/disabled category patterns, except here there is an arbitrary
247 // order, included categories go first, then excluded categories. Excluded
248 // categories are distinguished from included categories by the prefix '-'.
249 std::string
ToString() const;
251 // Determines whether category group would be enabled or
252 // disabled by this category filter.
253 bool IsCategoryGroupEnabled(const char* category_group
) const;
255 // Merges nested_filter with the current CategoryFilter
256 void Merge(const CategoryFilter
& nested_filter
);
258 // Clears both included/excluded pattern lists. This would be equivalent to
259 // creating a CategoryFilter with an empty string, through the constructor.
260 // i.e: CategoryFilter("").
262 // When using an empty filter, all categories are considered included as we
263 // are not excluding anything.
267 FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture
, CategoryFilter
);
269 static bool IsEmptyOrContainsLeadingOrTrailingWhitespace(
270 const std::string
& str
);
272 typedef std::vector
<std::string
> StringList
;
274 void Initialize(const std::string
& filter_string
);
275 void WriteString(const StringList
& values
,
277 bool included
) const;
278 bool HasIncludedPatterns() const;
280 bool DoesCategoryGroupContainCategory(const char* category_group
,
281 const char* category
) const;
283 StringList included_
;
284 StringList disabled_
;
285 StringList excluded_
;
288 class TraceSamplingThread
;
290 class BASE_EXPORT TraceLog
{
292 // Notification is a mask of one or more of the following events.
294 // The trace buffer does not flush dynamically, so when it fills up,
295 // subsequent trace events will be dropped. This callback is generated when
296 // the trace buffer is full. The callback must be thread safe.
297 TRACE_BUFFER_FULL
= 1 << 0,
298 // A subscribed trace-event occurred.
299 EVENT_WATCH_NOTIFICATION
= 1 << 1
302 // Options determines how the trace buffer stores data.
304 // Record until the trace buffer is full.
305 RECORD_UNTIL_FULL
= 1 << 0,
307 // Record until the user ends the trace. The trace buffer is a fixed size
308 // and we use it as a ring buffer during recording.
309 RECORD_CONTINUOUSLY
= 1 << 1,
311 // Enable the sampling profiler.
312 ENABLE_SAMPLING
= 1 << 2,
314 // Echo to console. Events are discarded.
315 ECHO_TO_CONSOLE
= 1 << 3,
318 static TraceLog
* GetInstance();
320 // Convert the given string to trace options. Defaults to RECORD_UNTIL_FULL if
321 // the string does not provide valid options.
322 static Options
TraceOptionsFromString(const std::string
& str
);
324 // Get set of known category groups. This can change as new code paths are
325 // reached. The known category groups are inserted into |category_groups|.
326 void GetKnownCategoryGroups(std::vector
<std::string
>* category_groups
);
328 // Retrieves the current CategoryFilter.
329 const CategoryFilter
& GetCurrentCategoryFilter();
331 Options
trace_options() const {
332 return static_cast<Options
>(subtle::NoBarrier_Load(&trace_options_
));
335 // Enables tracing. See CategoryFilter comments for details
336 // on how to control what categories will be traced.
337 void SetEnabled(const CategoryFilter
& category_filter
, Options options
);
339 // Disable tracing for all categories.
341 bool IsEnabled() { return !!enable_count_
; }
343 // The number of times we have begun recording traces. If tracing is off,
344 // returns -1. If tracing is on, then it returns the number of times we have
345 // recorded a trace. By watching for this number to increment, you can
346 // passively discover when a new trace has begun. This is then used to
347 // implement the TRACE_EVENT_IS_NEW_TRACE() primitive.
348 int GetNumTracesRecorded();
350 #if defined(OS_ANDROID)
355 // Enabled state listeners give a callback when tracing is enabled or
356 // disabled. This can be used to tie into other library's tracing systems
358 class EnabledStateObserver
{
360 // Called just after the tracing system becomes enabled, outside of the
361 // |lock_|. TraceLog::IsEnabled() is true at this point.
362 virtual void OnTraceLogEnabled() = 0;
364 // Called just after the tracing system disables, outside of the |lock_|.
365 // TraceLog::IsEnabled() is false at this point.
366 virtual void OnTraceLogDisabled() = 0;
368 void AddEnabledStateObserver(EnabledStateObserver
* listener
);
369 void RemoveEnabledStateObserver(EnabledStateObserver
* listener
);
370 bool HasEnabledStateObserver(EnabledStateObserver
* listener
) const;
372 float GetBufferPercentFull() const;
374 // Set the thread-safe notification callback. The callback can occur at any
375 // time and from any thread. WARNING: It is possible for the previously set
376 // callback to be called during OR AFTER a call to SetNotificationCallback.
377 // Therefore, the target of the callback must either be a global function,
378 // ref-counted object or a LazyInstance with Leaky traits (or equivalent).
379 typedef base::Callback
<void(int)> NotificationCallback
;
380 void SetNotificationCallback(const NotificationCallback
& cb
);
382 // Not using base::Callback because of its limited by 7 parameters.
383 // Also, using primitive type allows directly passing callback from WebCore.
384 // WARNING: It is possible for the previously set callback to be called
385 // after a call to SetEventCallback() that replaces or clears the callback.
386 // This callback may be invoked on any thread.
387 typedef void (*EventCallback
)(char phase
,
388 const unsigned char* category_group_enabled
,
390 unsigned long long id
,
392 const char* const arg_names
[],
393 const unsigned char arg_types
[],
394 const unsigned long long arg_values
[],
395 unsigned char flags
);
396 void SetEventCallback(EventCallback cb
);
398 // Flush all collected events to the given output callback. The callback will
399 // be called one or more times either synchronously or asynchronously from
400 // the current thread with IPC-bite-size chunks. The string format is
401 // undefined. Use TraceResultBuffer to convert one or more trace strings to
402 // JSON. The callback can be null if the caller doesn't want any data.
403 // Due to the implementation of thread-local buffers, flush can't be
404 // done when tracing is enabled. If called when tracing is enabled, the
405 // callback will be called directly with (empty_string, false) to indicate
406 // the end of this unsuccessful flush.
407 typedef base::Callback
<void(const scoped_refptr
<base::RefCountedString
>&,
408 bool has_more_events
)> OutputCallback
;
409 void Flush(const OutputCallback
& cb
);
411 // Called by TRACE_EVENT* macros, don't call this directly.
412 // The name parameter is a category group for example:
413 // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent")
414 static const unsigned char* GetCategoryGroupEnabled(const char* name
);
415 static const char* GetCategoryGroupName(
416 const unsigned char* category_group_enabled
);
418 // Called by TRACE_EVENT* macros, don't call this directly.
419 // If |copy| is set, |name|, |arg_name1| and |arg_name2| will be deep copied
420 // into the event; see "Memory scoping note" and TRACE_EVENT_COPY_XXX above.
421 void AddTraceEvent(char phase
,
422 const unsigned char* category_group_enabled
,
424 unsigned long long id
,
426 const char** arg_names
,
427 const unsigned char* arg_types
,
428 const unsigned long long* arg_values
,
429 scoped_ptr
<ConvertableToTraceFormat
> convertable_values
[],
430 unsigned char flags
);
431 void AddTraceEventWithThreadIdAndTimestamp(
433 const unsigned char* category_group_enabled
,
435 unsigned long long id
,
437 const TimeTicks
& timestamp
,
439 const char** arg_names
,
440 const unsigned char* arg_types
,
441 const unsigned long long* arg_values
,
442 scoped_ptr
<ConvertableToTraceFormat
> convertable_values
[],
443 unsigned char flags
);
444 static void AddTraceEventEtw(char phase
,
445 const char* category_group
,
448 static void AddTraceEventEtw(char phase
,
449 const char* category_group
,
451 const std::string
& extra
);
453 // For every matching event, a notification will be fired. NOTE: the
454 // notification will fire for each matching event that has already occurred
455 // since tracing was started (including before tracing if the process was
456 // started with tracing turned on).
457 void SetWatchEvent(const std::string
& category_name
,
458 const std::string
& event_name
);
459 // Cancel the watch event. If tracing is enabled, this may race with the
460 // watch event notification firing.
461 void CancelWatchEvent();
463 int process_id() const { return process_id_
; }
465 // Exposed for unittesting:
467 void InstallWaitableEventForSamplingTesting(WaitableEvent
* waitable_event
);
469 // Allows deleting our singleton instance.
470 static void DeleteForTesting();
472 // Allow tests to inspect TraceEvents.
473 size_t GetEventsSize() const { return logged_events_
->Size(); }
474 const TraceEvent
& GetEventAt(size_t index
) const {
475 return logged_events_
->GetEventAt(index
);
478 void SetProcessID(int process_id
);
480 // Process sort indices, if set, override the order of a process will appear
481 // relative to other processes in the trace viewer. Processes are sorted first
482 // on their sort index, ascending, then by their name, and then tid.
483 void SetProcessSortIndex(int sort_index
);
485 // Sets the name of the process.
486 void SetProcessName(const std::string
& process_name
);
488 // Processes can have labels in addition to their names. Use labels, for
489 // instance, to list out the web page titles that a process is handling.
490 void UpdateProcessLabel(int label_id
, const std::string
& current_label
);
491 void RemoveProcessLabel(int label_id
);
493 // Thread sort indices, if set, override the order of a thread will appear
494 // within its process in the trace viewer. Threads are sorted first on their
495 // sort index, ascending, then by their name, and then tid.
496 void SetThreadSortIndex(PlatformThreadId
, int sort_index
);
498 // Allow setting an offset between the current TimeTicks time and the time
499 // that should be reported.
500 void SetTimeOffset(TimeDelta offset
);
502 size_t GetObserverCountForTest() const;
505 // This allows constructor and destructor to be private and usable only
506 // by the Singleton class.
507 friend struct DefaultSingletonTraits
<TraceLog
>;
509 // Enable/disable each category group based on the current enable_count_
510 // and category_filter_. Disable the category group if enabled_count_ is 0, or
511 // if the category group contains a category that matches an included category
512 // pattern, that category group will be enabled.
513 // On Android, ATRACE_ENABLED flag will be applied if atrace is started.
514 void UpdateCategoryGroupEnabledFlags();
515 void UpdateCategoryGroupEnabledFlag(int category_index
);
517 static void SetCategoryGroupEnabled(int category_index
, bool enabled
);
518 static bool IsCategoryGroupEnabled(
519 const unsigned char* category_group_enabled
);
521 // The pointer returned from GetCategoryGroupEnabledInternal() points to a
522 // value with zero or more of the following bits. Used in this class only.
523 // The TRACE_EVENT macros should only use the value as a bool.
524 enum CategoryGroupEnabledFlags
{
525 // Normal enabled flag for category groups enabled with Enable().
526 CATEGORY_GROUP_ENABLED
= 1 << 0,
527 // On Android if ATrace is enabled, all categories will have this bit.
528 // Not used on other platforms.
529 ATRACE_ENABLED
= 1 << 1
532 // Helper class for managing notification_thread_count_ and running
533 // notification callbacks. This is very similar to a reader-writer lock, but
534 // shares the lock with TraceLog and manages the notification flags.
535 class NotificationHelper
{
537 inline explicit NotificationHelper(TraceLog
* trace_log
);
538 inline ~NotificationHelper();
540 // Called only while TraceLog::lock_ is held. This ORs the given
541 // notification with any existing notifications.
542 inline void AddNotificationWhileLocked(int notification
);
544 // Called only while TraceLog::lock_ is NOT held. If there are any pending
545 // notifications from previous calls to AddNotificationWhileLocked, this
546 // will call the NotificationCallback.
547 inline void SendNotificationIfAny();
550 TraceLog
* trace_log_
;
551 NotificationCallback callback_copy_
;
555 class ThreadLocalEventBuffer
;
559 const unsigned char* GetCategoryGroupEnabledInternal(const char* name
);
560 void AddMetadataEvents();
562 #if defined(OS_ANDROID)
563 void SendToATrace(char phase
,
564 const char* category_group
,
566 unsigned long long id
,
568 const char** arg_names
,
569 const unsigned char* arg_types
,
570 const unsigned long long* arg_values
,
571 scoped_ptr
<ConvertableToTraceFormat
> convertable_values
[],
572 unsigned char flags
);
573 static void ApplyATraceEnabledFlag(unsigned char* category_group_enabled
);
576 TraceBuffer
* GetTraceBuffer();
578 void AddEventToMainBufferWhileLocked(const TraceEvent
& trace_event
);
579 void CheckIfBufferIsFullWhileLocked(NotificationHelper
* notifier
);
580 // |flush_count| is used in the following callbacks to check if the callback
581 // is called for the current flush.
582 void FlushCurrentThread(int flush_count
);
583 void FinishFlush(int flush_count
);
584 void OnFlushTimeout(int flush_count
);
586 // This lock protects TraceLog member accesses from arbitrary threads.
590 int num_traces_recorded_
;
591 subtle::AtomicWord
/* bool */ buffer_is_full_
;
592 NotificationCallback notification_callback_
;
593 scoped_ptr
<TraceBuffer
> logged_events_
;
594 subtle::AtomicWord
/* EventCallback */ event_callback_
;
595 bool dispatching_to_observer_list_
;
596 std::vector
<EnabledStateObserver
*> enabled_state_observer_list_
;
598 std::string process_name_
;
599 base::hash_map
<int, std::string
> process_labels_
;
600 int process_sort_index_
;
601 base::hash_map
<int, int> thread_sort_indices_
;
602 base::hash_map
<int, std::string
> thread_names_
;
604 // The following two maps are used only when ECHO_TO_CONSOLE.
605 base::hash_map
<int, std::stack
<TimeTicks
> > thread_event_start_times_
;
606 base::hash_map
<std::string
, int> thread_colors_
;
608 // XORed with TraceID to make it unlikely to collide with other processes.
609 unsigned long long process_id_hash_
;
613 TimeDelta time_offset_
;
615 // Allow tests to wake up when certain events occur.
616 subtle::AtomicWord
/* const unsigned char* */ watch_category_
;
617 std::string watch_event_name_
;
619 subtle::AtomicWord
/* Options */ trace_options_
;
621 // Sampling thread handles.
622 scoped_ptr
<TraceSamplingThread
> sampling_thread_
;
623 PlatformThreadHandle sampling_thread_handle_
;
625 CategoryFilter category_filter_
;
627 ThreadLocalPointer
<ThreadLocalEventBuffer
> thread_local_event_buffer_
;
629 // Contains the message loops of threads that have had at least one event
630 // added into the local event buffer. Not using MessageLoopProxy because we
631 // need to know the life time of the message loops.
632 base::hash_set
<MessageLoop
*> thread_message_loops_
;
634 // Set when asynchronous Flush is in progress.
635 OutputCallback flush_output_callback_
;
636 scoped_refptr
<MessageLoopProxy
> flush_message_loop_proxy_
;
639 DISALLOW_COPY_AND_ASSIGN(TraceLog
);
645 #endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_