| OLD | NEW |
| (Empty) |
| 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 | |
| 42 EtwMofEvent() { | |
| 43 memset(static_cast<Super*>(this), 0, sizeof(Super)); | |
| 44 } | |
| 45 | |
| 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 | |
| 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 | |
| 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 | |
| 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. | |
| 110 void set_provider_name(const GUID& provider_name) { | |
| 111 provider_name_ = provider_name; | |
| 112 } | |
| 113 const GUID& provider_name() const { return provider_name_; } | |
| 114 TRACEHANDLE registration_handle() const { return registration_handle_; } | |
| 115 TRACEHANDLE session_handle() const { return session_handle_; } | |
| 116 EtwEventFlags enable_flags() const { return enable_flags_; } | |
| 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". | |
| 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. | |
| 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. | |
| 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. | |
| 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_ | |
| OLD | NEW |