1 // Copyright 2011 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 // 5 // Declaration of a Windows event trace controller class. 6 // The controller takes care of creating and manipulating event trace 7 // sessions. 8 // 9 // Event tracing for Windows is a system-provided service that provides 10 // logging control and high-performance transport for generic, binary trace 11 // events. Event trace providers register with the system by their name, 12 // which is a GUID, and can from that point forward receive callbacks that 13 // start or end tracing and that change their trace level and enable mask. 14 // 15 // A trace controller can create an event tracing session, which either 16 // sends events to a binary file, or to a realtime consumer, or both. 17 // 18 // A trace consumer consumes events from zero or one realtime session, 19 // as well as potentially from multiple binary trace files. 20 #ifndef BASE_WIN_EVENT_TRACE_CONTROLLER_H_ 21 #define BASE_WIN_EVENT_TRACE_CONTROLLER_H_ 22 23 #include <windows.h> 24 25 #include <evntrace.h> 26 #include <stddef.h> 27 #include <wmistr.h> 28 29 #include <string> 30 31 #include "base/base_export.h" 32 33 namespace base { 34 namespace win { 35 36 // Utility class to make it easier to work with EVENT_TRACE_PROPERTIES. 37 // The EVENT_TRACE_PROPERTIES structure contains information about an 38 // event tracing session. 39 class BASE_EXPORT EtwTraceProperties { 40 public: 41 EtwTraceProperties(); 42 43 EtwTraceProperties(const EtwTraceProperties&) = delete; 44 EtwTraceProperties& operator=(const EtwTraceProperties&) = delete; 45 get()46 EVENT_TRACE_PROPERTIES* get() { return &properties_; } 47 get()48 const EVENT_TRACE_PROPERTIES* get() const { 49 return reinterpret_cast<const EVENT_TRACE_PROPERTIES*>(&properties_); 50 } 51 GetLoggerName()52 const wchar_t* GetLoggerName() const { 53 return reinterpret_cast<const wchar_t*>(buffer_ + get()->LoggerNameOffset); 54 } 55 56 // Copies logger_name to the properties structure. 57 HRESULT SetLoggerName(const wchar_t* logger_name); GetLoggerFileName()58 const wchar_t* GetLoggerFileName() const { 59 return reinterpret_cast<const wchar_t*>(buffer_ + get()->LogFileNameOffset); 60 } 61 62 // Copies logger_file_name to the properties structure. 63 HRESULT SetLoggerFileName(const wchar_t* logger_file_name); 64 65 // Max string len for name and session name is 1024 per documentation. 66 static const size_t kMaxStringLen = 1024; 67 // Properties buffer allocates space for header and for 68 // max length for name and session name. 69 static const size_t kBufSize = 70 sizeof(EVENT_TRACE_PROPERTIES) + 2 * sizeof(wchar_t) * (kMaxStringLen); 71 72 private: 73 // The EVENT_TRACE_PROPERTIES structure needs to be overlaid on a 74 // larger buffer to allow storing the logger name and logger file 75 // name contiguously with the structure. 76 union { 77 // Our properties header. 78 EVENT_TRACE_PROPERTIES properties_; 79 // The actual size of the buffer is forced by this member. 80 char buffer_[kBufSize]; 81 }; 82 }; 83 84 // This class implements an ETW controller, which knows how to start and 85 // stop event tracing sessions, as well as controlling ETW provider 86 // log levels and enable bit masks under the session. 87 class BASE_EXPORT EtwTraceController { 88 public: 89 EtwTraceController(); 90 91 EtwTraceController(const EtwTraceController&) = delete; 92 EtwTraceController& operator=(const EtwTraceController&) = delete; 93 94 ~EtwTraceController(); 95 96 // Start a session with given name and properties. 97 HRESULT Start(const wchar_t* session_name, EtwTraceProperties* prop); 98 99 // Starts a session tracing to a file with some default properties. 100 HRESULT StartFileSession(const wchar_t* session_name, 101 const wchar_t* logfile_path, 102 bool realtime = false); 103 104 // Starts a realtime session with some default properties. |buffer_size| is 105 // in KB. A default value for |buffer_size| is used if 0 is passed in. 106 HRESULT StartRealtimeSession(const wchar_t* session_name, size_t buffer_size); 107 108 // Enables "provider" at "level" for this session. 109 // This will cause all providers registered with the GUID 110 // "provider" to start tracing at the new level, systemwide. 111 HRESULT EnableProvider(const GUID& provider, 112 UCHAR level, 113 ULONG flags = 0xFFFFFFFF); 114 // Disables "provider". 115 HRESULT DisableProvider(const GUID& provider); 116 117 // Stops our session and retrieve the new properties of the session, 118 // properties may be NULL. 119 HRESULT Stop(EtwTraceProperties* properties); 120 121 // Flushes our session and retrieve the current properties, 122 // properties may be NULL. 123 HRESULT Flush(EtwTraceProperties* properties); 124 125 // Static utility functions for controlling 126 // sessions we don't necessarily own. 127 static HRESULT Start(const wchar_t* session_name, 128 EtwTraceProperties* properties, 129 TRACEHANDLE* session_handle); 130 131 static HRESULT Query(const wchar_t* session_name, 132 EtwTraceProperties* properties); 133 134 static HRESULT Update(const wchar_t* session_name, 135 EtwTraceProperties* properties); 136 137 static HRESULT Stop(const wchar_t* session_name, 138 EtwTraceProperties* properties); 139 static HRESULT Flush(const wchar_t* session_name, 140 EtwTraceProperties* properties); 141 142 // Accessors. session()143 TRACEHANDLE session() const { return session_; } session_name()144 const wchar_t* session_name() const { return session_name_.c_str(); } 145 146 private: 147 std::wstring session_name_; 148 TRACEHANDLE session_ = NULL; 149 }; 150 151 } // namespace win 152 } // namespace base 153 154 #endif // BASE_WIN_EVENT_TRACE_CONTROLLER_H_ 155