diff --git a/common/TelemetryEvents/SourceControlIntegration/SourceControlIntegrationEvent.cs b/common/TelemetryEvents/SourceControlIntegration/SourceControlIntegrationEvent.cs new file mode 100644 index 0000000000..6d2cff9971 --- /dev/null +++ b/common/TelemetryEvents/SourceControlIntegration/SourceControlIntegrationEvent.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Diagnostics.Tracing; +using DevHome.Telemetry; +using Microsoft.Diagnostics.Telemetry; +using Microsoft.Diagnostics.Telemetry.Internal; + +namespace DevHome.Common.TelemetryEvents.SourceControlIntegration; + +[EventData] +public class SourceControlIntegrationEvent : EventBase +{ + public override PartA_PrivTags PartA_PrivTags => PrivTags.ProductAndServicePerformance; + + public string RepositoryRootPath + { + get; + } + + public int TrackedRepositoryCount + { + get; + } + + public SourceControlIntegrationEvent(string sourceControlProviderClassId, string repositoryRootPath, int trackedRepositoryCount) + { + RepositoryRootPath = SourceControlIntegrationHelper.GetSafeRootPath(repositoryRootPath); + TrackedRepositoryCount = trackedRepositoryCount; + } + + public override void ReplaceSensitiveStrings(Func replaceSensitiveStrings) + { + // The only sensitive strings is the repository root path. GetSafeRootPath is used to potentially remove PII and + // keep last part of path. + } +} diff --git a/common/TelemetryEvents/SourceControlIntegration/SourceControlIntegrationHelper.cs b/common/TelemetryEvents/SourceControlIntegration/SourceControlIntegrationHelper.cs new file mode 100644 index 0000000000..b3417e0e08 --- /dev/null +++ b/common/TelemetryEvents/SourceControlIntegration/SourceControlIntegrationHelper.cs @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.IO; +using System.Linq; + +namespace DevHome.Common.TelemetryEvents.SourceControlIntegration; + +public static class SourceControlIntegrationHelper +{ + public static string GetSafeRootPath(string rootPath) + { + var parts = rootPath.Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries); + return parts.LastOrDefault() ?? string.Empty; + } +} diff --git a/common/TelemetryEvents/SourceControlIntegration/SourceControlIntegrationUserEvent.cs b/common/TelemetryEvents/SourceControlIntegration/SourceControlIntegrationUserEvent.cs new file mode 100644 index 0000000000..0ac2340b5f --- /dev/null +++ b/common/TelemetryEvents/SourceControlIntegration/SourceControlIntegrationUserEvent.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Diagnostics.Tracing; +using DevHome.Telemetry; +using Microsoft.Diagnostics.Telemetry; +using Microsoft.Diagnostics.Telemetry.Internal; + +namespace DevHome.Common.TelemetryEvents.SourceControlIntegration; + +[EventData] +public class SourceControlIntegrationUserEvent : EventBase +{ + public override PartA_PrivTags PartA_PrivTags => PrivTags.ProductAndServicePerformance; + + public string RepositoryRootPath + { + get; + } + + public int TrackedRepositoryCount + { + get; + } + + public SourceControlIntegrationUserEvent(string sourceControlProviderClassId, string repositoryRootPath, int trackedRepositoryCount) + { + RepositoryRootPath = SourceControlIntegrationHelper.GetSafeRootPath(repositoryRootPath); + TrackedRepositoryCount = trackedRepositoryCount; + } + + public override void ReplaceSensitiveStrings(Func replaceSensitiveStrings) + { + // The only sensitive strings is the repository root path. GetSafeRootPath is used to potentially remove PII and + // keep last part of path. + } +} diff --git a/tools/Customization/DevHome.FileExplorerSourceControlIntegration/Services/RepositoryTracking.cs b/tools/Customization/DevHome.FileExplorerSourceControlIntegration/Services/RepositoryTracking.cs index 96879b80a0..c5f86348cb 100644 --- a/tools/Customization/DevHome.FileExplorerSourceControlIntegration/Services/RepositoryTracking.cs +++ b/tools/Customization/DevHome.FileExplorerSourceControlIntegration/Services/RepositoryTracking.cs @@ -3,6 +3,8 @@ using DevHome.Common.Helpers; using DevHome.Common.Services; +using DevHome.Common.TelemetryEvents.SourceControlIntegration; +using DevHome.Telemetry; using Serilog; using Windows.Storage; @@ -101,13 +103,16 @@ public void AddRepositoryPath(string extensionCLSID, string rootPath) log.Warning("Repository root path already registered in the repo store"); } } + + TelemetryFactory.Get().Log("AddEnhancedRepository_Event", LogLevel.Critical, new SourceControlIntegrationEvent(extensionCLSID, rootPath, TrackedRepositories.Count)); } public void RemoveRepositoryPath(string rootPath) { + var extensionCLSID = string.Empty; lock (trackRepoLock) { - TrackedRepositories.TryGetValue(rootPath, out var extensionCLSID); + TrackedRepositories.TryGetValue(rootPath, out extensionCLSID); TrackedRepositories.Remove(rootPath); fileService.Save(RepoStoreOptions.RepoStoreFolderPath, RepoStoreOptions.RepoStoreFileName, TrackedRepositories); log.Information("Repository removed from repo store"); @@ -120,6 +125,8 @@ public void RemoveRepositoryPath(string rootPath) log.Error(ex, $"Removed event signaling failed: "); } } + + TelemetryFactory.Get().Log("RemoveEnhancedRepository_Event", LogLevel.Critical, new SourceControlIntegrationEvent(extensionCLSID ?? string.Empty, rootPath, TrackedRepositories.Count)); } public Dictionary GetAllTrackedRepositories()