Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/Cli/dotnet/Telemetry/TelemetryFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,29 @@ private static IEnumerable<TelemetryEntryFormat> FilterImpl(ParseResult parseRes
yield break;
}

// When a top-level terminating option (--help, --version, --info) is invoked without a
// subcommand, RootSubCommandResult() returns empty string. Use the option name as the
// verb so these invocations are visible in telemetry.
if (string.IsNullOrEmpty(topLevelCommandName)
&& parseResult.Action is InvocableOptionAction { Terminating: true } topLevelOptionAction)
{
topLevelCommandName = topLevelOptionAction.Option.Name;
}
Comment thread
marcpopMSFT marked this conversation as resolved.

Dictionary<string, string?> properties = new() { ["verb"] = topLevelCommandName };
if (!string.IsNullOrEmpty(globalJsonState))
{
properties["globalJson"] = globalJsonState;
}

// When --help is the active action on any command (e.g. "dotnet build --help"),
// record that the invocation was a help request so it can be distinguished from
// an actual command execution.
if (parseResult.Action is PrintHelpAction)
{
properties["help"] = "true";
}

yield return new TelemetryEntryFormat("toplevelparser/command", properties);

if (parseResult.IsDotnetBuiltInCommand() &&
Expand Down
55 changes: 55 additions & 0 deletions test/dotnet.Tests/TelemetryTests/TelemetryFilterTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,59 @@ public void WhenCalledWithMissingArgumentWorkloadSubLevelCommandNameAndArgumentS
e.Properties["subcommand"] ==
Sha256Hasher.Hash("INSTALL"));
}

[TestMethod]
public void DotnetHelpShouldSendHelpVerbToTelemetry()
{
var parseResult = Parser.Parse(["--help"]);
TelemetryEventEntry.SendFiltered(parseResult);
_fakeTelemetry.LogEntries.Should().Contain(e => e.EventName == "toplevelparser/command" &&
e.Properties.ContainsKey("verb") &&
e.Properties["verb"] == Sha256Hasher.Hash("--HELP") &&
e.Properties.ContainsKey("help") &&
e.Properties["help"] == Sha256Hasher.Hash("TRUE"));
}

[TestMethod]
public void DotnetVersionShouldSendVersionVerbToTelemetry()
{
var parseResult = Parser.Parse(["--version"]);
TelemetryEventEntry.SendFiltered(parseResult);
_fakeTelemetry.LogEntries.Should().Contain(e => e.EventName == "toplevelparser/command" &&
e.Properties.ContainsKey("verb") &&
e.Properties["verb"] == Sha256Hasher.Hash("--VERSION"));
}

[TestMethod]
public void DotnetInfoShouldSendInfoVerbToTelemetry()
{
var parseResult = Parser.Parse(["--info"]);
TelemetryEventEntry.SendFiltered(parseResult);
_fakeTelemetry.LogEntries.Should().Contain(e => e.EventName == "toplevelparser/command" &&
e.Properties.ContainsKey("verb") &&
e.Properties["verb"] == Sha256Hasher.Hash("--INFO"));
}

[TestMethod]
public void SubcommandHelpShouldSendVerbWithHelpProperty()
{
var parseResult = Parser.Parse(["build", "--help"]);
TelemetryEventEntry.SendFiltered(parseResult);
_fakeTelemetry.LogEntries.Should().Contain(e => e.EventName == "toplevelparser/command" &&
e.Properties.ContainsKey("verb") &&
e.Properties["verb"] == Sha256Hasher.Hash("BUILD") &&
e.Properties.ContainsKey("help") &&
e.Properties["help"] == Sha256Hasher.Hash("TRUE"));
}

[TestMethod]
public void RegularBuildCommandShouldNotHaveHelpProperty()
{
var parseResult = Parser.Parse(["build"]);
TelemetryEventEntry.SendFiltered(parseResult);
_fakeTelemetry.LogEntries.Should().Contain(e => e.EventName == "toplevelparser/command" &&
e.Properties.ContainsKey("verb") &&
e.Properties["verb"] == Sha256Hasher.Hash("BUILD") &&
!e.Properties.ContainsKey("help"));
}
}
Loading