event_trace_provider.h 6.8 KB

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