MCPcopy Create free account
hub / github.com/GameTechDev/PresentMon / EtwLogSession

Method EtwLogSession

IntelPresentMon/PresentMonService/EtwLogSession.cpp:44–111  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

42 }
43
44 EtwLogSession::EtwLogSession(const std::wstring& loggerName, const std::filesystem::path& logFileDirectory,
45 std::span<const EtwProviderDescription> providers)
46 {
47 // assemble the path for the etl file
48 auto logFilePath = logFileDirectory / file::TempFile::MakeRandomName();
49 // create / start the trace session that outputs to .etl file
50 traceProps_.Wnode.BufferSize = sizeof(traceProps_);
51 traceProps_.MaximumFileSize = 1024;
52 traceProps_.Wnode.Flags = WNODE_FLAG_TRACED_GUID;
53 traceProps_.Wnode.ClientContext = TIMESTAMP_TYPE_QPC;
54 traceProps_.LogFileMode = EVENT_TRACE_FILE_MODE_SEQUENTIAL;
55 traceProps_.LoggerNameOffset = offsetof(TraceProperties_, LoggerName);
56 traceProps_.LogFileNameOffset = offsetof(TraceProperties_, LogFileName);
57 // consider zeroing this to match PresentData
58 traceProps_.BufferSize = 64;
59 wcscpy_s(traceProps_.LoggerName, std::size(traceProps_.LoggerName), loggerName.c_str());
60 wcscpy_s(traceProps_.LogFileName, std::size(traceProps_.LogFileName), logFilePath.c_str());
61 // create the trace logger session
62 if (auto sta = StartTraceW(&hTraceSession_, traceProps_.LoggerName, &traceProps_);
63 sta != ERROR_SUCCESS) {
64 pmlog_error("Failed to start ETL trace").hr(sta).raise<util::Exception>();
65 }
66 // enable providers with various filter mechanisms base on the injected provider descriptions
67 for (auto& p : providers) {
68 // filter by event id if there are any ids captured by the listener (otherwise assume unfiltered)
69 if (!p.events.empty()) {
70 // event filter that filters by event ID whitelist, payload size is dynamic so allocate blob
71 // EVENT_FILTER_EVENT_ID contains a ushort placeholder representing start of array we subtract
72 const size_t eventIdFilterSize = sizeof(EVENT_FILTER_EVENT_ID) +
73 sizeof(USHORT) * (p.events.size() - ANYSIZE_ARRAY);
74 auto pEventIdFilter = static_cast<EVENT_FILTER_EVENT_ID*>(alloca(eventIdFilterSize));
75 pEventIdFilter->FilterIn = TRUE;
76 pEventIdFilter->Reserved = 0;
77 pEventIdFilter->Count = (USHORT)p.events.size();
78 rn::copy(p.events, pEventIdFilter->Events);
79 // descriptor for the event filter
80 EVENT_FILTER_DESCRIPTOR filterDesc{
81 .Ptr = reinterpret_cast<ULONGLONG>(pEventIdFilter),
82 .Size = (ULONG)eventIdFilterSize,
83 .Type = EVENT_FILTER_TYPE_EVENT_ID,
84 };
85 // parameter struct to feed our filter into the enable call
86 ENABLE_TRACE_PARAMETERS enableParams{
87 .Version = ENABLE_TRACE_PARAMETERS_VERSION_2,
88 .EnableProperty = EVENT_ENABLE_PROPERTY_IGNORE_KEYWORD_0,
89 .SourceId = traceProps_.Wnode.Guid,
90 .EnableFilterDesc = &filterDesc,
91 .FilterDescCount = 1,
92 };
93 // enable the provider with event id filter
94 if (auto sta = EnableTraceEx2(hTraceSession_, &p.providerGuid, p.controlCode, p.maxLevel,
95 p.anyKeyMask, p.allKeyMask, 0, &enableParams); sta != ERROR_SUCCESS) {
96 auto providerGuid = util::str::ToNarrow(util::win::GuidToString(p.providerGuid));
97 pmlog_warn("Failed to enable ETW provider").hr(sta).pmwatch(providerGuid);
98 }
99 }
100 else {
101 // enable the provider without event filter

Callers

nothing calls this directly

Calls 6

copyFunction · 0.85
ToNarrowFunction · 0.85
GuidToStringFunction · 0.85
emptyMethod · 0.80
sizeFunction · 0.50
sizeMethod · 0.45

Tested by

no test coverage detected