Skip to content

Add telemetry for settings UI traffic #19156

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

carlos-zamora
Copy link
Member

@carlos-zamora carlos-zamora commented Jul 21, 2025

Summary of the Pull Request

Adds a telemetry provider to the Terminal.Settings.Editor project as well as new telemetry events to track traffic through the settings UI. Specifically, the following events were added:

  • NavigatedToPage: Event emitted when the user navigates to a page in the settings UI
    • Has a PageId parameter that includes the identifier of the page that was navigated to
    • (conditionally added when PageId = page.editColorScheme) SchemeName parameter tracks the name of the color scheme that's being edited
    • conditionally added when PageId = page.extensions:
      • ExtensionPackageCount: The number of extension packages displayed
      • ProfilesModifiedCount: The number of profiles modified by enabled extensions
      • ProfilesAddedCount: The number of profiles added by enabled extensions
      • ColorSchemesAddedCount: The number of color schemes added by enabled extensions
    • conditionally added when PageId = page.extensions.extensionView:
      • FragmentSource: The source of the fragment included in this extension package
      • FragmentCount: The number of fragments included in this extension package
      • Enabled: The enabled status of the extension
    • (conditionally added when PageID = page.newTabMenu) if the page is representing a folder view
    • conditionally added when PageID = page.profile.*:
      • IsProfileDefaults: if the modified profile is the profile.defaults object
      • ProfileGuid: the guid of the profile that was navigated to
      • ProfileSource: the source of the profile that was navigated to
      • conditionally added when PageID = page.profile (aka the base profile page):
        • Orphaned: tracks if the profile was orphaned
        • Hidden: tracks if the profile is hidden
      • (conditionally added when PageID = page.profile.appearance) HasBackgroundImage: if the profile has a background image defined
      • (conditionally added when PageID = page.profile.appearance) HasUnfocusedAppearance: if the profile has an unfocused appearance defined
  • AddNewProfile: Event emitted when the user adds a new profile IsExtensionView parameter tracks if the page is representing a view of an extension
    • Has a Type parameter that represents the type of the creation method (i.e. empty profile, duplicate)
  • ResetApplicationState: Event emitted when the user resets their application state (via the UI)
  • ResetToDefaultSettings: Event emitted when the user resets their settings to their default value (via the UI)
  • OpenJson: Event emitted when the user clicks the Open JSON button in the settings UI
    • Has a SettingsTarget parameter that represents the target settings file (i.e. settings.json vs defaults.json)
  • CreateUnfocusedAppearance: Event emitted when the user creates an unfocused appearance for a profile
    • IsProfileDefaults: if the modified profile is the profile.defaults object
    • ProfileGuid: the guid of the profile that was navigated to
    • ProfileSource: the source of the profile that was navigated to
  • DeleteProfile: Event emitted when the user deletes a profile
    • also includes ProfileGuid, ProfileSource, Orphaned from the NavigatedToPage section above

The page ids can be reused later as a serialized reference to the page. We already use the one for the extensions page for the "new" badge.

@carlos-zamora

This comment was marked as resolved.

@DHowett
Copy link
Member

DHowett commented Jul 21, 2025

we don't have a DllMain in the settings editor. Where is it supposed to go?

You'll need to add one! Crib init.cpp from TerminalSettingsModel.

@carlos-zamora carlos-zamora marked this pull request as ready for review July 22, 2025 00:27
"AddNewProfile",
TraceLoggingDescription("Event emitted when the user adds a new profile"),
TraceLoggingValue("Duplicate", "Type", "The type of the creation method (i.e. empty profile, duplicate)"),
TraceLoggingValue(to_hstring(profileGuid).c_str(), "SourceGuid", "The guid of the profile that was copied"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please don't do that - use TraceLoggingGuid instead and cast profileGuid to GUID

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, is the source GUID meaningful? unless it's one of the ones we know about it's just noise.

may be worth checking the source source to see if people are cloning autogenerated or fragment profiles. not to leak the source, just a boolean confirming whether Source was not empty.

@@ -26,6 +26,8 @@ namespace winrt

namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
static constexpr std::wstring_view ColorSchemesPageId{ L"page.colorSchemes" };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit about the names: NavigatedToPage is an unambiguous namespace, right? so the page. part of page.foo is redundant

@@ -26,6 +26,8 @@ namespace winrt

namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
static constexpr std::wstring_view ColorSchemesPageId{ L"page.colorSchemes" };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you're only going to use these string views in one place, you could just inline the string into the telemetry event

Comment on lines +48 to +49
const auto& currentPkgVM = _ViewModel.CurrentExtensionPackage();
const auto& currentPkg = currentPkgVM.Package();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const auto& currentPkgVM = _ViewModel.CurrentExtensionPackage();
const auto& currentPkg = currentPkgVM.Package();
const auto currentPkgVM = _ViewModel.CurrentExtensionPackage();
const auto currentPkg = currentPkgVM.Package();

@@ -41,6 +42,36 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
vmImpl->ExtensionPackageIdentifierTemplateSelector(_extensionPackageIdentifierTemplateSelector);
vmImpl->LazyLoadExtensions();
vmImpl->MarkAsVisited();

if (_ViewModel.IsExtensionView())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for consistency, here and below, go through vmImpl->. no point in calling the projected wrapper methods when you have the literal implementation type right here

TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"),
TraceLoggingValue(ProfilesAppearancePageId.data(), "PageId", "The identifier of the page that was navigated to"),
TraceLoggingValue(_Profile.IsBaseLayer(), "IsProfileDefaults", "If the modified profile is the profile.defaults object"),
TraceLoggingValue(to_hstring(_Profile.Guid()).c_str(), "ProfileGuid", "The guid of the profile that was navigated to"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same note about guid

"CreateUnfocusedAppearance",
TraceLoggingDescription("Event emitted when the user creates an unfocused appearance for a profile"),
TraceLoggingValue(_Profile.IsBaseLayer(), "IsProfileDefaults", "If the modified profile is the profile.defaults object"),
TraceLoggingValue(to_hstring(_Profile.Guid()).c_str(), "ProfileGuid", "The guid of the profile that was navigated to"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same note about guid

TraceLoggingValue(_Profile.IsBaseLayer(), "IsProfileDefaults", "If the modified profile is the profile.defaults object"),
TraceLoggingValue(to_hstring(_Profile.Guid()).c_str(), "ProfileGuid", "The guid of the profile that was navigated to"),
TraceLoggingValue(_Profile.Source().c_str(), "ProfileSource", "The source of the profile that was navigated to"),
TraceLoggingValue(false, "Orphaned", "Tracks if the profile was orphaned"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one could argue that the orphaned profile page is just a different type of page.

TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"),
TraceLoggingValue(ProfilesBasePageId.data(), "PageId", "The identifier of the page that was navigated to"),
TraceLoggingValue(_Profile.IsBaseLayer(), "IsProfileDefaults", "If the modified profile is the profile.defaults object"),
TraceLoggingValue(to_hstring(_Profile.Guid()).c_str(), "ProfileGuid", "The guid of the profile that was navigated to"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same note about guid

"NavigatedToPage",
TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"),
TraceLoggingValue(ProfilesBaseOrphanedPageId.data(), "PageId", "The identifier of the page that was navigated to"),
TraceLoggingValue(_Profile.IsBaseLayer(), "IsProfileDefaults", "If the modified profile is the profile.defaults object"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is an impossibility

@microsoft-github-policy-service microsoft-github-policy-service bot added the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label Jul 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something
Projects
Status: To Cherry Pick
Status: To Cherry Pick
Development

Successfully merging this pull request may close these issues.

2 participants