1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
base / win / event_trace_controller.h [blame]
// Copyright 2011 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
#pragma allow_unsafe_buffers
#endif
// Declaration of a Windows event trace controller class.
// The controller takes care of creating and manipulating event trace
// sessions.
//
// Event tracing for Windows is a system-provided service that provides
// logging control and high-performance transport for generic, binary trace
// events. Event trace providers register with the system by their name,
// which is a GUID, and can from that point forward receive callbacks that
// start or end tracing and that change their trace level and enable mask.
//
// A trace controller can create an event tracing session, which either
// sends events to a binary file, or to a realtime consumer, or both.
//
// A trace consumer consumes events from zero or one realtime session,
// as well as potentially from multiple binary trace files.
#ifndef BASE_WIN_EVENT_TRACE_CONTROLLER_H_
#define BASE_WIN_EVENT_TRACE_CONTROLLER_H_
#include <windows.h>
#include <evntrace.h>
#include <stddef.h>
#include <wmistr.h>
#include <string>
#include "base/base_export.h"
namespace base {
namespace win {
// Utility class to make it easier to work with EVENT_TRACE_PROPERTIES.
// The EVENT_TRACE_PROPERTIES structure contains information about an
// event tracing session.
class BASE_EXPORT EtwTraceProperties {
public:
EtwTraceProperties();
EtwTraceProperties(const EtwTraceProperties&) = delete;
EtwTraceProperties& operator=(const EtwTraceProperties&) = delete;
EVENT_TRACE_PROPERTIES* get() { return &properties_; }
const EVENT_TRACE_PROPERTIES* get() const {
return reinterpret_cast<const EVENT_TRACE_PROPERTIES*>(&properties_);
}
const wchar_t* GetLoggerName() const {
return reinterpret_cast<const wchar_t*>(buffer_ + get()->LoggerNameOffset);
}
// Copies logger_name to the properties structure.
HRESULT SetLoggerName(const wchar_t* logger_name);
const wchar_t* GetLoggerFileName() const {
return reinterpret_cast<const wchar_t*>(buffer_ + get()->LogFileNameOffset);
}
// Copies logger_file_name to the properties structure.
HRESULT SetLoggerFileName(const wchar_t* logger_file_name);
// Max string len for name and session name is 1024 per documentation.
static const size_t kMaxStringLen = 1024;
// Properties buffer allocates space for header and for
// max length for name and session name.
static const size_t kBufSize =
sizeof(EVENT_TRACE_PROPERTIES) + 2 * sizeof(wchar_t) * (kMaxStringLen);
private:
// The EVENT_TRACE_PROPERTIES structure needs to be overlaid on a
// larger buffer to allow storing the logger name and logger file
// name contiguously with the structure.
union {
// Our properties header.
EVENT_TRACE_PROPERTIES properties_;
// The actual size of the buffer is forced by this member.
char buffer_[kBufSize];
};
};
// This class implements an ETW controller, which knows how to start and
// stop event tracing sessions, as well as controlling ETW provider
// log levels and enable bit masks under the session.
class BASE_EXPORT EtwTraceController {
public:
EtwTraceController();
EtwTraceController(const EtwTraceController&) = delete;
EtwTraceController& operator=(const EtwTraceController&) = delete;
~EtwTraceController();
// Start a session with given name and properties.
HRESULT Start(const wchar_t* session_name, EtwTraceProperties* prop);
// Starts a session tracing to a file with some default properties.
HRESULT StartFileSession(const wchar_t* session_name,
const wchar_t* logfile_path,
bool realtime = false);
// Starts a realtime session with some default properties. |buffer_size| is
// in KB. A default value for |buffer_size| is used if 0 is passed in.
HRESULT StartRealtimeSession(const wchar_t* session_name, size_t buffer_size);
// Enables "provider" at "level" for this session.
// This will cause all providers registered with the GUID
// "provider" to start tracing at the new level, systemwide.
HRESULT EnableProvider(const GUID& provider,
UCHAR level,
ULONG flags = 0xFFFFFFFF);
// Disables "provider".
HRESULT DisableProvider(const GUID& provider);
// Stops our session and retrieve the new properties of the session,
// properties may be NULL.
HRESULT Stop(EtwTraceProperties* properties);
// Flushes our session and retrieve the current properties,
// properties may be NULL.
HRESULT Flush(EtwTraceProperties* properties);
// Static utility functions for controlling
// sessions we don't necessarily own.
static HRESULT Start(const wchar_t* session_name,
EtwTraceProperties* properties,
TRACEHANDLE* session_handle);
static HRESULT Query(const wchar_t* session_name,
EtwTraceProperties* properties);
static HRESULT Update(const wchar_t* session_name,
EtwTraceProperties* properties);
static HRESULT Stop(const wchar_t* session_name,
EtwTraceProperties* properties);
static HRESULT Flush(const wchar_t* session_name,
EtwTraceProperties* properties);
// Accessors.
TRACEHANDLE session() const { return session_; }
const wchar_t* session_name() const { return session_name_.c_str(); }
private:
std::wstring session_name_;
TRACEHANDLE session_ = NULL;
};
} // namespace win
} // namespace base
#endif // BASE_WIN_EVENT_TRACE_CONTROLLER_H_