c910045187
*cfc72cee
(origin/dev/duhowett/ibxint, github/master) Make sure cursor blinks after opening new tab (1030) *9ad25440
Fix #936: misuse of uninitialized objects causes AppVerifier breaks on Windows Terminal startup (1015) *5f938a04
Update Terminal.cpp (1034) *4c47631b
Cleanup - termDispatch.hpp & adaptDispatch.hpp overrides (1004) *cc304759
add audit mode to ci (948) *80f10796
Fix the bell sound when Alt+key is pressed. (1006) *42e87ed3
fix build break from using `await` instead of `co_await` (1009) *40b557a4
Update manifest to correct 1903 version, unref param fix (1008) *0f62ec81
Eat all tap keypresses no matter what. (985) *ce0eaab9
inbox: Merge accumulated build fixes from RS_ONECORE_DEP_ACIOSS (1002) *1c509683
add .editorconfig file (585) *efd69990
Add support for OSC 10 and 11 to set the default colors (891) Related work items: #21610659, #21838182
254 lines
9.6 KiB
C++
254 lines
9.6 KiB
C++
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT license.
|
|
|
|
#include <precomp.h>
|
|
|
|
#include "telemetry.hpp"
|
|
|
|
TRACELOGGING_DEFINE_PROVIDER(g_hConsoleVirtTermParserEventTraceProvider,
|
|
"Microsoft.Windows.Console.VirtualTerminal.Parser",
|
|
// {c9ba2a84-d3ca-5e19-2bd6-776a0910cb9d}
|
|
(0xc9ba2a84, 0xd3ca, 0x5e19, 0x2b, 0xd6, 0x77, 0x6a, 0x09, 0x10, 0xcb, 0x9d));
|
|
|
|
using namespace Microsoft::Console::VirtualTerminal;
|
|
|
|
#pragma warning(push)
|
|
// Disable 4351 so we can initialize the arrays to 0 without a warning.
|
|
#pragma warning(disable:4351)
|
|
TermTelemetry::TermTelemetry()
|
|
: _uiTimesUsedCurrent(0),
|
|
_uiTimesFailedCurrent(0),
|
|
_uiTimesFailedOutsideRangeCurrent(0),
|
|
_uiTimesUsed(),
|
|
_uiTimesFailed(),
|
|
_uiTimesFailedOutsideRange(0),
|
|
_activityId(),
|
|
_fShouldWriteFinalLog(false)
|
|
{
|
|
TraceLoggingRegister(g_hConsoleVirtTermParserEventTraceProvider);
|
|
|
|
// Create a random activityId just in case it doesn't get set later in SetActivityId().
|
|
EventActivityIdControl(EVENT_ACTIVITY_CTRL_CREATE_ID, &_activityId);
|
|
}
|
|
#pragma warning(pop)
|
|
|
|
TermTelemetry::~TermTelemetry()
|
|
{
|
|
WriteFinalTraceLog();
|
|
TraceLoggingUnregister(g_hConsoleVirtTermParserEventTraceProvider);
|
|
}
|
|
|
|
// Routine Description:
|
|
// - Logs the usage of a particular VT100 code.
|
|
//
|
|
// Arguments:
|
|
// - code - VT100 code.
|
|
// Return Value:
|
|
// - <none>
|
|
void TermTelemetry::Log(const Codes code)
|
|
{
|
|
// Initially we wanted to pass over a string (ex. "CUU") and use a dictionary data type to hold the counts.
|
|
// However we would have to search through the dictionary every time we called this method, so we decided
|
|
// to use an array which has very quick access times.
|
|
// The downside is we have to create an enum type, and then convert them to strings when we finally
|
|
// send out the telemetry, but the upside is we should have very good performance.
|
|
_uiTimesUsed[code]++;
|
|
_uiTimesUsedCurrent++;
|
|
}
|
|
|
|
// Routine Description:
|
|
// - Logs a particular VT100 escape code failed or was unsupported.
|
|
//
|
|
// Arguments:
|
|
// - code - VT100 code.
|
|
// Return Value:
|
|
// - <none>
|
|
void TermTelemetry::LogFailed(const wchar_t wch)
|
|
{
|
|
if (wch > CHAR_MAX)
|
|
{
|
|
_uiTimesFailedOutsideRange++;
|
|
_uiTimesFailedOutsideRangeCurrent++;
|
|
}
|
|
else
|
|
{
|
|
// Even though we pass over a wide character, we only care about the ASCII single byte character.
|
|
_uiTimesFailed[wch]++;
|
|
_uiTimesFailedCurrent++;
|
|
}
|
|
}
|
|
|
|
// Routine Description:
|
|
// - Gets and resets the total count of codes used.
|
|
//
|
|
// Arguments:
|
|
// - <none>
|
|
// Return Value:
|
|
// - total number.
|
|
unsigned int TermTelemetry::GetAndResetTimesUsedCurrent()
|
|
{
|
|
unsigned int uiTemp = _uiTimesUsedCurrent;
|
|
_uiTimesUsedCurrent = 0;
|
|
return uiTemp;
|
|
}
|
|
|
|
// Routine Description:
|
|
// - Gets and resets the total count of codes failed.
|
|
//
|
|
// Arguments:
|
|
// - <none>
|
|
// Return Value:
|
|
// - total number.
|
|
unsigned int TermTelemetry::GetAndResetTimesFailedCurrent()
|
|
{
|
|
unsigned int uiTemp = _uiTimesFailedCurrent;
|
|
_uiTimesFailedCurrent = 0;
|
|
return uiTemp;
|
|
}
|
|
|
|
// Routine Description:
|
|
// - Gets and resets the total count of codes failed outside the valid range.
|
|
//
|
|
// Arguments:
|
|
// - <none>
|
|
// Return Value:
|
|
// - total number.
|
|
unsigned int TermTelemetry::GetAndResetTimesFailedOutsideRangeCurrent()
|
|
{
|
|
unsigned int uiTemp = _uiTimesFailedOutsideRangeCurrent;
|
|
_uiTimesFailedOutsideRangeCurrent = 0;
|
|
return uiTemp;
|
|
}
|
|
|
|
// Routine Description:
|
|
// - Lets us know whether we should write the final log. Typically set true when the console has been
|
|
// interacted with, to help reduce the amount of telemetry we're sending.
|
|
//
|
|
// Arguments:
|
|
// - writeLog - true if we should write the log.
|
|
// Return Value:
|
|
// - <none>
|
|
void TermTelemetry::SetShouldWriteFinalLog(const bool writeLog)
|
|
{
|
|
_fShouldWriteFinalLog = writeLog;
|
|
}
|
|
|
|
// Routine Description:
|
|
// - Sets the activity Id, so we can match our events with other providers (such as Microsoft.Windows.Console.Host).
|
|
//
|
|
// Arguments:
|
|
// - activityId - Pointer to Guid to set our activity Id to.
|
|
// Return Value:
|
|
// - <none>
|
|
void TermTelemetry::SetActivityId(const GUID *activityId)
|
|
{
|
|
_activityId = *activityId;
|
|
}
|
|
|
|
// Routine Description:
|
|
// - Writes the final log of all the telemetry collected. The primary reason to send back a final log instead
|
|
// of individual events is to reduce the amount of telemetry being sent and potentially overloading our servers.
|
|
//
|
|
// Arguments:
|
|
// - code - VT100 code.
|
|
// Return Value:
|
|
// - <none>
|
|
void TermTelemetry::WriteFinalTraceLog() const
|
|
{
|
|
if (_fShouldWriteFinalLog)
|
|
{
|
|
// Determine if we've logged any VT100 sequences at all.
|
|
bool fLoggedSequence = (_uiTimesFailedOutsideRange > 0);
|
|
|
|
if (!fLoggedSequence)
|
|
{
|
|
for (int n = 0; n < ARRAYSIZE(_uiTimesUsed); n++)
|
|
{
|
|
if (_uiTimesUsed[n] > 0)
|
|
{
|
|
fLoggedSequence = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!fLoggedSequence)
|
|
{
|
|
for (int n = 0; n < ARRAYSIZE(_uiTimesFailed); n++)
|
|
{
|
|
if (_uiTimesFailed[n] > 0)
|
|
{
|
|
fLoggedSequence = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Only send telemetry if we've logged some VT100 sequences. This should help reduce the amount of unnecessary
|
|
// telemetry being sent.
|
|
if (fLoggedSequence)
|
|
{
|
|
// I could use the TraceLoggingUIntArray, but then we would have to know the order of the enums on the backend.
|
|
// So just log each enum count separately with its string representation which makes it more human readable.
|
|
// Set the related activity to NULL since we aren't using it.
|
|
TraceLoggingWriteActivity(g_hConsoleVirtTermParserEventTraceProvider,
|
|
"ControlCodesUsed",
|
|
&_activityId,
|
|
NULL,
|
|
TraceLoggingUInt32(_uiTimesUsed[CUU], "CUU"),
|
|
TraceLoggingUInt32(_uiTimesUsed[CUD], "CUD"),
|
|
TraceLoggingUInt32(_uiTimesUsed[CUF], "CUF"),
|
|
TraceLoggingUInt32(_uiTimesUsed[CUB], "CUB"),
|
|
TraceLoggingUInt32(_uiTimesUsed[CNL], "CNL"),
|
|
TraceLoggingUInt32(_uiTimesUsed[CPL], "CPL"),
|
|
TraceLoggingUInt32(_uiTimesUsed[CHA], "CHA"),
|
|
TraceLoggingUInt32(_uiTimesUsed[CUP], "CUP"),
|
|
TraceLoggingUInt32(_uiTimesUsed[ED], "ED"),
|
|
TraceLoggingUInt32(_uiTimesUsed[EL], "EL"),
|
|
TraceLoggingUInt32(_uiTimesUsed[SGR], "SGR"),
|
|
TraceLoggingUInt32(_uiTimesUsed[DECSC], "DECSC"),
|
|
TraceLoggingUInt32(_uiTimesUsed[DECRC], "DECRC"),
|
|
TraceLoggingUInt32(_uiTimesUsed[DECSET], "DECSET"),
|
|
TraceLoggingUInt32(_uiTimesUsed[DECRST], "DECRST"),
|
|
TraceLoggingUInt32(_uiTimesUsed[DECKPAM], "DECKPAM"),
|
|
TraceLoggingUInt32(_uiTimesUsed[DECKPNM], "DECKPNM"),
|
|
TraceLoggingUInt32(_uiTimesUsed[DSR], "DSR"),
|
|
TraceLoggingUInt32(_uiTimesUsed[DA], "DA"),
|
|
TraceLoggingUInt32(_uiTimesUsed[VPA], "VPA"),
|
|
TraceLoggingUInt32(_uiTimesUsed[ICH], "ICH"),
|
|
TraceLoggingUInt32(_uiTimesUsed[DCH], "DCH"),
|
|
TraceLoggingUInt32(_uiTimesUsed[IL], "IL"),
|
|
TraceLoggingUInt32(_uiTimesUsed[DL], "DL"),
|
|
TraceLoggingUInt32(_uiTimesUsed[SU], "SU"),
|
|
TraceLoggingUInt32(_uiTimesUsed[SD], "SD"),
|
|
TraceLoggingUInt32(_uiTimesUsed[ANSISYSSC], "ANSISYSSC"),
|
|
TraceLoggingUInt32(_uiTimesUsed[ANSISYSRC], "ANSISYSRC"),
|
|
TraceLoggingUInt32(_uiTimesUsed[DECSTBM], "DECSTBM"),
|
|
TraceLoggingUInt32(_uiTimesUsed[RI], "RI"),
|
|
TraceLoggingUInt32(_uiTimesUsed[OSCWT], "OscWindowTitle"),
|
|
TraceLoggingUInt32(_uiTimesUsed[HTS], "HTS"),
|
|
TraceLoggingUInt32(_uiTimesUsed[CHT], "CHT"),
|
|
TraceLoggingUInt32(_uiTimesUsed[CBT], "CBT"),
|
|
TraceLoggingUInt32(_uiTimesUsed[TBC], "TBC"),
|
|
TraceLoggingUInt32(_uiTimesUsed[ECH], "ECH"),
|
|
TraceLoggingUInt32(_uiTimesUsed[DesignateG0], "DesignateG0"),
|
|
TraceLoggingUInt32(_uiTimesUsed[DesignateG1], "DesignateG1"),
|
|
TraceLoggingUInt32(_uiTimesUsed[DesignateG2], "DesignateG2"),
|
|
TraceLoggingUInt32(_uiTimesUsed[DesignateG3], "DesignateG3"),
|
|
TraceLoggingUInt32(_uiTimesUsed[HVP], "HVP"),
|
|
TraceLoggingUInt32(_uiTimesUsed[DECSTR], "DECSTR"),
|
|
TraceLoggingUInt32(_uiTimesUsed[RIS], "RIS"),
|
|
TraceLoggingUInt32(_uiTimesUsed[DECSCUSR], "DECSCUSR"),
|
|
TraceLoggingUInt32(_uiTimesUsed[DTTERM_WM], "DTTERM_WM"),
|
|
TraceLoggingUInt32(_uiTimesUsed[OSCCT], "OscColorTable"),
|
|
TraceLoggingUInt32(_uiTimesUsed[OSCSCC], "OscSetCursorColor"),
|
|
TraceLoggingUInt32(_uiTimesUsed[OSCRCC], "OscResetCursorColor"),
|
|
TraceLoggingUInt32(_uiTimesUsed[OSCFG], "OscForegroundColor"),
|
|
TraceLoggingUInt32(_uiTimesUsed[OSCBG], "OscBackgroundColor"),
|
|
TraceLoggingUInt32(_uiTimesUsed[REP], "REP"),
|
|
TraceLoggingUInt32Array(_uiTimesFailed, ARRAYSIZE(_uiTimesFailed), "Failed"),
|
|
TraceLoggingUInt32(_uiTimesFailedOutsideRange, "FailedOutsideRange"));
|
|
}
|
|
}
|
|
}
|