Skip to content

Commit fb19a3b

Browse files
authored
Merge pull request #60 from intel-innersource/feature/dbg-diagnostics
Feature/dbg diagnostics
2 parents 173319d + 868ef54 commit fb19a3b

File tree

78 files changed

+1247
-233
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+1247
-233
lines changed

IntelPresentMon/AppCef/source/SchemeFileHandler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ namespace p2c::client::cef
5858
return false;
5959
}
6060

61-
pmlog_info(std::format(L"Opening file: {}", file_path_.wstring()));
61+
pmlog_dbg(std::format(L"Opening file: {}", file_path_.wstring()));
6262
return true;
6363
}
6464

IntelPresentMon/AppCef/source/SchemeHandlerFactory.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ namespace p2c::client::cef
7070
return nullptr;
7171
}
7272
else {
73-
pmlog_info(std::format(L"Processing request URL: {}", request->GetURL().ToWString()));
73+
pmlog_dbg(std::format(L"Processing request URL: {}", request->GetURL().ToWString()));
7474
}
7575
return new SchemeFileHandler(baseDir_);
7676
}

IntelPresentMon/AppCef/source/winmain.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
#include "NanoCefProcessHandler.h"
55
#include "../resource.h"
66
#include <Core/source/infra/Logging.h>
7+
#include <Core/source/infra/LogSetup.h>
78
#include <Core/source/infra/util/FolderResolver.h>
89
#include <Core/source/cli/CliOptions.h>
910
#include <CommonUtilities/log/IdentificationTable.h>
1011
#include <CommonUtilities/generated/build_id.h>
12+
#include <PresentMonAPIWrapper/DiagnosticHandler.h>
1113
#include <dwmapi.h>
1214

1315
#pragma comment(lib, "Dwmapi.lib")
@@ -202,8 +204,21 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
202204
DebugBreak();
203205
}
204206
// name this process / thread
205-
log::IdentificationTable::AddThisProcess(str::ToWide(Options::Get().cefType.AsOptional().value_or("main-client")));
207+
log::IdentificationTable::AddThisProcess(str::ToWide(opt.cefType.AsOptional().value_or("main-client")));
206208
log::IdentificationTable::AddThisThread(L"main");
209+
// connect to the diagnostic layer
210+
std::optional<pmapi::DiagnosticHandler> diag;
211+
if (opt.enableDiagnostic && opt.cefType && *opt.cefType == "renderer") {
212+
diag.emplace(
213+
(PM_DIAGNOSTIC_LEVEL)opt.logLevel.AsOptional().value_or(log::GlobalPolicy::Get().GetLogLevel()),
214+
PM_DIAGNOSTIC_OUTPUT_FLAGS_DEBUGGER | PM_DIAGNOSTIC_OUTPUT_FLAGS_QUEUE,
215+
[](const PM_DIAGNOSTIC_MESSAGE& msg) {
216+
auto ts = msg.pTimestamp ? str::ToWide(msg.pTimestamp) : std::wstring{};
217+
pmlog_(log::Level(msg.level)).note(
218+
std::format(L"@@ D I A G @@ => <{}> {}", ts, str::ToWide(msg.pText)));
219+
}
220+
);
221+
}
207222
// configure the logging system (partially based on command line options)
208223
ConfigureLogging();
209224

IntelPresentMon/CommonUtilities/CommonUtilities.vcxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
<ClInclude Include="cli\CliFramework.h" />
2323
<ClInclude Include="Exception.h" />
2424
<ClInclude Include="log\CopyDriver.h" />
25+
<ClInclude Include="log\DiagnosticDriver.h" />
2526
<ClInclude Include="log\ErrorCode.h" />
2627
<ClInclude Include="log\EntryMarshallInjector.h" />
2728
<ClInclude Include="log\EntryCereal.h" />
@@ -53,6 +54,7 @@
5354
<ClInclude Include="log\NamedPipeMarshallReceiver.h" />
5455
<ClInclude Include="log\StackTrace.h" />
5556
<ClInclude Include="log\StackTraceCereal.h" />
57+
<ClInclude Include="log\Subsystem.h" />
5658
<ClInclude Include="log\TextFormatter.h" />
5759
<ClInclude Include="log\MarshallDriver.h" />
5860
<ClInclude Include="log\TimePoint.h" />
@@ -77,6 +79,7 @@
7779
<ClCompile Include="cli\CliFramework.cpp" />
7880
<ClCompile Include="Exception.cpp" />
7981
<ClCompile Include="log\CopyDriver.cpp" />
82+
<ClCompile Include="log\DiagnosticDriver.cpp" />
8083
<ClCompile Include="log\EntryMarshallInjector.cpp" />
8184
<ClCompile Include="Hash.cpp" />
8285
<ClCompile Include="log\Channel.cpp" />
@@ -95,6 +98,7 @@
9598
<ClCompile Include="log\BasicFileDriver.cpp" />
9699
<ClCompile Include="log\NamedPipeMarshallReceiver.cpp" />
97100
<ClCompile Include="log\StackTrace.cpp" />
101+
<ClCompile Include="log\Subsystem.cpp" />
98102
<ClCompile Include="log\TextFormatter.cpp" />
99103
<ClCompile Include="log\SimpleFileStrategy.cpp" />
100104
<ClCompile Include="log\PanicLogger.cpp" />

IntelPresentMon/CommonUtilities/CommonUtilities.vcxproj.filters

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,12 @@
174174
<ClInclude Include="Math.h">
175175
<Filter>Header Files</Filter>
176176
</ClInclude>
177+
<ClInclude Include="log\Subsystem.h">
178+
<Filter>Header Files</Filter>
179+
</ClInclude>
180+
<ClInclude Include="log\DiagnosticDriver.h">
181+
<Filter>Header Files</Filter>
182+
</ClInclude>
177183
</ItemGroup>
178184
<ItemGroup>
179185
<ClCompile Include="cli\CliFramework.cpp">
@@ -275,6 +281,12 @@
275281
<ClCompile Include="log\TimePoint.cpp">
276282
<Filter>Source Files</Filter>
277283
</ClCompile>
284+
<ClCompile Include="log\Subsystem.cpp">
285+
<Filter>Source Files</Filter>
286+
</ClCompile>
287+
<ClCompile Include="log\DiagnosticDriver.cpp">
288+
<Filter>Source Files</Filter>
289+
</ClCompile>
278290
</ItemGroup>
279291
<ItemGroup>
280292
<None Include="vcpkg.json" />

IntelPresentMon/CommonUtilities/Exception.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ namespace pmon::util
7878
std::rethrow_exception(pEx);
7979
}
8080
catch (const std::exception& e) {
81-
return std::format("[{}]\n{}", typeid(e).name(), e.what());
81+
return std::format("[{}] {}", typeid(e).name(), e.what());
8282
}
8383
catch (...) {
8484
return "Unrecognized exception";

IntelPresentMon/CommonUtilities/Exception.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,6 @@ namespace pmon::util
5454

5555
// prevent any exceptions from leaking from this statement
5656
#define pmquell(stat) try { stat; } catch (...) {}
57+
58+
#define pmcatch_report catch (...) { pmlog_error(::pmon::util::ReportExceptionWide()); }
5759
}

IntelPresentMon/CommonUtilities/cli/CliFramework.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ namespace pmon::util::cli
130130
{
131131
// create the option
132132
pOption_ = pParent->app_.add_option(std::move(names), data_, std::move(description));
133+
// if customizer is a Validator object, add it to the option
133134
if constexpr (std::is_base_of_v<CLI::Validator, std::decay_t<U>> ) {
134135
if (customizer.get_modifying()) {
135136
pOption_->transform(std::forward<U>(customizer));
@@ -138,7 +139,7 @@ namespace pmon::util::cli
138139
pOption_->check(std::forward<U>(customizer));
139140
}
140141
}
141-
else {
142+
else { // if customizer not a Validator, assume it's a function that works on the Option and call it
142143
customizer(pOption_);
143144
}
144145
OptionCommonPostCreate_(pParent);
@@ -184,7 +185,9 @@ namespace pmon::util::cli
184185
void OptionCommonPostCreate_(OptionsContainer* pParent)
185186
{
186187
// add to active group
187-
pOption_->group(pParent->activeGroup_);
188+
if (!pParent->activeGroup_.empty()) {
189+
pOption_->group(pParent->activeGroup_);
190+
}
188191
// capture main name for the option (used when forwarding)
189192
SetName_(pOption_->get_name());
190193
// capture the raw input string
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
#include "DiagnosticDriver.h"
2+
#include "../Exception.h"
3+
#include "../win/WinAPI.h"
4+
#include <iostream>
5+
#include <span>
6+
#include <algorithm>
7+
8+
using namespace std::chrono_literals;
9+
namespace rn = std::ranges;
10+
11+
namespace pmon::util::log
12+
{
13+
DiagnosticDriver::DiagnosticDriver(const PM_DIAGNOSTIC_CONFIGURATION* pConfig)
14+
{
15+
if (pConfig) {
16+
config_ = DiagnosticConfig{ *pConfig };
17+
}
18+
}
19+
DiagnosticDriver::~DiagnosticDriver()
20+
{
21+
dying_ = true;
22+
manualUnblockEvent_.Set();
23+
}
24+
void DiagnosticDriver::Submit(const Entry& e)
25+
{
26+
// ignore non-diagnostic entries and low-priority levels
27+
if (!e.diagnosticLayer_ || int(e.level_) > int(config_.filterLevel)) {
28+
return;
29+
}
30+
// filtering by subsystem
31+
if (!config_.subsystems.empty() && !rn::contains(config_.subsystems,
32+
(PM_DIAGNOSTIC_SUBSYSTEM)e.subsystem_)) {
33+
return;
34+
}
35+
// prepare string payloads
36+
auto msg = str::ToNarrow(e.note_);
37+
std::string timestamp;
38+
if (config_.enableTimestamp) {
39+
const auto zt = std::chrono::zoned_time{ std::chrono::current_zone(), e.timestamp_ };
40+
timestamp = std::format("{}", zt);
41+
}
42+
std::string trace;
43+
if (config_.enableTrace) {
44+
if (e.pTrace_ && e.pTrace_->Resolved()) {
45+
trace = str::ToNarrow(e.pTrace_->ToString());
46+
}
47+
}
48+
std::string location;
49+
if (config_.enableLocation) {
50+
location = std::format("{}({})", str::ToNarrow(e.GetSourceFileName()), e.sourceLine_);
51+
}
52+
// create diagnostic message based on logging entry
53+
auto pMessage = std::make_unique<DiagnosticMessage>();
54+
// set values
55+
pMessage->level = (PM_DIAGNOSTIC_LEVEL)e.level_;
56+
pMessage->system = (PM_DIAGNOSTIC_SUBSYSTEM)e.subsystem_;
57+
pMessage->pid = e.pid_;
58+
pMessage->tid = e.tid_;
59+
// handle buffers
60+
pMessage->messageBuffer_ = std::move(msg);
61+
pMessage->locationBuffer_ = std::move(location);
62+
pMessage->timestampBuffer_ = std::move(timestamp);
63+
pMessage->traceBuffer_ = std::move(trace);
64+
pMessage->SyncBuffers_();
65+
// process message
66+
ProcessCommon_(std::move(pMessage));
67+
}
68+
void DiagnosticDriver::Flush() {}
69+
uint32_t DiagnosticDriver::GetQueuedMessageCount()
70+
{
71+
return (uint32_t)messageQueue_.size_approx();
72+
}
73+
uint32_t DiagnosticDriver::GetMaxQueuedMessages()
74+
{
75+
return maxQueuedMessages_;
76+
}
77+
void DiagnosticDriver::SetMaxQueuedMessages(uint32_t max)
78+
{
79+
maxQueuedMessages_ = max;
80+
}
81+
uint32_t DiagnosticDriver::GetDiscardedMessageCount()
82+
{
83+
return discardedCount_;
84+
}
85+
std::unique_ptr<DiagnosticMessage> DiagnosticDriver::DequeueMessage()
86+
{
87+
messageWaitEvent_.Reset();
88+
std::unique_ptr<DiagnosticMessage> pMessage;
89+
messageQueue_.try_dequeue(pMessage);
90+
return pMessage;
91+
}
92+
void DiagnosticDriver::EnqueueMessage(const PM_DIAGNOSTIC_MESSAGE* pMessage)
93+
{
94+
if (!pMessage) {
95+
throw Except<Exception>("Diagnostic message injection with null message pointer");
96+
}
97+
ProcessCommon_(std::make_unique<DiagnosticMessage>(*pMessage));
98+
}
99+
PM_DIAGNOSTIC_WAKE_REASON DiagnosticDriver::WaitForMessage(uint32_t timeoutMs)
100+
{
101+
if (GetQueuedMessageCount() > 0) {
102+
return PM_DIAGNOSTIC_WAKE_REASON_MESSAGE_AVAILABLE;
103+
}
104+
const auto wakeSignal = timeoutMs ?
105+
win::WaitAnyEventFor(timeoutMs * 1ms, messageWaitEvent_, manualUnblockEvent_) :
106+
win::WaitAnyEvent(messageWaitEvent_, manualUnblockEvent_);
107+
if (!wakeSignal) {
108+
return PM_DIAGNOSTIC_WAKE_REASON_TIMEOUT;
109+
}
110+
if (*wakeSignal == 0) {
111+
return PM_DIAGNOSTIC_WAKE_REASON_MESSAGE_AVAILABLE;
112+
}
113+
if (*wakeSignal == 1) {
114+
return dying_ ?
115+
PM_DIAGNOSTIC_WAKE_REASON_SHUTDOWN :
116+
PM_DIAGNOSTIC_WAKE_REASON_MANUAL_UNBLOCK;
117+
}
118+
throw Except<Exception>("Bad event index waiting on message+unblock events");
119+
}
120+
void DiagnosticDriver::UnblockWaitingThread()
121+
{
122+
manualUnblockEvent_.Set();
123+
}
124+
void DiagnosticDriver::Enqueue_(std::unique_ptr<DiagnosticMessage> pMsg)
125+
{
126+
// ensure that # of queued does not exceed max
127+
while (GetQueuedMessageCount() >= GetMaxQueuedMessages()) {
128+
std::unique_ptr<DiagnosticMessage> p;
129+
if (messageQueue_.try_dequeue(p)) {
130+
discardedCount_++;
131+
}
132+
}
133+
// enqueue the message
134+
messageQueue_.enqueue(std::move(pMsg));
135+
// signal message availability
136+
messageWaitEvent_.Set();
137+
}
138+
void DiagnosticDriver::ProcessCommon_(std::unique_ptr<DiagnosticMessage> pMsg)
139+
{
140+
using namespace std::string_literals;
141+
// handle direct output
142+
std::string formattedMsg;
143+
auto format = [&] { if (formattedMsg.empty()) {
144+
auto level = str::ToNarrow(GetLevelName((Level)pMsg->level));
145+
auto sys = str::ToNarrow(GetSubsystemName((Subsystem)pMsg->system));
146+
if (pMsg->pTimestamp) {
147+
formattedMsg = std::format("[PMON:{} {}] {{{}}} {}\n", sys, level, pMsg->pTimestamp, pMsg->pText);
148+
}
149+
else {
150+
formattedMsg = std::format("[PMON:{} {}] {}\n", sys, level, pMsg->pText);
151+
}
152+
} };
153+
// output formatted string directly to active media
154+
if (config_.outputFlags & PM_DIAGNOSTIC_OUTPUT_FLAGS_DEBUGGER) {
155+
format();
156+
OutputDebugStringA(formattedMsg.c_str());
157+
}
158+
if (config_.outputFlags & PM_DIAGNOSTIC_OUTPUT_FLAGS_STDERR) {
159+
format();
160+
std::cerr << formattedMsg;
161+
}
162+
if (config_.outputFlags & PM_DIAGNOSTIC_OUTPUT_FLAGS_STDOUT) {
163+
format();
164+
std::cout << formattedMsg;
165+
}
166+
// handle queue
167+
if (config_.outputFlags & PM_DIAGNOSTIC_OUTPUT_FLAGS_QUEUE) {
168+
Enqueue_(std::move(pMsg));
169+
}
170+
}
171+
DiagnosticConfig::DiagnosticConfig(const PM_DIAGNOSTIC_CONFIGURATION& src)
172+
:
173+
PM_DIAGNOSTIC_CONFIGURATION{ src }
174+
{
175+
if (src.pSubsystems) {
176+
subsystems.append_range(std::span(src.pSubsystems, src.nSubsystems));
177+
nSubsystems = (uint32_t)subsystems.size();
178+
}
179+
}
180+
DiagnosticConfig::DiagnosticConfig()
181+
:
182+
PM_DIAGNOSTIC_CONFIGURATION{
183+
.filterLevel{ PM_DIAGNOSTIC_LEVEL_WARNING },
184+
.outputFlags{ PM_DIAGNOSTIC_OUTPUT_FLAGS_DEBUGGER },
185+
.pSubsystems{ nullptr },
186+
.nSubsystems{ 0 },
187+
.enableTimestamp{ false },
188+
.enableTrace{ PM_DIAGNOSTIC_LEVEL_NONE },
189+
.enableLocation{ false }
190+
}
191+
{}
192+
DiagnosticMessage::DiagnosticMessage(const PM_DIAGNOSTIC_MESSAGE& msg)
193+
:
194+
PM_DIAGNOSTIC_MESSAGE{ msg }
195+
{
196+
if (!msg.pText) {
197+
throw Except<Exception>("Diagnostic message text pointer not set");
198+
}
199+
messageBuffer_ = msg.pText;
200+
if (msg.pTimestamp) {
201+
timestampBuffer_ = msg.pTimestamp;
202+
}
203+
if (msg.pTrace) {
204+
traceBuffer_ = msg.pTrace;
205+
}
206+
if (msg.pLocation) {
207+
locationBuffer_ = msg.pLocation;
208+
}
209+
SyncBuffers_();
210+
}
211+
DiagnosticMessage::DiagnosticMessage() : PM_DIAGNOSTIC_MESSAGE{}
212+
{}
213+
void DiagnosticMessage::SyncBuffers_()
214+
{
215+
if (!messageBuffer_.empty()) {
216+
pText = messageBuffer_.c_str();
217+
}
218+
if (!timestampBuffer_.empty()) {
219+
pTimestamp = timestampBuffer_.c_str();
220+
}
221+
if (!traceBuffer_.empty()) {
222+
pTrace = traceBuffer_.c_str();
223+
}
224+
if (!locationBuffer_.empty()) {
225+
pLocation = locationBuffer_.c_str();
226+
}
227+
}
228+
}

0 commit comments

Comments
 (0)