mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-02-24 04:00:02 +01:00
add CmdPal_ExtensionInvoked telemetry event
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
public record ExtensionInvokedMessage(string ExtensionId, string CommandType, bool Success, ulong ExecutionTimeMs);
|
||||
@@ -269,8 +269,17 @@ public partial class ShellViewModel : ObservableObject,
|
||||
var isMainPage = command == _rootPage;
|
||||
_isNested = !isMainPage;
|
||||
|
||||
// Track extension page navigation
|
||||
if (host is not null)
|
||||
{
|
||||
string extensionId = host.GetExtensionDisplayName() ?? "builtin";
|
||||
string commandType = command?.Name ?? command?.Id ?? "unknown";
|
||||
WeakReferenceMessenger.Default.Send<ExtensionInvokedMessage>(
|
||||
new(extensionId, commandType, true, 0));
|
||||
}
|
||||
|
||||
// Construct our ViewModel of the appropriate type and pass it the UI Thread context.
|
||||
var pageViewModel = _pageViewModelFactory.TryCreatePageViewModel(page, _isNested, host);
|
||||
var pageViewModel = _pageViewModelFactory.TryCreatePageViewModel(page, _isNested, host!);
|
||||
if (pageViewModel is null)
|
||||
{
|
||||
CoreLogger.LogError($"Failed to create ViewModel for page {page.GetType().Name}");
|
||||
@@ -338,6 +347,12 @@ public partial class ShellViewModel : ObservableObject,
|
||||
|
||||
private void SafeHandleInvokeCommandSynchronous(PerformCommandMessage message, IInvokableCommand invokable, AppExtensionHost? host)
|
||||
{
|
||||
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
|
||||
var command = message.Command.Unsafe;
|
||||
string extensionId = host?.GetExtensionDisplayName() ?? "builtin";
|
||||
string commandType = command?.Name ?? command?.Id ?? "unknown";
|
||||
bool success = false;
|
||||
|
||||
try
|
||||
{
|
||||
// Call out to extension process.
|
||||
@@ -348,16 +363,24 @@ public partial class ShellViewModel : ObservableObject,
|
||||
// But if it did succeed, we need to handle the result.
|
||||
UnsafeHandleCommandResult(result);
|
||||
|
||||
success = true;
|
||||
_handleInvokeTask = null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
success = false;
|
||||
_handleInvokeTask = null;
|
||||
|
||||
// TODO: It would be better to do this as a page exception, rather
|
||||
// than a silent log message.
|
||||
host?.Log(ex.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
stopwatch.Stop();
|
||||
WeakReferenceMessenger.Default.Send<ExtensionInvokedMessage>(
|
||||
new(extensionId, commandType, success, (ulong)stopwatch.ElapsedMilliseconds));
|
||||
}
|
||||
}
|
||||
|
||||
private void UnsafeHandleCommandResult(ICommandResult? result)
|
||||
|
||||
@@ -34,6 +34,6 @@ public sealed partial class CommandPaletteHost : AppExtensionHost, IExtensionHos
|
||||
|
||||
public override string? GetExtensionDisplayName()
|
||||
{
|
||||
return Extension?.ExtensionDisplayName;
|
||||
return Extension?.ExtensionDisplayName ?? _builtInProvider?.DisplayName ?? _builtInProvider?.Id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.Tracing;
|
||||
using Microsoft.PowerToys.Telemetry;
|
||||
using Microsoft.PowerToys.Telemetry.Events;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.Events;
|
||||
|
||||
/// <summary>
|
||||
/// Tracks extension usage with extension name and invocation details.
|
||||
/// Purpose: Identify popular vs. unused plugins and track extension performance.
|
||||
/// </summary>
|
||||
[EventData]
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)]
|
||||
public class CmdPalExtensionInvoked : EventBase, IEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the unique identifier of the extension provider.
|
||||
/// </summary>
|
||||
public string ExtensionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the display name of the command being invoked.
|
||||
/// </summary>
|
||||
public string CommandType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the command executed successfully.
|
||||
/// </summary>
|
||||
public bool Success { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the execution time in milliseconds.
|
||||
/// </summary>
|
||||
public ulong ExecutionTimeMs { get; set; }
|
||||
|
||||
public CmdPalExtensionInvoked(string extensionId, string commandType, bool success, ulong executionTimeMs)
|
||||
{
|
||||
EventName = "CmdPal_ExtensionInvoked";
|
||||
ExtensionId = extensionId;
|
||||
CommandType = commandType;
|
||||
Success = success;
|
||||
ExecutionTimeMs = executionTimeMs;
|
||||
}
|
||||
|
||||
public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage;
|
||||
}
|
||||
@@ -22,12 +22,14 @@ namespace Microsoft.CmdPal.UI;
|
||||
internal sealed class TelemetryForwarder :
|
||||
ITelemetryService,
|
||||
IRecipient<BeginInvokeMessage>,
|
||||
IRecipient<CmdPalInvokeResultMessage>
|
||||
IRecipient<CmdPalInvokeResultMessage>,
|
||||
IRecipient<ExtensionInvokedMessage>
|
||||
{
|
||||
public TelemetryForwarder()
|
||||
{
|
||||
WeakReferenceMessenger.Default.Register<BeginInvokeMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<CmdPalInvokeResultMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<ExtensionInvokedMessage>(this);
|
||||
}
|
||||
|
||||
public void Receive(CmdPalInvokeResultMessage message)
|
||||
@@ -40,6 +42,15 @@ internal sealed class TelemetryForwarder :
|
||||
PowerToysTelemetry.Log.WriteEvent(new BeginInvoke());
|
||||
}
|
||||
|
||||
public void Receive(ExtensionInvokedMessage message)
|
||||
{
|
||||
PowerToysTelemetry.Log.WriteEvent(new CmdPalExtensionInvoked(
|
||||
message.ExtensionId,
|
||||
message.CommandType,
|
||||
message.Success,
|
||||
message.ExecutionTimeMs));
|
||||
}
|
||||
|
||||
public void LogRunQuery(string query, int resultCount, ulong durationMs)
|
||||
{
|
||||
PowerToysTelemetry.Log.WriteEvent(new CmdPalRunQuery(query, resultCount, durationMs));
|
||||
|
||||
Reference in New Issue
Block a user