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_
12 #include "base/callback.h"
13 #include "base/hash_tables.h"
14 #include "base/memory/ref_counted_memory.h"
15 #include "base/memory/scoped_vector.h"
16 #include "base/observer_list.h"
17 #include "base/string_util.h"
18 #include "base/synchronization/condition_variable.h"
19 #include "base/synchronization/lock.h"
20 #include "base/threading/thread.h"
21 #include "base/timer.h"
23 // Older style trace macros with explicit id and extra data
24 // Only these macros result in publishing data to ETW as currently implemented.
25 #define TRACE_EVENT_BEGIN_ETW(name, id, extra) \
26 base::debug::TraceLog::AddTraceEventEtw( \
27 TRACE_EVENT_PHASE_BEGIN, \
28 name, reinterpret_cast<const void*>(id), extra)
30 #define TRACE_EVENT_END_ETW(name, id, extra) \
31 base::debug::TraceLog::AddTraceEventEtw( \
32 TRACE_EVENT_PHASE_END, \
33 name, reinterpret_cast<const void*>(id), extra)
35 #define TRACE_EVENT_INSTANT_ETW(name, id, extra) \
36 base::debug::TraceLog::AddTraceEventEtw( \
37 TRACE_EVENT_PHASE_INSTANT, \
38 name, reinterpret_cast<const void*>(id), extra)
40 template <typename Type
>
41 struct StaticMemorySingletonTraits
;
49 // For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided
50 // class must implement this interface.
51 class ConvertableToTraceFormat
{
53 virtual ~ConvertableToTraceFormat() {}
55 // Append the class info to the provided |out| string. The appended
56 // data must be a valid JSON object. Strings must be propertly quoted, and
57 // escaped. There is no processing applied to the content after it is
59 virtual void AppendAsTraceFormat(std::string
* out
) const = 0;
62 const int kTraceMaxNumArgs
= 2;
64 // Output records are "Events" and can be obtained via the
65 // OutputCallback whenever the tracing system decides to flush. This
66 // can happen at any time, on any thread, or you can programatically
67 // force it to happen.
68 class BASE_EXPORT TraceEvent
{
72 unsigned long long as_uint
;
75 const void* as_pointer
;
76 const char* as_string
;
80 TraceEvent(int thread_id
,
83 const unsigned char* category_enabled
,
85 unsigned long long id
,
87 const char** arg_names
,
88 const unsigned char* arg_types
,
89 const unsigned long long* arg_values
,
90 scoped_ptr
<ConvertableToTraceFormat
> convertable_values
[],
92 TraceEvent(const TraceEvent
& other
);
93 TraceEvent
& operator=(const TraceEvent
& other
);
96 // Serialize event data to JSON
97 static void AppendEventsAsJSON(const std::vector
<TraceEvent
>& events
,
101 void AppendAsJSON(std::string
* out
) const;
103 static void AppendValueAsJSON(unsigned char type
,
107 TimeTicks
timestamp() const { return timestamp_
; }
109 // Exposed for unittesting:
111 const base::RefCountedString
* parameter_copy_storage() const {
112 return parameter_copy_storage_
.get();
115 const unsigned char* category_enabled() const { return category_enabled_
; }
116 const char* name() const { return name_
; }
119 // Note: these are ordered by size (largest first) for optimal packing.
120 TimeTicks timestamp_
;
121 // id_ can be used to store phase-specific data.
122 unsigned long long id_
;
123 TraceValue arg_values_
[kTraceMaxNumArgs
];
124 const char* arg_names_
[kTraceMaxNumArgs
];
125 scoped_ptr
<ConvertableToTraceFormat
> convertable_values_
[kTraceMaxNumArgs
];
126 const unsigned char* category_enabled_
;
128 scoped_refptr
<base::RefCountedString
> parameter_copy_storage_
;
131 unsigned char flags_
;
132 unsigned char arg_types_
[kTraceMaxNumArgs
];
135 // TraceBuffer holds the events as they are collected.
136 class BASE_EXPORT TraceBuffer
{
138 virtual ~TraceBuffer() {}
140 virtual void AddEvent(const TraceEvent
& event
) = 0;
141 virtual bool HasMoreEvents() const = 0;
142 virtual const TraceEvent
& NextEvent() = 0;
143 virtual bool IsFull() const = 0;
144 virtual size_t CountEnabledByName(const unsigned char* category
,
145 const std::string
& event_name
) const = 0;
146 virtual size_t Size() const = 0;
147 virtual const TraceEvent
& GetEventAt(size_t index
) const = 0;
150 // TraceResultBuffer collects and converts trace fragments returned by TraceLog
152 class BASE_EXPORT TraceResultBuffer
{
154 typedef base::Callback
<void(const std::string
&)> OutputCallback
;
156 // If you don't need to stream JSON chunks out efficiently, and just want to
157 // get a complete JSON string after calling Finish, use this struct to collect
158 // JSON trace output.
159 struct BASE_EXPORT SimpleOutput
{
160 OutputCallback
GetCallback();
161 void Append(const std::string
& json_string
);
163 // Do what you want with the json_output_ string after calling
164 // TraceResultBuffer::Finish.
165 std::string json_output
;
169 ~TraceResultBuffer();
171 // Set callback. The callback will be called during Start with the initial
172 // JSON output and during AddFragment and Finish with following JSON output
173 // chunks. The callback target must live past the last calls to
174 // TraceResultBuffer::Start/AddFragment/Finish.
175 void SetOutputCallback(const OutputCallback
& json_chunk_callback
);
177 // Start JSON output. This resets all internal state, so you can reuse
178 // the TraceResultBuffer by calling Start.
181 // Call AddFragment 0 or more times to add trace fragments from TraceLog.
182 void AddFragment(const std::string
& trace_fragment
);
184 // When all fragments have been added, call Finish to complete the JSON
189 OutputCallback output_callback_
;
193 class TraceSamplingThread
;
195 class BASE_EXPORT TraceLog
{
197 // Notification is a mask of one or more of the following events.
199 // The trace buffer does not flush dynamically, so when it fills up,
200 // subsequent trace events will be dropped. This callback is generated when
201 // the trace buffer is full. The callback must be thread safe.
202 TRACE_BUFFER_FULL
= 1 << 0,
203 // A subscribed trace-event occurred.
204 EVENT_WATCH_NOTIFICATION
= 1 << 1
207 // Options determines how the trace buffer stores data.
209 // Record until the trace buffer is full.
210 RECORD_UNTIL_FULL
= 1 << 0,
212 // Record until the user ends the trace. The trace buffer is a fixed size
213 // and we use it as a ring buffer during recording.
214 RECORD_CONTINUOUSLY
= 1 << 1,
216 // Enable the sampling profiler.
217 ENABLE_SAMPLING
= 1 << 2
220 static TraceLog
* GetInstance();
222 // Convert the given string to trace options. Defaults to RECORD_UNTIL_FULL if
223 // the string does not provide valid options.
224 static Options
TraceOptionsFromString(const std::string
& str
);
226 // Get set of known categories. This can change as new code paths are reached.
227 // The known categories are inserted into |categories|.
228 void GetKnownCategories(std::vector
<std::string
>* categories
);
230 // Enable tracing for provided list of categories. If tracing is already
231 // enabled, this method does nothing -- changing categories during trace is
233 // If both included_categories and excluded_categories are empty,
234 // all categories are traced.
235 // Else if included_categories is non-empty, only those are traced.
236 // Else if excluded_categories is non-empty, everything but those are traced.
237 // Wildcards * and ? are supported (see MatchPattern in string_util.h).
238 void SetEnabled(const std::vector
<std::string
>& included_categories
,
239 const std::vector
<std::string
>& excluded_categories
,
242 // |categories| is a comma-delimited list of category wildcards.
243 // A category can have an optional '-' prefix to make it an excluded category.
244 // All the same rules apply above, so for example, having both included and
245 // excluded categories in the same list would not be supported.
247 // Example: SetEnabled("test_MyTest*");
248 // Example: SetEnabled("test_MyTest*,test_OtherStuff");
249 // Example: SetEnabled("-excluded_category1,-excluded_category2");
250 void SetEnabled(const std::string
& categories
, Options options
);
252 // Retieves the categories set via a prior call to SetEnabled(). Only
253 // meaningful if |IsEnabled()| is true.
254 void GetEnabledTraceCategories(std::vector
<std::string
>* included_out
,
255 std::vector
<std::string
>* excluded_out
);
257 Options
trace_options() const { return trace_options_
; }
259 // Disable tracing for all categories.
261 // Helper method to enable/disable tracing for all categories.
262 void SetEnabled(bool enabled
, Options options
);
263 bool IsEnabled() { return !!enable_count_
; }
265 #if defined(OS_ANDROID)
270 // Enabled state listeners give a callback when tracing is enabled or
271 // disabled. This can be used to tie into other library's tracing systems
273 class EnabledStateChangedObserver
{
275 // Called just before the tracing system becomes
276 // enabled. TraceLog::IsEnabled will return false at this point and trace
277 // macros and methods called within the observer will deadlock.
278 virtual void OnTraceLogWillEnable() { }
280 // Called just before the tracing system disables. TraceLog::IsEnabled is
281 // still false at this point TRACE macros will still be capturing
282 // data. However, trace macros and methods called within the observer will
284 virtual void OnTraceLogWillDisable() { }
286 void AddEnabledStateObserver(EnabledStateChangedObserver
* listener
);
287 void RemoveEnabledStateObserver(EnabledStateChangedObserver
* listener
);
289 float GetBufferPercentFull() const;
291 // Set the thread-safe notification callback. The callback can occur at any
292 // time and from any thread. WARNING: It is possible for the previously set
293 // callback to be called during OR AFTER a call to SetNotificationCallback.
294 // Therefore, the target of the callback must either be a global function,
295 // ref-counted object or a LazyInstance with Leaky traits (or equivalent).
296 typedef base::Callback
<void(int)> NotificationCallback
;
297 void SetNotificationCallback(const NotificationCallback
& cb
);
299 // Not using base::Callback because of its limited by 7 parameteters.
300 // Also, using primitive type allows directly passsing callback from WebCore.
301 // WARNING: It is possible for the previously set callback to be called
302 // after a call to SetEventCallback() that replaces or clears the callback.
303 // This callback may be invoked on any thread.
304 typedef void (*EventCallback
)(char phase
,
305 const unsigned char* category_enabled
,
307 unsigned long long id
,
309 const char* const arg_names
[],
310 const unsigned char arg_types
[],
311 const unsigned long long arg_values
[],
312 unsigned char flags
);
313 void SetEventCallback(EventCallback cb
);
315 // Flush all collected events to the given output callback. The callback will
316 // be called one or more times with IPC-bite-size chunks. The string format is
317 // undefined. Use TraceResultBuffer to convert one or more trace strings to
319 typedef base::Callback
<void(const scoped_refptr
<base::RefCountedString
>&)>
321 void Flush(const OutputCallback
& cb
);
323 // Called by TRACE_EVENT* macros, don't call this directly.
324 static const unsigned char* GetCategoryEnabled(const char* name
);
325 static const char* GetCategoryName(const unsigned char* category_enabled
);
327 // Called by TRACE_EVENT* macros, don't call this directly.
328 // If |copy| is set, |name|, |arg_name1| and |arg_name2| will be deep copied
329 // into the event; see "Memory scoping note" and TRACE_EVENT_COPY_XXX above.
330 void AddTraceEvent(char phase
,
331 const unsigned char* category_enabled
,
333 unsigned long long id
,
335 const char** arg_names
,
336 const unsigned char* arg_types
,
337 const unsigned long long* arg_values
,
338 scoped_ptr
<ConvertableToTraceFormat
> convertable_values
[],
339 unsigned char flags
);
340 void AddTraceEventWithThreadIdAndTimestamp(
342 const unsigned char* category_enabled
,
344 unsigned long long id
,
346 const TimeTicks
& timestamp
,
348 const char** arg_names
,
349 const unsigned char* arg_types
,
350 const unsigned long long* arg_values
,
351 scoped_ptr
<ConvertableToTraceFormat
> convertable_values
[],
352 unsigned char flags
);
353 static void AddTraceEventEtw(char phase
,
357 static void AddTraceEventEtw(char phase
,
360 const std::string
& extra
);
362 // For every matching event, a notification will be fired. NOTE: the
363 // notification will fire for each matching event that has already occurred
364 // since tracing was started (including before tracing if the process was
365 // started with tracing turned on).
366 void SetWatchEvent(const std::string
& category_name
,
367 const std::string
& event_name
);
368 // Cancel the watch event. If tracing is enabled, this may race with the
369 // watch event notification firing.
370 void CancelWatchEvent();
372 int process_id() const { return process_id_
; }
374 // Exposed for unittesting:
376 void InstallWaitableEventForSamplingTesting(WaitableEvent
* waitable_event
);
378 // Allows deleting our singleton instance.
379 static void DeleteForTesting();
381 // Allows resurrecting our singleton instance post-AtExit processing.
382 static void Resurrect();
384 // Allow tests to inspect TraceEvents.
385 size_t GetEventsSize() const { return logged_events_
->Size(); }
386 const TraceEvent
& GetEventAt(size_t index
) const {
387 return logged_events_
->GetEventAt(index
);
390 void SetProcessID(int process_id
);
392 // Allow setting an offset between the current TimeTicks time and the time
393 // that should be reported.
394 void SetTimeOffset(TimeDelta offset
);
397 // This allows constructor and destructor to be private and usable only
398 // by the Singleton class.
399 friend struct StaticMemorySingletonTraits
<TraceLog
>;
401 // The pointer returned from GetCategoryEnabledInternal() points to a value
402 // with zero or more of the following bits. Used in this class only.
403 // The TRACE_EVENT macros should only use the value as a bool.
404 enum CategoryEnabledFlags
{
405 // Normal enabled flag for categories enabled with Enable().
406 CATEGORY_ENABLED
= 1 << 0,
407 // On Android if ATrace is enabled, all categories will have this bit.
408 // Not used on other platforms.
409 ATRACE_ENABLED
= 1 << 1
412 // Helper class for managing notification_thread_count_ and running
413 // notification callbacks. This is very similar to a reader-writer lock, but
414 // shares the lock with TraceLog and manages the notification flags.
415 class NotificationHelper
{
417 inline explicit NotificationHelper(TraceLog
* trace_log
);
418 inline ~NotificationHelper();
420 // Called only while TraceLog::lock_ is held. This ORs the given
421 // notification with any existing notifcations.
422 inline void AddNotificationWhileLocked(int notification
);
424 // Called only while TraceLog::lock_ is NOT held. If there are any pending
425 // notifications from previous calls to AddNotificationWhileLocked, this
426 // will call the NotificationCallback.
427 inline void SendNotificationIfAny();
430 TraceLog
* trace_log_
;
431 NotificationCallback callback_copy_
;
437 const unsigned char* GetCategoryEnabledInternal(const char* name
);
438 void AddThreadNameMetadataEvents();
440 #if defined(OS_ANDROID)
441 void SendToATrace(char phase
,
442 const char* category
,
444 unsigned long long id
,
446 const char** arg_names
,
447 const unsigned char* arg_types
,
448 const unsigned long long* arg_values
,
449 unsigned char flags
);
450 static void ApplyATraceEnabledFlag(unsigned char* category_enabled
);
453 TraceBuffer
* GetTraceBuffer();
455 // TODO(nduca): switch to per-thread trace buffers to reduce thread
457 // This lock protects TraceLog member accesses from arbitrary threads.
460 NotificationCallback notification_callback_
;
461 scoped_ptr
<TraceBuffer
> logged_events_
;
462 EventCallback event_callback_
;
463 std::vector
<std::string
> included_categories_
;
464 std::vector
<std::string
> excluded_categories_
;
465 bool dispatching_to_observer_list_
;
466 ObserverList
<EnabledStateChangedObserver
> enabled_state_observer_list_
;
468 base::hash_map
<int, std::string
> thread_names_
;
470 // XORed with TraceID to make it unlikely to collide with other processes.
471 unsigned long long process_id_hash_
;
475 TimeDelta time_offset_
;
477 // Allow tests to wake up when certain events occur.
478 const unsigned char* watch_category_
;
479 std::string watch_event_name_
;
481 Options trace_options_
;
483 // Sampling thread handles.
484 scoped_ptr
<TraceSamplingThread
> sampling_thread_
;
485 PlatformThreadHandle sampling_thread_handle_
;
487 DISALLOW_COPY_AND_ASSIGN(TraceLog
);
493 #endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_