Task 45828333: Move existing ETW tracing into LHC (#772)

This commit is contained in:
tculotta 2023-08-04 11:17:52 -07:00 коммит произвёл GitHub
Родитель cc017c12da
Коммит 670f91ce4b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 123 добавлений и 12 удалений

Просмотреть файл

@ -208,6 +208,12 @@ STDAPI_(void) HCTraceSetClientCallback(_In_opt_ HCTraceCallback* callback) noexc
/// <returns></returns>
STDAPI_(void) HCTraceSetTraceToDebugger(_In_ bool traceToDebugger) noexcept;
#if HC_PLATFORM_IS_MICROSOFT
/// <summary>
/// Enables or disables ETW tracing for Xbox and PC platforms.
/// </summary>
STDAPI_(void) HCTraceSetEtwEnabled(_In_ bool enabled) noexcept;
#endif
//------------------------------------------------------------------------------
// Trace macros

Просмотреть файл

@ -14,6 +14,10 @@
#include "utils.h"
#include "Platform/PlatformTrace.h"
#if HC_PLATFORM_IS_MICROSOFT
#include <TraceLoggingProvider.h>
#endif
namespace
{
@ -46,21 +50,49 @@ int vsprintf_s(char(&buffer)[SIZE], _Printf_format_string_ char const* format, v
#endif
#endif
#if HC_PLATFORM_IS_MICROSOFT
TRACELOGGING_DEFINE_PROVIDER(
g_hTraceLoggingProvider,
"libHttpClient",
(0x2b6274b2, 0x159f, 0x4e6f, 0xb8, 0x0, 0xd, 0x17, 0x0, 0x9e, 0x14, 0x7a) // {2B6274B2-159F-4E6F-B800-0D17009E147A}
);
// Helper method to ensure our ETW Provider never gets registered twice. Registering an ETW provider twice may result
// in a crash or undefined behavior. See https://learn.microsoft.com/en-us/windows/win32/api/traceloggingprovider/nf-traceloggingprovider-traceloggingregister
// for more details.
void RegisterProvider()
{
struct ProviderRegistrar
{
ProviderRegistrar()
{
TraceLoggingRegister(g_hTraceLoggingProvider);
}
~ProviderRegistrar()
{
TraceLoggingUnregister(g_hTraceLoggingProvider);
}
};
static ProviderRegistrar s_registrar{};
}
#endif
//------------------------------------------------------------------------------
// Trace implementation
//------------------------------------------------------------------------------
void TraceMessageToDebugger(
template<size_t SIZE>
void FormatTrace(
char const* areaName,
HCTraceLevel level,
uint64_t threadId,
uint64_t timestamp,
char const* message
) noexcept
char const* message,
char (&outputBuffer)[SIZE]
)
{
if (!GetTraceState().GetTraceToDebugger())
return;
// Needs to match the HCTraceLevel enum
static char const* traceLevelNames[] =
{
@ -72,8 +104,6 @@ void TraceMessageToDebugger(
"V",
};
static size_t const BUFFER_SIZE = 4096;
std::time_t timeTInSec = static_cast<std::time_t>(timestamp / 1000);
uint32_t fractionMSec = static_cast<uint32_t>(timestamp % 1000);
std::tm fmtTime = {};
@ -86,7 +116,6 @@ void TraceMessageToDebugger(
localtime_r(&timeTInSec, &fmtTime);
#endif
char outputBuffer[BUFFER_SIZE] = {};
// [threadId][level][time][area] message
auto written = sprintf_s(outputBuffer, "[%04llX][%s][%02d:%02d:%02d.%03u][%s] %s",
threadId,
@ -104,8 +133,8 @@ void TraceMessageToDebugger(
}
// Make sure there is room for the \r \n and \0
written = std::min(written, static_cast<int>(BUFFER_SIZE - 3));
auto remaining = BUFFER_SIZE - written;
written = std::min(written, static_cast<int>(SIZE - 3));
auto remaining = SIZE - written;
// Print new line
auto written2 = sprintf_s(outputBuffer + written, remaining, "\r\n");
@ -113,6 +142,24 @@ void TraceMessageToDebugger(
{
return;
}
}
void TraceMessageToDebugger(
char const* areaName,
HCTraceLevel level,
uint64_t threadId,
uint64_t timestamp,
char const* message
) noexcept
{
if (!GetTraceState().GetTraceToDebugger())
{
return;
}
static size_t const BUFFER_SIZE = 4096;
char outputBuffer[BUFFER_SIZE] = {};
FormatTrace(areaName, level, threadId, timestamp, message, outputBuffer);
xbox::httpclient::TraceToDebugger(areaName, level, outputBuffer);
}
@ -132,6 +179,32 @@ void TraceMessageToClient(
}
}
#if HC_PLATFORM_IS_MICROSOFT
void TraceMessageToETW(
char const* areaName,
HCTraceLevel level,
uint64_t threadId,
uint64_t timestamp,
char const* message
) noexcept
{
if (!GetTraceState().GetEtwEnabled())
{
return;
}
static size_t const BUFFER_SIZE = 4096;
char outputBuffer[BUFFER_SIZE] = {};
FormatTrace(areaName, level, threadId, timestamp, message, outputBuffer);
TraceLoggingWrite(
g_hTraceLoggingProvider,
"libHttpClient_TraceMessage",
TraceLoggingString(outputBuffer, "Message")
);
}
#endif
}
STDAPI_(void) HCTraceSetTraceToDebugger(_In_ bool traceToDebugger) noexcept
@ -144,6 +217,18 @@ STDAPI_(void) HCTraceSetClientCallback(_In_opt_ HCTraceCallback* callback) noexc
GetTraceState().SetClientCallback(callback);
}
#if HC_PLATFORM_IS_MICROSOFT
STDAPI_(void) HCTraceSetEtwEnabled(_In_ bool enabled) noexcept
{
GetTraceState().SetEtwEnabled(enabled);
if (enabled)
{
RegisterProvider();
}
}
#endif
STDAPI_(void) HCTraceImplMessage(
struct HCTraceImplArea const* area,
HCTraceLevel level,
@ -185,7 +270,7 @@ STDAPI_(void) HCTraceImplMessage_v(
}
// Only do work if there's reason to
if (GetTraceState().GetClientCallback() == nullptr && !GetTraceState().GetTraceToDebugger())
if (GetTraceState().GetClientCallback() == nullptr && !GetTraceState().GetTraceToDebugger() && !GetTraceState().GetEtwEnabled())
{
return;
}
@ -204,6 +289,9 @@ STDAPI_(void) HCTraceImplMessage_v(
TraceMessageToDebugger(area->Name, level, threadId, timestamp, message);
TraceMessageToClient(area->Name, level, threadId, timestamp, message);
#if HC_PLATFORM_IS_MICROSOFT
TraceMessageToETW(area->Name, level, threadId, timestamp, message);
#endif
}
STDAPI_(uint64_t) HCTraceImplScopeId() noexcept
@ -244,6 +332,18 @@ void TraceState::SetTraceToDebugger(_In_ bool traceToDebugger) noexcept
m_traceToDebugger = traceToDebugger;
}
bool TraceState::GetEtwEnabled() const noexcept
{
return m_etwEnabled;
}
#if HC_PLATFORM_IS_MICROSOFT
void TraceState::SetEtwEnabled(_In_ bool etwEnabled) noexcept
{
m_etwEnabled = etwEnabled;
}
#endif
void TraceState::SetClientCallback(HCTraceCallback* callback) noexcept
{
m_clientCallback = callback;

Просмотреть файл

@ -14,6 +14,10 @@ public:
void SetClientCallback(HCTraceCallback* callback) noexcept;
HCTraceCallback* GetClientCallback() const noexcept;
uint64_t GetTimestamp() const noexcept;
bool GetEtwEnabled() const noexcept;
#if HC_PLATFORM_IS_MICROSOFT
void SetEtwEnabled(_In_ bool enabled) noexcept;
#endif
private:
std::atomic<uint32_t> m_tracingClients{ 0 };
@ -23,6 +27,7 @@ private:
};
std::atomic<HCTraceCallback*> m_clientCallback{ nullptr };
bool m_traceToDebugger = false;
bool m_etwEnabled = false;
};
TraceState& GetTraceState() noexcept;