Home | History | Annotate | Download | only in base
      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 
     32   EtwMofEvent() {
     33     memset(static_cast<Super*>(this), 0, sizeof(Super));
     34   }
     35 
     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 
     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 
     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 
     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.
    100   void set_provider_name(const GUID& provider_name) {
    101     provider_name_ = provider_name;
    102   }
    103   const GUID& provider_name() const { return provider_name_; }
    104   TRACEHANDLE registration_handle() const { return registration_handle_; }
    105   TRACEHANDLE session_handle() const { return session_handle_; }
    106   EtwEventFlags enable_flags() const { return enable_flags_; }
    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".
    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.
    132   virtual void OnEventsEnabled() {}
    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