event_trace_provider.h 6.9 KB

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