Home | History | Annotate | Download | only in win
      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 
     42   EtwMofEvent() {
     43     memset(static_cast<Super*>(this), 0, sizeof(Super));
     44   }
     45 
     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 
     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 
     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 
     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.
    110   void set_provider_name(const GUID& provider_name) {
    111     provider_name_ = provider_name;
    112   }
    113   const GUID& provider_name() const { return provider_name_; }
    114   TRACEHANDLE registration_handle() const { return registration_handle_; }
    115   TRACEHANDLE session_handle() const { return session_handle_; }
    116   EtwEventFlags enable_flags() const { return enable_flags_; }
    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".
    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.
    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.
    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.
    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