• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
EtwMofEvent()32   EtwMofEvent() {
33     memset(static_cast<Super*>(this), 0, sizeof(Super));
34   }
35 
EtwMofEvent(const EtwEventClass & event_class,EtwEventType type,EtwEventLevel level)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 
EtwMofEvent(const EtwEventClass & event_class,EtwEventType type,EtwEventVersion version,EtwEventLevel level)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 
SetField(int field,size_t size,const void * data)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 
get()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.
set_provider_name(const GUID & provider_name)100   void set_provider_name(const GUID& provider_name) {
101     provider_name_ = provider_name;
102   }
provider_name()103   const GUID& provider_name() const { return provider_name_; }
registration_handle()104   TRACEHANDLE registration_handle() const { return registration_handle_; }
session_handle()105   TRACEHANDLE session_handle() const { return session_handle_; }
enable_flags()106   EtwEventFlags enable_flags() const { return enable_flags_; }
enable_level()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".
ShouldLog(EtwEventLevel level,EtwEventFlags flags)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.
OnEventsEnabled()132   virtual void OnEventsEnabled() {}
OnEventsDisabled()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