• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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