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_
9 #include "build/build_config.h"
14 #include "base/callback.h"
15 #include "base/hash_tables.h"
16 #include "base/memory/ref_counted_memory.h"
17 #include "base/observer_list.h"
18 #include "base/string_util.h"
19 #include "base/synchronization/condition_variable.h"
20 #include "base/synchronization/lock.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
;
47 const int kTraceMaxNumArgs
= 2;
49 // Output records are "Events" and can be obtained via the
50 // OutputCallback whenever the tracing system decides to flush. This
51 // can happen at any time, on any thread, or you can programatically
52 // force it to happen.
53 class BASE_EXPORT TraceEvent
{
57 unsigned long long as_uint
;
60 const void* as_pointer
;
61 const char* as_string
;
65 TraceEvent(int thread_id
,
68 const unsigned char* category_enabled
,
70 unsigned long long id
,
72 const char** arg_names
,
73 const unsigned char* arg_types
,
74 const unsigned long long* arg_values
,
78 // Serialize event data to JSON
79 static void AppendEventsAsJSON(const std::vector
<TraceEvent
>& events
,
83 void AppendAsJSON(std::string
* out
) const;
85 static void AppendValueAsJSON(unsigned char type
,
89 TimeTicks
timestamp() const { return timestamp_
; }
91 // Exposed for unittesting:
93 const base::RefCountedString
* parameter_copy_storage() const {
94 return parameter_copy_storage_
.get();
97 const unsigned char* category_enabled() const { return category_enabled_
; }
98 const char* name() const { return name_
; }
101 // Note: these are ordered by size (largest first) for optimal packing.
102 TimeTicks timestamp_
;
103 // id_ can be used to store phase-specific data.
104 unsigned long long id_
;
105 TraceValue arg_values_
[kTraceMaxNumArgs
];
106 const char* arg_names_
[kTraceMaxNumArgs
];
107 const unsigned char* category_enabled_
;
109 scoped_refptr
<base::RefCountedString
> parameter_copy_storage_
;
112 unsigned char flags_
;
113 unsigned char arg_types_
[kTraceMaxNumArgs
];
117 // TraceResultBuffer collects and converts trace fragments returned by TraceLog
119 class BASE_EXPORT TraceResultBuffer
{
121 typedef base::Callback
<void(const std::string
&)> OutputCallback
;
123 // If you don't need to stream JSON chunks out efficiently, and just want to
124 // get a complete JSON string after calling Finish, use this struct to collect
125 // JSON trace output.
126 struct BASE_EXPORT SimpleOutput
{
127 OutputCallback
GetCallback();
128 void Append(const std::string
& json_string
);
130 // Do what you want with the json_output_ string after calling
131 // TraceResultBuffer::Finish.
132 std::string json_output
;
136 ~TraceResultBuffer();
138 // Set callback. The callback will be called during Start with the initial
139 // JSON output and during AddFragment and Finish with following JSON output
140 // chunks. The callback target must live past the last calls to
141 // TraceResultBuffer::Start/AddFragment/Finish.
142 void SetOutputCallback(const OutputCallback
& json_chunk_callback
);
144 // Start JSON output. This resets all internal state, so you can reuse
145 // the TraceResultBuffer by calling Start.
148 // Call AddFragment 0 or more times to add trace fragments from TraceLog.
149 void AddFragment(const std::string
& trace_fragment
);
151 // When all fragments have been added, call Finish to complete the JSON
156 OutputCallback output_callback_
;
161 class BASE_EXPORT TraceLog
{
163 // Notification is a mask of one or more of the following events.
165 // The trace buffer does not flush dynamically, so when it fills up,
166 // subsequent trace events will be dropped. This callback is generated when
167 // the trace buffer is full. The callback must be thread safe.
168 TRACE_BUFFER_FULL
= 1 << 0,
169 // A subscribed trace-event occurred.
170 EVENT_WATCH_NOTIFICATION
= 1 << 1
173 static TraceLog
* GetInstance();
175 // Get set of known categories. This can change as new code paths are reached.
176 // The known categories are inserted into |categories|.
177 void GetKnownCategories(std::vector
<std::string
>* categories
);
179 // Enable tracing for provided list of categories. If tracing is already
180 // enabled, this method does nothing -- changing categories during trace is
182 // If both included_categories and excluded_categories are empty,
183 // all categories are traced.
184 // Else if included_categories is non-empty, only those are traced.
185 // Else if excluded_categories is non-empty, everything but those are traced.
186 // Wildcards * and ? are supported (see MatchPattern in string_util.h).
187 void SetEnabled(const std::vector
<std::string
>& included_categories
,
188 const std::vector
<std::string
>& excluded_categories
);
190 // |categories| is a comma-delimited list of category wildcards.
191 // A category can have an optional '-' prefix to make it an excluded category.
192 // All the same rules apply above, so for example, having both included and
193 // excluded categories in the same list would not be supported.
195 // Example: SetEnabled("test_MyTest*");
196 // Example: SetEnabled("test_MyTest*,test_OtherStuff");
197 // Example: SetEnabled("-excluded_category1,-excluded_category2");
198 void SetEnabled(const std::string
& categories
);
200 // Retieves the categories set via a prior call to SetEnabled(). Only
201 // meaningful if |IsEnabled()| is true.
202 void GetEnabledTraceCategories(std::vector
<std::string
>* included_out
,
203 std::vector
<std::string
>* excluded_out
);
205 // Disable tracing for all categories.
207 // Helper method to enable/disable tracing for all categories.
208 void SetEnabled(bool enabled
);
209 bool IsEnabled() { return enabled_
; }
211 #if defined(OS_ANDROID)
212 static void InitATrace();
215 // Enabled state listeners give a callback when tracing is enabled or
216 // disabled. This can be used to tie into other library's tracing systems
218 class EnabledStateChangedObserver
{
220 // Called just before the tracing system becomes
221 // enabled. TraceLog::IsEnabled will return false at this point and trace
222 // macros and methods called within the observer will deadlock.
223 virtual void OnTraceLogWillEnable() { }
225 // Called just before the tracing system disables. TraceLog::IsEnabled is
226 // still false at this point TRACE macros will still be capturing
227 // data. However, trace macros and methods called within the observer will
229 virtual void OnTraceLogWillDisable() { }
231 void AddEnabledStateObserver(EnabledStateChangedObserver
* listener
);
232 void RemoveEnabledStateObserver(EnabledStateChangedObserver
* listener
);
234 float GetBufferPercentFull() const;
236 // Set the thread-safe notification callback. The callback can occur at any
237 // time and from any thread. WARNING: It is possible for the previously set
238 // callback to be called during OR AFTER a call to SetNotificationCallback.
239 // Therefore, the target of the callback must either be a global function,
240 // ref-counted object or a LazyInstance with Leaky traits (or equivalent).
241 typedef base::Callback
<void(int)> NotificationCallback
;
242 void SetNotificationCallback(const NotificationCallback
& cb
);
244 // Flush all collected events to the given output callback. The callback will
245 // be called one or more times with IPC-bite-size chunks. The string format is
246 // undefined. Use TraceResultBuffer to convert one or more trace strings to
248 typedef base::Callback
<void(const scoped_refptr
<base::RefCountedString
>&)>
250 void Flush(const OutputCallback
& cb
);
252 // Called by TRACE_EVENT* macros, don't call this directly.
253 static const unsigned char* GetCategoryEnabled(const char* name
);
254 static const char* GetCategoryName(const unsigned char* category_enabled
);
256 // Called by TRACE_EVENT* macros, don't call this directly.
257 // If |copy| is set, |name|, |arg_name1| and |arg_name2| will be deep copied
258 // into the event; see "Memory scoping note" and TRACE_EVENT_COPY_XXX above.
259 void AddTraceEvent(char phase
,
260 const unsigned char* category_enabled
,
262 unsigned long long id
,
264 const char** arg_names
,
265 const unsigned char* arg_types
,
266 const unsigned long long* arg_values
,
267 unsigned char flags
);
268 static void AddTraceEventEtw(char phase
,
272 static void AddTraceEventEtw(char phase
,
275 const std::string
& extra
);
277 // For every matching event, a notification will be fired. NOTE: the
278 // notification will fire for each matching event that has already occurred
279 // since tracing was started (including before tracing if the process was
280 // started with tracing turned on).
281 void SetWatchEvent(const std::string
& category_name
,
282 const std::string
& event_name
);
283 // Cancel the watch event. If tracing is enabled, this may race with the
284 // watch event notification firing.
285 void CancelWatchEvent();
287 int process_id() const { return process_id_
; }
289 // Exposed for unittesting:
291 // Allows deleting our singleton instance.
292 static void DeleteForTesting();
294 // Allows resurrecting our singleton instance post-AtExit processing.
295 static void Resurrect();
297 // Allow tests to inspect TraceEvents.
298 size_t GetEventsSize() const { return logged_events_
.size(); }
299 const TraceEvent
& GetEventAt(size_t index
) const {
300 DCHECK(index
< logged_events_
.size());
301 return logged_events_
[index
];
304 void SetProcessID(int process_id
);
306 // Allow setting an offset between the current TimeTicks time and the time
307 // that should be reported.
308 void SetTimeOffset(TimeDelta offset
);
311 // This allows constructor and destructor to be private and usable only
312 // by the Singleton class.
313 friend struct StaticMemorySingletonTraits
<TraceLog
>;
315 // The pointer returned from GetCategoryEnabledInternal() points to a value
316 // with zero or more of the following bits. Used in this class only.
317 // The TRACE_EVENT macros should only use the value as a bool.
318 enum CategoryEnabledFlags
{
319 // Normal enabled flag for categories enabled with Enable().
320 CATEGORY_ENABLED
= 1 << 0,
321 // On Android if ATrace is enabled, all categories will have this bit.
322 // Not used on other platforms.
323 ATRACE_ENABLED
= 1 << 1
326 // Helper class for managing notification_thread_count_ and running
327 // notification callbacks. This is very similar to a reader-writer lock, but
328 // shares the lock with TraceLog and manages the notification flags.
329 class NotificationHelper
{
331 inline explicit NotificationHelper(TraceLog
* trace_log
);
332 inline ~NotificationHelper();
334 // Called only while TraceLog::lock_ is held. This ORs the given
335 // notification with any existing notifcations.
336 inline void AddNotificationWhileLocked(int notification
);
338 // Called only while TraceLog::lock_ is NOT held. If there are any pending
339 // notifications from previous calls to AddNotificationWhileLocked, this
340 // will call the NotificationCallback.
341 inline void SendNotificationIfAny();
344 TraceLog
* trace_log_
;
345 NotificationCallback callback_copy_
;
351 const unsigned char* GetCategoryEnabledInternal(const char* name
);
352 void AddThreadNameMetadataEvents();
354 #if defined(OS_ANDROID)
355 void SendToATrace(char phase
,
356 const char* category
,
359 const char** arg_names
,
360 const unsigned char* arg_types
,
361 const unsigned long long* arg_values
);
362 void AddClockSyncMetadataEvents();
363 static void ApplyATraceEnabledFlag(unsigned char* category_enabled
);
366 // TODO(nduca): switch to per-thread trace buffers to reduce thread
368 // This lock protects TraceLog member accesses from arbitrary threads.
371 NotificationCallback notification_callback_
;
372 std::vector
<TraceEvent
> logged_events_
;
373 std::vector
<std::string
> included_categories_
;
374 std::vector
<std::string
> excluded_categories_
;
375 bool dispatching_to_observer_list_
;
376 ObserverList
<EnabledStateChangedObserver
> enabled_state_observer_list_
;
378 base::hash_map
<int, std::string
> thread_names_
;
380 // XORed with TraceID to make it unlikely to collide with other processes.
381 unsigned long long process_id_hash_
;
385 TimeDelta time_offset_
;
387 // Allow tests to wake up when certain events occur.
388 const unsigned char* watch_category_
;
389 std::string watch_event_name_
;
391 DISALLOW_COPY_AND_ASSIGN(TraceLog
);
397 #endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_