Update .DEPS.git
[chromium-blink-merge.git] / base / debug / trace_event_impl.h
blob87cfa8cdfa2ead264fb8ac37c5d5e782660f51f5
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"
11 #include <string>
12 #include <vector>
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;
43 namespace base {
45 namespace debug {
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 {
54 public:
55 union TraceValue {
56 bool as_bool;
57 unsigned long long as_uint;
58 long long as_int;
59 double as_double;
60 const void* as_pointer;
61 const char* as_string;
64 TraceEvent();
65 TraceEvent(int thread_id,
66 TimeTicks timestamp,
67 char phase,
68 const unsigned char* category_enabled,
69 const char* name,
70 unsigned long long id,
71 int num_args,
72 const char** arg_names,
73 const unsigned char* arg_types,
74 const unsigned long long* arg_values,
75 unsigned char flags);
76 ~TraceEvent();
78 // Serialize event data to JSON
79 static void AppendEventsAsJSON(const std::vector<TraceEvent>& events,
80 size_t start,
81 size_t count,
82 std::string* out);
83 void AppendAsJSON(std::string* out) const;
85 static void AppendValueAsJSON(unsigned char type,
86 TraceValue value,
87 std::string* out);
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_; }
100 private:
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_;
108 const char* name_;
109 scoped_refptr<base::RefCountedString> parameter_copy_storage_;
110 int thread_id_;
111 char phase_;
112 unsigned char flags_;
113 unsigned char arg_types_[kTraceMaxNumArgs];
117 // TraceResultBuffer collects and converts trace fragments returned by TraceLog
118 // to JSON output.
119 class BASE_EXPORT TraceResultBuffer {
120 public:
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;
135 TraceResultBuffer();
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.
146 void 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
152 // formatted output.
153 void Finish();
155 private:
156 OutputCallback output_callback_;
157 bool append_comma_;
161 class BASE_EXPORT TraceLog {
162 public:
163 // Notification is a mask of one or more of the following events.
164 enum Notification {
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
181 // not supported.
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.
206 void SetDisabled();
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();
213 #endif
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
217 // on-demand.
218 class EnabledStateChangedObserver {
219 public:
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
228 // deadlock.
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
247 // JSON.
248 typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&)>
249 OutputCallback;
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,
261 const char* name,
262 unsigned long long id,
263 int num_args,
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,
269 const char* name,
270 const void* id,
271 const char* extra);
272 static void AddTraceEventEtw(char phase,
273 const char* name,
274 const void* id,
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);
310 private:
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 {
330 public:
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();
343 private:
344 TraceLog* trace_log_;
345 NotificationCallback callback_copy_;
346 int notification_;
349 TraceLog();
350 ~TraceLog();
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,
357 const char* name,
358 int num_args,
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);
364 #endif
366 // TODO(nduca): switch to per-thread trace buffers to reduce thread
367 // synchronization.
368 // This lock protects TraceLog member accesses from arbitrary threads.
369 Lock lock_;
370 bool enabled_;
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_;
383 int process_id_;
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);
394 } // namespace debug
395 } // namespace base
397 #endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_