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