1 // Copyright (c) 2011 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. 4 // 5 // Declaration of a Windows event trace provider class, to allow using 6 // Windows Event Tracing for logging transport and control. 7 #ifndef BASE_WIN_EVENT_TRACE_PROVIDER_H_ 8 #define BASE_WIN_EVENT_TRACE_PROVIDER_H_ 9 10 #include <windows.h> 11 #include <wmistr.h> 12 #include <evntrace.h> 13 14 #include "base/base_export.h" 15 #include "base/basictypes.h" 16 17 namespace base { 18 namespace win { 19 20 typedef GUID EtwEventClass; 21 typedef UCHAR EtwEventType; 22 typedef UCHAR EtwEventLevel; 23 typedef USHORT EtwEventVersion; 24 typedef ULONG EtwEventFlags; 25 26 // Base class is a POD for correctness. 27 template <size_t N> struct EtwMofEventBase { 28 EVENT_TRACE_HEADER header; 29 MOF_FIELD fields[N]; 30 }; 31 32 // Utility class to auto-initialize event trace header structures. 33 template <size_t N> class EtwMofEvent: public EtwMofEventBase<N> { 34 public: 35 typedef EtwMofEventBase<N> Super; 36 37 // Clang and the C++ standard don't allow unqualified lookup into dependent 38 // bases, hence these using decls to explicitly pull the names out. 39 using EtwMofEventBase<N>::header; 40 using EtwMofEventBase<N>::fields; 41 EtwMofEvent()42 EtwMofEvent() { 43 memset(static_cast<Super*>(this), 0, sizeof(Super)); 44 } 45 EtwMofEvent(const EtwEventClass & event_class,EtwEventType type,EtwEventLevel level)46 EtwMofEvent(const EtwEventClass& event_class, EtwEventType type, 47 EtwEventLevel level) { 48 memset(static_cast<Super*>(this), 0, sizeof(Super)); 49 header.Size = sizeof(Super); 50 header.Guid = event_class; 51 header.Class.Type = type; 52 header.Class.Level = level; 53 header.Flags = WNODE_FLAG_TRACED_GUID | WNODE_FLAG_USE_MOF_PTR; 54 } 55 EtwMofEvent(const EtwEventClass & event_class,EtwEventType type,EtwEventVersion version,EtwEventLevel level)56 EtwMofEvent(const EtwEventClass& event_class, EtwEventType type, 57 EtwEventVersion version, EtwEventLevel level) { 58 memset(static_cast<Super*>(this), 0, sizeof(Super)); 59 header.Size = sizeof(Super); 60 header.Guid = event_class; 61 header.Class.Type = type; 62 header.Class.Version = version; 63 header.Class.Level = level; 64 header.Flags = WNODE_FLAG_TRACED_GUID | WNODE_FLAG_USE_MOF_PTR; 65 } 66 SetField(int field,size_t size,const void * data)67 void SetField(int field, size_t size, const void *data) { 68 // DCHECK(field < N); 69 if ((field < N) && (size <= kuint32max)) { 70 fields[field].DataPtr = reinterpret_cast<ULONG64>(data); 71 fields[field].Length = static_cast<ULONG>(size); 72 } 73 } 74 get()75 EVENT_TRACE_HEADER* get() { return& header; } 76 77 private: 78 DISALLOW_COPY_AND_ASSIGN(EtwMofEvent); 79 }; 80 81 // Trace provider with Event Tracing for Windows. The trace provider 82 // registers with ETW by its name which is a GUID. ETW calls back to 83 // the object whenever the trace level or enable flags for this provider 84 // name changes. 85 // Users of this class can test whether logging is currently enabled at 86 // a particular trace level, and whether particular enable flags are set, 87 // before other resources are consumed to generate and issue the log 88 // messages themselves. 89 class BASE_EXPORT EtwTraceProvider { 90 public: 91 // Creates an event trace provider identified by provider_name, which 92 // will be the name registered with Event Tracing for Windows (ETW). 93 explicit EtwTraceProvider(const GUID& provider_name); 94 95 // Creates an unnamed event trace provider, the provider must be given 96 // a name before registration. 97 EtwTraceProvider(); 98 virtual ~EtwTraceProvider(); 99 100 // Registers the trace provider with Event Tracing for Windows. 101 // Note: from this point forward ETW may call the provider's control 102 // callback. If the provider's name is enabled in some trace session 103 // already, the callback may occur recursively from this call, so 104 // call this only when you're ready to handle callbacks. 105 ULONG Register(); 106 // Unregisters the trace provider with ETW. 107 ULONG Unregister(); 108 109 // Accessors. set_provider_name(const GUID & provider_name)110 void set_provider_name(const GUID& provider_name) { 111 provider_name_ = provider_name; 112 } provider_name()113 const GUID& provider_name() const { return provider_name_; } registration_handle()114 TRACEHANDLE registration_handle() const { return registration_handle_; } session_handle()115 TRACEHANDLE session_handle() const { return session_handle_; } enable_flags()116 EtwEventFlags enable_flags() const { return enable_flags_; } enable_level()117 EtwEventLevel enable_level() const { return enable_level_; } 118 119 // Returns true iff logging should be performed for "level" and "flags". 120 // Note: flags is treated as a bitmask, and should normally have a single 121 // bit set, to test whether to log for a particular sub "facility". ShouldLog(EtwEventLevel level,EtwEventFlags flags)122 bool ShouldLog(EtwEventLevel level, EtwEventFlags flags) { 123 return NULL != session_handle_ && level >= enable_level_ && 124 (0 != (flags & enable_flags_)); 125 } 126 127 // Simple wrappers to log Unicode and ANSI strings. 128 // Do nothing if !ShouldLog(level, 0xFFFFFFFF). 129 ULONG Log(const EtwEventClass& event_class, EtwEventType type, 130 EtwEventLevel level, const char *message); 131 ULONG Log(const EtwEventClass& event_class, EtwEventType type, 132 EtwEventLevel level, const wchar_t *message); 133 134 // Log the provided event. 135 ULONG Log(EVENT_TRACE_HEADER* event); 136 137 protected: 138 // Called after events have been enabled, override in subclasses 139 // to set up state or log at the start of a session. 140 // Note: This function may be called ETW's thread and may be racy, 141 // bring your own locking if needed. OnEventsEnabled()142 virtual void OnEventsEnabled() {} 143 144 // Called just before events are disabled, override in subclasses 145 // to tear down state or log at the end of a session. 146 // Note: This function may be called ETW's thread and may be racy, 147 // bring your own locking if needed. OnEventsDisabled()148 virtual void OnEventsDisabled() {} 149 150 // Called just after events have been disabled, override in subclasses 151 // to tear down state at the end of a session. At this point it's 152 // to late to log anything to the session. 153 // Note: This function may be called ETW's thread and may be racy, 154 // bring your own locking if needed. PostEventsDisabled()155 virtual void PostEventsDisabled() {} 156 157 private: 158 ULONG EnableEvents(PVOID buffer); 159 ULONG DisableEvents(); 160 ULONG Callback(WMIDPREQUESTCODE request, PVOID buffer); 161 static ULONG WINAPI ControlCallback(WMIDPREQUESTCODE request, PVOID context, 162 ULONG *reserved, PVOID buffer); 163 164 GUID provider_name_; 165 TRACEHANDLE registration_handle_; 166 TRACEHANDLE session_handle_; 167 EtwEventFlags enable_flags_; 168 EtwEventLevel enable_level_; 169 170 // We don't use this, but on XP we're obliged to pass one in to 171 // RegisterTraceGuids. Non-const, because that's how the API needs it. 172 static TRACE_GUID_REGISTRATION obligatory_guid_registration_; 173 174 DISALLOW_COPY_AND_ASSIGN(EtwTraceProvider); 175 }; 176 177 } // namespace win 178 } // namespace base 179 180 #endif // BASE_WIN_EVENT_TRACE_PROVIDER_H_ 181