Index: base/debug/trace_event.h |
diff --git a/base/debug/trace_event.h b/base/debug/trace_event.h |
index a1fff3e66d78645080008dc19dc75bda57e9b673..84094b22c5c35896417d9b3de80280f72fa08da1 100644 |
--- a/base/debug/trace_event.h |
+++ b/base/debug/trace_event.h |
@@ -2,6 +2,13 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
+// This header is designed to give you trace_event macros without specifying |
+// how the events actually get collected and stored. If you need to expose trace |
+// event to some other universe, you can copy-and-paste this file, |
+// implement the TRACE_EVENT_API macros, and do any other necessary fixup for |
+// the target platform. The end result is that multiple libraries can funnel |
+// events through to a shared trace event collector. |
+ |
// Trace events are for tracking application performance and resource usage. |
// Macros are provided to track: |
// Begin and end of function calls |
@@ -147,87 +154,16 @@ |
#define BASE_DEBUG_TRACE_EVENT_H_ |
#pragma once |
-#include "build/build_config.h" |
- |
#include <string> |
-#include <vector> |
- |
-#include "base/callback.h" |
-#include "base/hash_tables.h" |
-#include "base/memory/ref_counted_memory.h" |
-#include "base/string_util.h" |
-#include "base/synchronization/lock.h" |
-#include "base/third_party/dynamic_annotations/dynamic_annotations.h" |
-#include "base/timer.h" |
- |
-//////////////////////////////////////////////////////////////////////////////// |
-// TODO(jbates): split this into a separate header. |
-// This header is designed to be give you trace_event macros without specifying |
-// how the events actually get collected and stored. If you need to expose trace |
-// event to some other universe, you can copy-and-paste this file and just |
-// implement these API macros. |
- |
-// unsigned char* |
-// TRACE_EVENT_API_GET_CATEGORY_ENABLED(const char* category_name) |
-#define TRACE_EVENT_API_GET_CATEGORY_ENABLED \ |
- base::debug::TraceLog::GetCategoryEnabled |
- |
-// Returns the threshold_begin_id used by TRACE_IF_LONGER_THAN macros. |
-// int TRACE_EVENT_API_ADD_TRACE_EVENT( |
-// char phase, |
-// const unsigned char* category_enabled, |
-// const char* name, |
-// unsigned long long id, |
-// int num_args, |
-// const char** arg_names, |
-// const unsigned char* arg_types, |
-// const unsigned long long* arg_values, |
-// int threshold_begin_id, |
-// long long threshold, |
-// unsigned char flags) |
-#define TRACE_EVENT_API_ADD_TRACE_EVENT \ |
- base::debug::TraceLog::GetInstance()->AddTraceEvent |
- |
-// void TRACE_EVENT_API_ADD_COUNTER_EVENT( |
-// const unsigned char* category_enabled, |
-// const char* name, |
-// unsigned long long id, |
-// const char* arg1_name, int arg1_val, |
-// const char* arg2_name, int arg2_val, |
-// unsigned char flags) |
-#define TRACE_EVENT_API_ADD_COUNTER_EVENT \ |
- base::debug::TraceLog::GetInstance()->AddCounterEvent |
- |
-// Mangle |pointer| with a process ID hash so that if |pointer| occurs on more |
-// than one process, it will not collide in the trace data. |
-// unsigned long long TRACE_EVENT_API_GET_ID_FROM_POINTER(void* pointer) |
-#define TRACE_EVENT_API_GET_ID_FROM_POINTER \ |
- base::debug::TraceLog::GetInstance()->GetInterProcessID |
-//////////////////////////////////////////////////////////////////////////////// |
+#include "build/build_config.h" |
+#include "base/debug/trace_event_impl.h" |
// By default, const char* argument values are assumed to have long-lived scope |
// and will not be copied. Use this macro to force a const char* to be copied. |
#define TRACE_STR_COPY(str) \ |
trace_event_internal::TraceStringWithCopy(str) |
-// Older style trace macros with explicit id and extra data |
-// Only these macros result in publishing data to ETW as currently implemented. |
-#define TRACE_EVENT_BEGIN_ETW(name, id, extra) \ |
- base::debug::TraceLog::AddTraceEventEtw( \ |
- TRACE_EVENT_PHASE_BEGIN, \ |
- name, reinterpret_cast<const void*>(id), extra) |
- |
-#define TRACE_EVENT_END_ETW(name, id, extra) \ |
- base::debug::TraceLog::AddTraceEventEtw( \ |
- TRACE_EVENT_PHASE_END, \ |
- name, reinterpret_cast<const void*>(id), extra) |
- |
-#define TRACE_EVENT_INSTANT_ETW(name, id, extra) \ |
- base::debug::TraceLog::AddTraceEventEtw( \ |
- TRACE_EVENT_PHASE_INSTANT, \ |
- name, reinterpret_cast<const void*>(id), extra) |
- |
// Records a pair of begin and end events called "name" for the current |
// scope, with 0, 1 or 2 associated arguments. If the category is not |
// enabled, then this does nothing. |
@@ -495,6 +431,48 @@ |
arg1_name, arg1_val, arg2_name, arg2_val) |
+//////////////////////////////////////////////////////////////////////////////// |
+// Implementation specific tracing API definitions. |
+ |
+// const unsigned char* |
+// TRACE_EVENT_API_GET_CATEGORY_ENABLED(const char* category_name) |
+#define TRACE_EVENT_API_GET_CATEGORY_ENABLED \ |
+ base::debug::TraceLog::GetCategoryEnabled |
+ |
+// Returns the threshold_begin_id used by TRACE_IF_LONGER_THAN macros. |
+// int TRACE_EVENT_API_ADD_TRACE_EVENT( |
+// char phase, |
+// const unsigned char* category_enabled, |
+// const char* name, |
+// unsigned long long id, |
+// int num_args, |
+// const char** arg_names, |
+// const unsigned char* arg_types, |
+// const unsigned long long* arg_values, |
+// int threshold_begin_id, |
+// long long threshold, |
+// unsigned char flags) |
+#define TRACE_EVENT_API_ADD_TRACE_EVENT \ |
+ base::debug::TraceLog::GetInstance()->AddTraceEvent |
+ |
+// void TRACE_EVENT_API_ADD_COUNTER_EVENT( |
+// const unsigned char* category_enabled, |
+// const char* name, |
+// unsigned long long id, |
+// const char* arg1_name, int arg1_val, |
+// const char* arg2_name, int arg2_val, |
+// unsigned char flags) |
+#define TRACE_EVENT_API_ADD_COUNTER_EVENT \ |
+ base::debug::TraceLog::GetInstance()->AddCounterEvent |
+ |
+// Mangle |pointer| with a process ID hash so that if |pointer| occurs on more |
+// than one process, it will not collide in the trace data. |
+// unsigned long long TRACE_EVENT_API_GET_ID_FROM_POINTER(void* pointer) |
+#define TRACE_EVENT_API_GET_ID_FROM_POINTER \ |
+ base::debug::TraceLog::GetInstance()->GetInterProcessID |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
+ |
// Implementation detail: trace event macros create temporary variables |
// to keep instrumentation overhead low. These macros give each temporary |
// variable a unique name based on the line number to prevent name collissions. |
@@ -586,17 +564,6 @@ |
##__VA_ARGS__); \ |
} |
-template <typename Type> |
-struct StaticMemorySingletonTraits; |
- |
-namespace base { |
- |
-class RefCountedString; |
- |
-namespace debug { |
- |
-const int kTraceMaxNumArgs = 2; |
- |
// Notes regarding the following definitions: |
// New values can be added and propagated to third party libraries, but existing |
// definitions must never be changed, because third party libraries may use old |
@@ -625,275 +592,6 @@ const int kTraceMaxNumArgs = 2; |
#define TRACE_VALUE_TYPE_STRING (static_cast<unsigned char>(6)) |
#define TRACE_VALUE_TYPE_COPY_STRING (static_cast<unsigned char>(7)) |
-// Output records are "Events" and can be obtained via the |
-// OutputCallback whenever the tracing system decides to flush. This |
-// can happen at any time, on any thread, or you can programatically |
-// force it to happen. |
-class BASE_EXPORT TraceEvent { |
- public: |
- union TraceValue { |
- bool as_bool; |
- unsigned long long as_uint; |
- long long as_int; |
- double as_double; |
- const void* as_pointer; |
- const char* as_string; |
- }; |
- |
- TraceEvent(); |
- TraceEvent(int thread_id, |
- TimeTicks timestamp, |
- char phase, |
- const unsigned char* category_enabled, |
- const char* name, |
- unsigned long long id, |
- int num_args, |
- const char** arg_names, |
- const unsigned char* arg_types, |
- const unsigned long long* arg_values, |
- unsigned char flags); |
- ~TraceEvent(); |
- |
- // Serialize event data to JSON |
- static void AppendEventsAsJSON(const std::vector<TraceEvent>& events, |
- size_t start, |
- size_t count, |
- std::string* out); |
- void AppendAsJSON(std::string* out) const; |
- |
- TimeTicks timestamp() const { return timestamp_; } |
- |
- // Exposed for unittesting: |
- |
- const base::RefCountedString* parameter_copy_storage() const { |
- return parameter_copy_storage_.get(); |
- } |
- |
- const char* name() const { return name_; } |
- |
- private: |
- // Note: these are ordered by size (largest first) for optimal packing. |
- TimeTicks timestamp_; |
- // id_ can be used to store phase-specific data. |
- unsigned long long id_; |
- TraceValue arg_values_[kTraceMaxNumArgs]; |
- const char* arg_names_[kTraceMaxNumArgs]; |
- const unsigned char* category_enabled_; |
- const char* name_; |
- scoped_refptr<base::RefCountedString> parameter_copy_storage_; |
- int thread_id_; |
- char phase_; |
- unsigned char flags_; |
- unsigned char arg_types_[kTraceMaxNumArgs]; |
-}; |
- |
- |
-// TraceResultBuffer collects and converts trace fragments returned by TraceLog |
-// to JSON output. |
-class BASE_EXPORT TraceResultBuffer { |
- public: |
- typedef base::Callback<void(const std::string&)> OutputCallback; |
- |
- // If you don't need to stream JSON chunks out efficiently, and just want to |
- // get a complete JSON string after calling Finish, use this struct to collect |
- // JSON trace output. |
- struct BASE_EXPORT SimpleOutput { |
- OutputCallback GetCallback(); |
- void Append(const std::string& json_string); |
- |
- // Do what you want with the json_output_ string after calling |
- // TraceResultBuffer::Finish. |
- std::string json_output; |
- }; |
- |
- TraceResultBuffer(); |
- ~TraceResultBuffer(); |
- |
- // Set callback. The callback will be called during Start with the initial |
- // JSON output and during AddFragment and Finish with following JSON output |
- // chunks. The callback target must live past the last calls to |
- // TraceResultBuffer::Start/AddFragment/Finish. |
- void SetOutputCallback(const OutputCallback& json_chunk_callback); |
- |
- // Start JSON output. This resets all internal state, so you can reuse |
- // the TraceResultBuffer by calling Start. |
- void Start(); |
- |
- // Call AddFragment 0 or more times to add trace fragments from TraceLog. |
- void AddFragment(const std::string& trace_fragment); |
- |
- // When all fragments have been added, call Finish to complete the JSON |
- // formatted output. |
- void Finish(); |
- |
- private: |
- OutputCallback output_callback_; |
- bool append_comma_; |
-}; |
- |
- |
-class BASE_EXPORT TraceLog { |
- public: |
- static TraceLog* GetInstance(); |
- |
- // Get set of known categories. This can change as new code paths are reached. |
- // The known categories are inserted into |categories|. |
- void GetKnownCategories(std::vector<std::string>* categories); |
- |
- // Enable tracing for provided list of categories. If tracing is already |
- // enabled, this method does nothing -- changing categories during trace is |
- // not supported. |
- // If both included_categories and excluded_categories are empty, |
- // all categories are traced. |
- // Else if included_categories is non-empty, only those are traced. |
- // Else if excluded_categories is non-empty, everything but those are traced. |
- // Wildcards * and ? are supported (see MatchPattern in string_util.h). |
- void SetEnabled(const std::vector<std::string>& included_categories, |
- const std::vector<std::string>& excluded_categories); |
- |
- // |categories| is a comma-delimited list of category wildcards. |
- // A category can have an optional '-' prefix to make it an excluded category. |
- // All the same rules apply above, so for example, having both included and |
- // excluded categories in the same list would not be supported. |
- // |
- // Example: SetEnabled("test_MyTest*"); |
- // Example: SetEnabled("test_MyTest*,test_OtherStuff"); |
- // Example: SetEnabled("-excluded_category1,-excluded_category2"); |
- void SetEnabled(const std::string& categories); |
- |
- // Retieves the categories set via a prior call to SetEnabled(). Only |
- // meaningful if |IsEnabled()| is true. |
- void GetEnabledTraceCategories(std::vector<std::string>* included_out, |
- std::vector<std::string>* excluded_out); |
- |
- // Disable tracing for all categories. |
- void SetDisabled(); |
- // Helper method to enable/disable tracing for all categories. |
- void SetEnabled(bool enabled); |
- bool IsEnabled() { return enabled_; } |
- |
- float GetBufferPercentFull() const; |
- |
- // When enough events are collected, they are handed (in bulk) to |
- // the output callback. If no callback is set, the output will be |
- // silently dropped. The callback must be thread safe. The string format is |
- // undefined. Use TraceResultBuffer to convert one or more trace strings to |
- // JSON. |
- typedef RefCountedData<std::string> RefCountedString; |
- typedef base::Callback<void(const scoped_refptr<RefCountedString>&)> |
- OutputCallback; |
- void SetOutputCallback(const OutputCallback& cb); |
- |
- // The trace buffer does not flush dynamically, so when it fills up, |
- // subsequent trace events will be dropped. This callback is generated when |
- // the trace buffer is full. The callback must be thread safe. |
- typedef base::Callback<void(void)> BufferFullCallback; |
- void SetBufferFullCallback(const BufferFullCallback& cb); |
- |
- // Flushes all logged data to the callback. |
- void Flush(); |
- |
- // Called by TRACE_EVENT* macros, don't call this directly. |
- static const unsigned char* GetCategoryEnabled(const char* name); |
- static const char* GetCategoryName(const unsigned char* category_enabled); |
- |
- // Called by TRACE_EVENT* macros, don't call this directly. |
- // Returns the index in the internal vector of the event if it was added, or |
- // -1 if the event was not added. |
- // On end events, the return value of the begin event can be specified along |
- // with a threshold in microseconds. If the elapsed time between begin and end |
- // is less than the threshold, the begin/end event pair is dropped. |
- // 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. |
- int AddTraceEvent(char phase, |
- const unsigned char* category_enabled, |
- const char* name, |
- unsigned long long id, |
- int num_args, |
- const char** arg_names, |
- const unsigned char* arg_types, |
- const unsigned long long* arg_values, |
- int threshold_begin_id, |
- long long threshold, |
- unsigned char flags); |
- static void AddTraceEventEtw(char phase, |
- const char* name, |
- const void* id, |
- const char* extra); |
- static void AddTraceEventEtw(char phase, |
- const char* name, |
- const void* id, |
- const std::string& extra); |
- |
- // A wrapper around AddTraceEvent used by TRACE_COUNTERx macros |
- // that allows only integer values for the counters. |
- void AddCounterEvent(const unsigned char* category_enabled, |
- const char* name, |
- unsigned long long id, |
- const char* arg1_name, int arg1_val, |
- const char* arg2_name, int arg2_val, |
- unsigned char flags); |
- |
- // Mangle |ptr| with a hash based on the process ID so that if |ptr| occurs on |
- // more than one process, it will not collide. |
- unsigned long long GetInterProcessID(void* ptr) const { |
- return static_cast<unsigned long long>(reinterpret_cast<uintptr_t>(ptr)) ^ |
- process_id_hash_; |
- } |
- |
- int process_id() const { return process_id_; } |
- |
- // Exposed for unittesting: |
- |
- // Allows deleting our singleton instance. |
- static void DeleteForTesting(); |
- |
- // Allows resurrecting our singleton instance post-AtExit processing. |
- static void Resurrect(); |
- |
- // Allow tests to inspect TraceEvents. |
- size_t GetEventsSize() const { return logged_events_.size(); } |
- const TraceEvent& GetEventAt(size_t index) const { |
- DCHECK(index < logged_events_.size()); |
- return logged_events_[index]; |
- } |
- |
- void SetProcessID(int process_id); |
- |
- private: |
- // This allows constructor and destructor to be private and usable only |
- // by the Singleton class. |
- friend struct StaticMemorySingletonTraits<TraceLog>; |
- |
- TraceLog(); |
- ~TraceLog(); |
- const unsigned char* GetCategoryEnabledInternal(const char* name); |
- void AddThreadNameMetadataEvents(); |
- void AddClockSyncMetadataEvents(); |
- |
- // TODO(nduca): switch to per-thread trace buffers to reduce thread |
- // synchronization. |
- Lock lock_; |
- bool enabled_; |
- OutputCallback output_callback_; |
- BufferFullCallback buffer_full_callback_; |
- std::vector<TraceEvent> logged_events_; |
- std::vector<std::string> included_categories_; |
- std::vector<std::string> excluded_categories_; |
- |
- base::hash_map<int, std::string> thread_names_; |
- |
- // XORed with TraceID to make it unlikely to collide with other processes. |
- unsigned long long process_id_hash_; |
- |
- int process_id_; |
- |
- DISALLOW_COPY_AND_ASSIGN(TraceLog); |
-}; |
- |
-} // namespace debug |
-} // namespace base |
- |
namespace trace_event_internal { |
// Specify these values when the corresponding argument of AddTraceEvent is not |