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