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