event_trace_provider.h revision ddb351dbec246cf1fab5ec20d2d5520909041de1
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
18namespace base {
19namespace win {
20
21typedef GUID EtwEventClass;
22typedef UCHAR EtwEventType;
23typedef UCHAR EtwEventLevel;
24typedef USHORT EtwEventVersion;
25typedef ULONG EtwEventFlags;
26
27// Base class is a POD for correctness.
28template <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.
34template <size_t N> class EtwMofEvent: public EtwMofEventBase<N> {
35 public:
36  typedef EtwMofEventBase<N> Super;
37
38  EtwMofEvent() {
39    memset(static_cast<Super*>(this), 0, sizeof(Super));
40  }
41
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
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
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
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.
85class 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.
106  void set_provider_name(const GUID& provider_name) {
107    provider_name_ = provider_name;
108  }
109  const GUID& provider_name() const { return provider_name_; }
110  TRACEHANDLE registration_handle() const { return registration_handle_; }
111  TRACEHANDLE session_handle() const { return session_handle_; }
112  EtwEventFlags enable_flags() const { return enable_flags_; }
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".
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.
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.
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.
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