• 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 #pragma once
10 
11 #include <windows.h>
12 #include <wmistr.h>
13 #include <evntrace.h>
14 
15 #include "base/base_api.h"
16 #include "base/basictypes.h"
17 
18 namespace base {
19 namespace win {
20 
21 typedef GUID EtwEventClass;
22 typedef UCHAR EtwEventType;
23 typedef UCHAR EtwEventLevel;
24 typedef USHORT EtwEventVersion;
25 typedef ULONG EtwEventFlags;
26 
27 // Base class is a POD for correctness.
28 template <size_t N> struct EtwMofEventBase {
29   EVENT_TRACE_HEADER header;
30   MOF_FIELD fields[N];
31 };
32 
33 // Utility class to auto-initialize event trace header structures.
34 template <size_t N> class EtwMofEvent: public EtwMofEventBase<N> {
35  public:
36   typedef EtwMofEventBase<N> Super;
37 
EtwMofEvent()38   EtwMofEvent() {
39     memset(static_cast<Super*>(this), 0, sizeof(Super));
40   }
41 
EtwMofEvent(const EtwEventClass & event_class,EtwEventType type,EtwEventLevel level)42   EtwMofEvent(const EtwEventClass& event_class, 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,EtwEventType type,EtwEventVersion version,EtwEventLevel level)52   EtwMofEvent(const EtwEventClass& event_class, EtwEventType type,
53               EtwEventVersion version, 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 
SetField(int field,size_t size,const void * data)63   void SetField(int field, size_t size, const void *data) {
64     // DCHECK(field < N);
65     if ((field < N) && (size <= kuint32max)) {
66       fields[field].DataPtr = reinterpret_cast<ULONG64>(data);
67       fields[field].Length = static_cast<ULONG>(size);
68     }
69   }
70 
get()71   EVENT_TRACE_HEADER* get() { return& header; }
72 
73  private:
74   DISALLOW_COPY_AND_ASSIGN(EtwMofEvent);
75 };
76 
77 // Trace provider with Event Tracing for Windows. The trace provider
78 // registers with ETW by its name which is a GUID. ETW calls back to
79 // the object whenever the trace level or enable flags for this provider
80 // name changes.
81 // Users of this class can test whether logging is currently enabled at
82 // a particular trace level, and whether particular enable flags are set,
83 // before other resources are consumed to generate and issue the log
84 // messages themselves.
85 class BASE_API EtwTraceProvider {
86  public:
87   // Creates an event trace provider identified by provider_name, which
88   // will be the name registered with Event Tracing for Windows (ETW).
89   explicit EtwTraceProvider(const GUID& provider_name);
90 
91   // Creates an unnamed event trace provider, the provider must be given
92   // a name before registration.
93   EtwTraceProvider();
94   virtual ~EtwTraceProvider();
95 
96   // Registers the trace provider with Event Tracing for Windows.
97   // Note: from this point forward ETW may call the provider's control
98   //    callback. If the provider's name is enabled in some trace session
99   //    already, the callback may occur recursively from this call, so
100   //    call this only when you're ready to handle callbacks.
101   ULONG Register();
102   // Unregisters the trace provider with ETW.
103   ULONG Unregister();
104 
105   // Accessors.
set_provider_name(const GUID & provider_name)106   void set_provider_name(const GUID& provider_name) {
107     provider_name_ = provider_name;
108   }
provider_name()109   const GUID& provider_name() const { return provider_name_; }
registration_handle()110   TRACEHANDLE registration_handle() const { return registration_handle_; }
session_handle()111   TRACEHANDLE session_handle() const { return session_handle_; }
enable_flags()112   EtwEventFlags enable_flags() const { return enable_flags_; }
enable_level()113   EtwEventLevel enable_level() const { return enable_level_; }
114 
115   // Returns true iff logging should be performed for "level" and "flags".
116   // Note: flags is treated as a bitmask, and should normally have a single
117   //      bit set, to test whether to log for a particular sub "facility".
ShouldLog(EtwEventLevel level,EtwEventFlags flags)118   bool ShouldLog(EtwEventLevel level, EtwEventFlags flags) {
119     return NULL != session_handle_ && level >= enable_level_ &&
120         (0 != (flags & enable_flags_));
121   }
122 
123   // Simple wrappers to log Unicode and ANSI strings.
124   // Do nothing if !ShouldLog(level, 0xFFFFFFFF).
125   ULONG Log(const EtwEventClass& event_class, EtwEventType type,
126             EtwEventLevel level, const char *message);
127   ULONG Log(const EtwEventClass& event_class, EtwEventType type,
128             EtwEventLevel level, const wchar_t *message);
129 
130   // Log the provided event.
131   ULONG Log(EVENT_TRACE_HEADER* event);
132 
133  protected:
134   // Called after events have been enabled, override in subclasses
135   // to set up state or log at the start of a session.
136   // Note: This function may be called ETW's thread and may be racy,
137   //    bring your own locking if needed.
OnEventsEnabled()138   virtual void OnEventsEnabled() {}
139 
140   // Called just before events are disabled, override in subclasses
141   // to tear down state or log at the end of a session.
142   // Note: This function may be called ETW's thread and may be racy,
143   //    bring your own locking if needed.
OnEventsDisabled()144   virtual void OnEventsDisabled() {}
145 
146   // Called just after events have been disabled, override in subclasses
147   // to tear down state at the end of a session. At this point it's
148   // to late to log anything to the session.
149   // Note: This function may be called ETW's thread and may be racy,
150   //    bring your own locking if needed.
PostEventsDisabled()151   virtual void PostEventsDisabled() {}
152 
153  private:
154   ULONG EnableEvents(PVOID buffer);
155   ULONG DisableEvents();
156   ULONG Callback(WMIDPREQUESTCODE request, PVOID buffer);
157   static ULONG WINAPI ControlCallback(WMIDPREQUESTCODE request, PVOID context,
158                                       ULONG *reserved, PVOID buffer);
159 
160   GUID provider_name_;
161   TRACEHANDLE registration_handle_;
162   TRACEHANDLE session_handle_;
163   EtwEventFlags enable_flags_;
164   EtwEventLevel enable_level_;
165 
166   // We don't use this, but on XP we're obliged to pass one in to
167   // RegisterTraceGuids. Non-const, because that's how the API needs it.
168   static TRACE_GUID_REGISTRATION obligatory_guid_registration_;
169 
170   DISALLOW_COPY_AND_ASSIGN(EtwTraceProvider);
171 };
172 
173 }  // namespace win
174 }  // namespace base
175 
176 #endif  // BASE_WIN_EVENT_TRACE_PROVIDER_H_
177