Skip to content

Commit 6d6d067

Browse files
authored
Fix the telemetry collection logic (#22908)
* Use regex to check if that's a valid az command * Update the telemetry property names * Update version and release note. * Add/Update a few test cases * Rename property names. * Update the telemetry property name
1 parent f9a7fb4 commit 6d6d067

File tree

10 files changed

+50
-26
lines changed

10 files changed

+50
-26
lines changed

tools/Az.Tools.Predictor/Az.Tools.Predictor.Test/AzPredictorTelemetryTests.cs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,13 @@ public async Task VerifyOnCommandLineAcceptedException()
623623
[InlineData("start_of_snippet", @"-StorageAccountKey""xxx""New-AzStorageContainer -context xxx")]
624624
[InlineData("start_of_snippet", @"New-AzureStorageContext-StorageAccountName ""xxx"" -StorageAccountKey ""xxx""")]
625625
[InlineData("start_of_snippet", @"sig=xxxxxxxxxxx/Sensor-Azure")]
626+
[InlineData("start_of_snippet", @"sig=xxxxxxxxxxx/Get-az")]
626627
[InlineData("start_of_snippet", @"sig=Signature/Test-Sensor-Azu")]
628+
[InlineData("start_of_snippet", @"sig=Signature/Set-azstorage")]
629+
[InlineData("start_of_snippet", "New-AzStorage\"key=value\"")]
630+
[InlineData("start_of_snippet", "New-az\\\"key=value\\\"")]
631+
[InlineData("start_of_snippet", "git")]
632+
[InlineData("start_of_snippet", "Get-Key -Key abcd")]
627633
public void VerifyUserInputInGetSuggestionEvent(string expectedUserInput, string input)
628634
{
629635
var expectedTelemetryCount = 1;
@@ -637,8 +643,8 @@ public void VerifyUserInputInGetSuggestionEvent(string expectedUserInput, string
637643

638644
Assert.EndsWith("Aggregation", telemetryClient.RecordedTelemetry[0].EventName);
639645
var suggestionSessions = JsonSerializer.Deserialize<IList<IDictionary<string, object>>>(telemetryClient.RecordedTelemetry[0].Properties[GetSuggestionTelemetryData.PropertyNamePrediction]);
640-
Assert.Equal(expectedUserInput, ((JsonElement)(suggestionSessions[0][GetSuggestionTelemetryData.PropertyNameUserInput])).GetString());
641-
Assert.Equal(expectedUserInput, telemetryClient.RecordedTelemetry[0].Properties[GetSuggestionTelemetryData.PropertyNameUserInput]);
646+
Assert.Equal(expectedUserInput, ((JsonElement)(suggestionSessions[0][GetSuggestionTelemetryData.PropertyNameInnerUserInput])).GetString());
647+
Assert.Equal(expectedUserInput, telemetryClient.RecordedTelemetry[0].Properties[GetSuggestionTelemetryData.PropertyNameOuterUserInput]);
642648
}
643649

644650
/// <summary>
@@ -678,7 +684,7 @@ public void VerifySeparateUserInput()
678684
VerifyTelemetryDispatchCount(expectedTelemetryCount, telemetryClient);
679685

680686
Assert.EndsWith("Aggregation", telemetryClient.RecordedTelemetry[0].EventName);
681-
Assert.Equal(string.Join(AzPredictorTelemetryClient._StringValueConcatenator, expectedUserInputValue), telemetryClient.RecordedTelemetry[0].Properties[GetSuggestionTelemetryData.PropertyNameUserInput]);
687+
Assert.Equal(string.Join(AzPredictorTelemetryClient._StringValueConcatenator, expectedUserInputValue), telemetryClient.RecordedTelemetry[0].Properties[GetSuggestionTelemetryData.PropertyNameOuterUserInput]);
682688
}
683689

684690
/// <summary>
@@ -703,7 +709,7 @@ private void VerifySameSuggestionSessionId()
703709
Assert.EndsWith("Aggregation", telemetryClient.RecordedTelemetry[0].EventName);
704710
Assert.Equal(MockObjects.PredictionClient.Name, telemetryClient.RecordedTelemetry[0].Properties["ClientId"]);
705711
var suggestionSessions = JsonSerializer.Deserialize<IList<IDictionary<string, object>>>(telemetryClient.RecordedTelemetry[0].Properties[GetSuggestionTelemetryData.PropertyNamePrediction]);
706-
Assert.Equal("Clear-Content -Filter *** -Path ***", ((JsonElement)(suggestionSessions[0][GetSuggestionTelemetryData.PropertyNameUserInput])).GetString());
712+
Assert.Equal("Clear-Content -Filter *** -Path ***", ((JsonElement)(suggestionSessions[0][GetSuggestionTelemetryData.PropertyNameInnerUserInput])).GetString());
707713
Assert.Equal(1, ((JsonElement)suggestionSessions[0][GetSuggestionTelemetryData.PropertyNameFound]).GetArrayLength());
708714

709715
var displayCountOrIndex = 3;
@@ -870,7 +876,7 @@ public void VerifyExceptionInGetSuggestion()
870876

871877
Assert.EndsWith("Exception", telemetryClient.RecordedTelemetry[0].EventName);
872878
Assert.Equal(MockObjects.PredictionClient.Name, telemetryClient.RecordedTelemetry[0].Properties["ClientId"]);
873-
Assert.Equal(AzPredictorConstants.CommandPlaceholder, telemetryClient.RecordedTelemetry[0].Properties["UserInput"]);
879+
Assert.Equal(AzPredictorConstants.CommandPlaceholder, telemetryClient.RecordedTelemetry[0].Properties[GetSuggestionTelemetryData.PropertyNameOuterUserInput]);
874880
Assert.StartsWith($"Type: {typeof(MockTestException)}\nStack Trace: ", telemetryClient.RecordedTelemetry[0].Properties["Exception"]);
875881

876882
Assert.EndsWith("Aggregation", telemetryClient.RecordedTelemetry[1].EventName);
@@ -1093,7 +1099,7 @@ public void VerifyAggregationDataSplitAtDisplaySuggestion()
10931099
var recordedTelemetry = telemetryClient.RecordedTelemetry[0];
10941100
var suggestionSessions = JsonSerializer.Deserialize<IList<IDictionary<string, object>>>(recordedTelemetry.Properties[GetSuggestionTelemetryData.PropertyNamePrediction]);
10951101
Assert.Equal(expectedSuggestionSessionInFirstBatch, suggestionSessions.Count());
1096-
Assert.True(suggestionSessions.All((s) => s.ContainsKey(GetSuggestionTelemetryData.PropertyNameFound) && s.ContainsKey(GetSuggestionTelemetryData.PropertyNameUserInput)));
1102+
Assert.True(suggestionSessions.All((s) => s.ContainsKey(GetSuggestionTelemetryData.PropertyNameFound) && s.ContainsKey(GetSuggestionTelemetryData.PropertyNameInnerUserInput)));
10971103
Assert.True(suggestionSessions.All((s) => !s.ContainsKey(SuggestionAcceptedTelemetryData.PropertyNameAccepted)));
10981104
Assert.True(suggestionSessions.All((s) => !s.ContainsKey(SuggestionDisplayedTelemetryData.PropertyNameDisplayed)));
10991105
Assert.Equal(suggestionPackage.Session.Value, ((JsonElement)suggestionSessions.Last()[GetSuggestionTelemetryData.PropertyNameSuggestionSessionId]).GetUInt32());
@@ -1102,7 +1108,7 @@ public void VerifyAggregationDataSplitAtDisplaySuggestion()
11021108
suggestionSessions = JsonSerializer.Deserialize<IList<IDictionary<string, object>>>(recordedTelemetry.Properties[GetSuggestionTelemetryData.PropertyNamePrediction]);
11031109
Assert.Equal(expectedSuggestionSessionInSecondBatch, suggestionSessions.Count());
11041110
Assert.False(suggestionSessions[0].ContainsKey(GetSuggestionTelemetryData.PropertyNameFound));
1105-
Assert.False(suggestionSessions[0].ContainsKey(GetSuggestionTelemetryData.PropertyNameUserInput));
1111+
Assert.False(suggestionSessions[0].ContainsKey(GetSuggestionTelemetryData.PropertyNameInnerUserInput));
11061112
Assert.False(suggestionSessions[0].ContainsKey(GetSuggestionTelemetryData.PropertyNameIsCancelled));
11071113
Assert.Equal(suggestionPackage.Session.Value, ((JsonElement)suggestionSessions[0][GetSuggestionTelemetryData.PropertyNameSuggestionSessionId]).GetUInt32());
11081114
Assert.Equal(1, ((JsonElement)suggestionSessions[0][SuggestionDisplayedTelemetryData.PropertyNameDisplayed])[0].GetInt32());
@@ -1151,7 +1157,7 @@ public void VerifyAggregationDataSplitAtAcceptSuggestion()
11511157
var recordedTelemetry = telemetryClient.RecordedTelemetry[0];
11521158
var suggestionSessions = JsonSerializer.Deserialize<IList<IDictionary<string, object>>>(recordedTelemetry.Properties[GetSuggestionTelemetryData.PropertyNamePrediction]);
11531159
Assert.Equal(expectedSuggestionSessionInFirstBatch, suggestionSessions.Count());
1154-
Assert.True(suggestionSessions.All((s) => s.ContainsKey(GetSuggestionTelemetryData.PropertyNameFound) && s.ContainsKey(GetSuggestionTelemetryData.PropertyNameUserInput)));
1160+
Assert.True(suggestionSessions.All((s) => s.ContainsKey(GetSuggestionTelemetryData.PropertyNameFound) && s.ContainsKey(GetSuggestionTelemetryData.PropertyNameInnerUserInput)));
11551161
Assert.True(suggestionSessions.All((s) => !s.ContainsKey(SuggestionAcceptedTelemetryData.PropertyNameAccepted)));
11561162
Assert.True(suggestionSessions.SkipLast(1).All((s) => !s.ContainsKey(SuggestionDisplayedTelemetryData.PropertyNameDisplayed) && !s.ContainsKey(GetSuggestionTelemetryData.PropertyNameSuggestionSessionId)));
11571163
Assert.Equal(suggestionPackage.Session.Value, ((JsonElement)suggestionSessions.Last()[GetSuggestionTelemetryData.PropertyNameSuggestionSessionId]).GetUInt32());
@@ -1162,7 +1168,7 @@ public void VerifyAggregationDataSplitAtAcceptSuggestion()
11621168
suggestionSessions = JsonSerializer.Deserialize<IList<IDictionary<string, object>>>(recordedTelemetry.Properties[GetSuggestionTelemetryData.PropertyNamePrediction]);
11631169
Assert.Equal(expectedSuggestionSessionInSecondBatch, suggestionSessions.Count());
11641170
Assert.False(suggestionSessions[0].ContainsKey(GetSuggestionTelemetryData.PropertyNameFound));
1165-
Assert.False(suggestionSessions[0].ContainsKey(GetSuggestionTelemetryData.PropertyNameUserInput));
1171+
Assert.False(suggestionSessions[0].ContainsKey(GetSuggestionTelemetryData.PropertyNameInnerUserInput));
11661172
Assert.False(suggestionSessions[0].ContainsKey(GetSuggestionTelemetryData.PropertyNameIsCancelled));
11671173
Assert.Equal(suggestionPackage.Session.Value, ((JsonElement)suggestionSessions[0][GetSuggestionTelemetryData.PropertyNameSuggestionSessionId]).GetUInt32());
11681174
Assert.Equal(acceptedSuggestion, ((JsonElement)suggestionSessions[0][SuggestionAcceptedTelemetryData.PropertyNameAccepted]).GetString());

tools/Az.Tools.Predictor/Az.Tools.Predictor.Test/SuggestionSessionTests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public void TestSizeForOneSuggestion(string suggestion, SuggestionSource source,
6262
+ 1 // For the one digit of source
6363
+ SuggestionSessionTests._AdditionalSizeForTwoElementArray // for [,]
6464
+ SuggestionSessionTests._AdditionalSizeForArrayBracket // for [] in Found
65-
+ GetSuggestionTelemetryData.PropertyNameUserInput.Length + SuggestionSessionTests._AdditionalSizeForKey
65+
+ GetSuggestionTelemetryData.PropertyNameInnerUserInput.Length + SuggestionSessionTests._AdditionalSizeForKey
6666
+ userInput.Length + SuggestionSessionTests._AdditionalSizeForString
6767
+ GetSuggestionTelemetryData.PropertyNameIsCancelled.Length + SuggestionSessionTests._AdditionalSizeForKey
6868
+ isCancelled.ToString(CultureInfo.InvariantCulture).Length;
@@ -99,7 +99,7 @@ public void TestSizeForTwoSuggestions(string suggestion1, SuggestionSource sourc
9999
+ 1 // for the one digit of source2
100100
+ SuggestionSessionTests._AdditionalSizeForTwoElementArray // for [,]
101101
+ SuggestionSessionTests._AdditionalSizeForTwoElementArray // for [,] in Found
102-
+ GetSuggestionTelemetryData.PropertyNameUserInput.Length + SuggestionSessionTests._AdditionalSizeForKey
102+
+ GetSuggestionTelemetryData.PropertyNameInnerUserInput.Length + SuggestionSessionTests._AdditionalSizeForKey
103103
+ userInput.Length + SuggestionSessionTests._AdditionalSizeForString
104104
+ GetSuggestionTelemetryData.PropertyNameIsCancelled.Length + SuggestionSessionTests._AdditionalSizeForKey
105105
+ isCancelled.ToString(CultureInfo.InvariantCulture).Length;
@@ -135,7 +135,7 @@ public void TestSizeForDisplaySuggestion(string suggestion, SuggestionSource sou
135135
+ 1 // For the one digit of source
136136
+ SuggestionSessionTests._AdditionalSizeForTwoElementArray // for [,]
137137
+ SuggestionSessionTests._AdditionalSizeForArrayBracket // for [] in Found
138-
+ GetSuggestionTelemetryData.PropertyNameUserInput.Length + SuggestionSessionTests._AdditionalSizeForKey
138+
+ GetSuggestionTelemetryData.PropertyNameInnerUserInput.Length + SuggestionSessionTests._AdditionalSizeForKey
139139
+ userInput.Length + SuggestionSessionTests._AdditionalSizeForString
140140
+ GetSuggestionTelemetryData.PropertyNameIsCancelled.Length + SuggestionSessionTests._AdditionalSizeForKey
141141
+ isCancelled.ToString(CultureInfo.InvariantCulture).Length
@@ -172,7 +172,7 @@ public void TestSizeForAcceptSuggestion(string suggestion, SuggestionSource sour
172172
+ 1 // For the one digit of source
173173
+ SuggestionSessionTests._AdditionalSizeForTwoElementArray // for [,]
174174
+ SuggestionSessionTests._AdditionalSizeForArrayBracket // for [] in Found
175-
+ GetSuggestionTelemetryData.PropertyNameUserInput.Length + SuggestionSessionTests._AdditionalSizeForKey
175+
+ GetSuggestionTelemetryData.PropertyNameInnerUserInput.Length + SuggestionSessionTests._AdditionalSizeForKey
176176
+ userInput.Length + SuggestionSessionTests._AdditionalSizeForString
177177
+ GetSuggestionTelemetryData.PropertyNameIsCancelled.Length + SuggestionSessionTests._AdditionalSizeForKey
178178
+ isCancelled.ToString(CultureInfo.InvariantCulture).Length

tools/Az.Tools.Predictor/Az.Tools.Predictor/Az.Tools.Predictor.psd1

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
RootModule = 'Az.Tools.Predictor.psm1'
1212

1313
# Version number of this module.
14-
ModuleVersion = '1.1.2'
14+
ModuleVersion = '1.1.3'
1515

1616
# Supported PSEditions
1717
CompatiblePSEditions = 'Core'
@@ -67,8 +67,7 @@ PrivateData = @{
6767
# IconUri = ''
6868

6969
# ReleaseNotes of this module
70-
ReleaseNotes = '* Data collection mechnanism updated
71-
* Improvements in command parsing mechanism'
70+
ReleaseNotes = '* Data collection mechnanism updated'
7271

7372
# Prerelease string of this module
7473
# Prerelease = ''

tools/Az.Tools.Predictor/Az.Tools.Predictor/AzPredictorConstants.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
using System.Collections;
1717
using System.Collections.Generic;
1818
using System.Collections.Immutable;
19+
using System.Text;
20+
using System.Text.RegularExpressions;
1921

2022
namespace Microsoft.Azure.PowerShell.Tools.AzPredictor
2123
{
@@ -226,6 +228,15 @@ internal static class AzPredictorConstants
226228
// Other Verbs
227229
"Use"
228230
}, StringComparer.OrdinalIgnoreCase);
231+
232+
/// <summary>
233+
/// The regex pattern to match the noun in an Az cmdlet.
234+
/// </summary>
235+
public static readonly Regex AzNounPattern = new Regex($"^{AzCommandMoniker}[a-zA-Z]*$",
236+
RegexOptions.Compiled
237+
| RegexOptions.Singleline
238+
| RegexOptions.IgnoreCase,
239+
TimeSpan.FromMilliseconds(10));
229240
}
230241
}
231242

tools/Az.Tools.Predictor/Az.Tools.Predictor/AzPredictorService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -346,10 +346,10 @@ public virtual bool IsSupportedCommand(string cmd)
346346

347347
// There must be two parts (verb and noun) to be a valid PowerShell commands.
348348
// The first part must be an approved PowerShell verb and the second part must begin with "Az".
349-
if (commandParts?.Length == 2 )
349+
if (commandParts?.Length == 2)
350350
{
351351
return AzPredictorConstants.ApprovedPowerShellVerbs.Contains(commandParts[0])
352-
&& commandParts[1].StartsWith(AzPredictorConstants.AzCommandMoniker, StringComparison.OrdinalIgnoreCase);
352+
&& AzPredictorConstants.AzNounPattern.IsMatch(commandParts[1]);
353353
}
354354

355355
return false;

tools/Az.Tools.Predictor/Az.Tools.Predictor/ChangeLog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
-->
2020
## Upcoming Release
2121

22+
## Version 1.1.3
23+
* Updated data collection mechanism
24+
2225
## Version 1.1.2
2326
* Updated data collection mechanism
2427
* Improvements in command parsing mechanism

tools/Az.Tools.Predictor/Az.Tools.Predictor/Telemetry/AggregatedTelemetryData.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public string UserInput
5454
get { return _userInput; }
5555
set
5656
{
57-
int keySize = SuggestionSession.GetKeySize(GetSuggestionTelemetryData.PropertyNameUserInput.Length);
57+
int keySize = SuggestionSession.GetKeySize(GetSuggestionTelemetryData.PropertyNameInnerUserInput.Length);
5858

5959
if (_userInput is not null)
6060
{

tools/Az.Tools.Predictor/Az.Tools.Predictor/Telemetry/AzPredictorTelemetryClient.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ protected void SendAggregatedTelemetryData()
291291

292292
if (suggestionSession.UserInput != null)
293293
{
294-
toAddSuggestion.Add(GetSuggestionTelemetryData.PropertyNameUserInput, suggestionSession.UserInput);
294+
toAddSuggestion.Add(GetSuggestionTelemetryData.PropertyNameInnerUserInput, suggestionSession.UserInput);
295295
_uniqueUserInput.Add(suggestionSession.UserInput);
296296
}
297297

@@ -324,7 +324,7 @@ protected void SendAggregatedTelemetryData()
324324
if (suggestions.Count > 0)
325325
{
326326
properties.Add(GetSuggestionTelemetryData.PropertyNamePrediction, JsonSerializer.Serialize(suggestions, JsonUtilities.TelemetrySerializerOptions));
327-
properties.Add(GetSuggestionTelemetryData.PropertyNameUserInput, string.Join(_StringValueConcatenator, _uniqueUserInput));
327+
properties.Add(GetSuggestionTelemetryData.PropertyNameOuterUserInput, string.Join(_StringValueConcatenator, _uniqueUserInput));
328328
}
329329

330330
if (aggregatedData.CommandLine != null)
@@ -494,7 +494,7 @@ private void ProcessTelemetryData(GetSuggestionTelemetryData telemetryData)
494494
telemetryData.Exception,
495495
new Dictionary<string, string>()
496496
{
497-
{ GetSuggestionTelemetryData.PropertyNameUserInput, maskedUserInput },
497+
{ GetSuggestionTelemetryData.PropertyNameOuterUserInput, maskedUserInput },
498498
});
499499
}
500500
}

tools/Az.Tools.Predictor/Az.Tools.Predictor/Telemetry/GetSuggestionTelemetryData.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,22 @@ public sealed class GetSuggestionTelemetryData : ITelemetryData
3636
/// <summary>
3737
/// The telemetry property name for "Prediction".
3838
/// </summary>
39-
public const string PropertyNamePrediction = "Prediction2";
39+
public const string PropertyNamePrediction = "Prediction_a";
4040

4141
/// <summary>
4242
/// The telemetry property name for "SuggestionSessionId".
4343
/// </summary>
4444
public const string PropertyNameSuggestionSessionId = "SuggestionSessionId";
4545

4646
/// <summary>
47-
/// The telemetry property name fo "userInput".
47+
/// The telemetry property name fo "userInput" used as the nested property.
4848
/// </summary>
49-
public const string PropertyNameUserInput = "UserInput";
49+
public const string PropertyNameInnerUserInput = "UserInput";
50+
51+
/// <summary>
52+
/// The telemetry property name fo "userInput" used as a top-level property.
53+
/// </summary>
54+
public const string PropertyNameOuterUserInput = "UserInput_a";
5055

5156
/// <inheritdoc/>
5257
public PredictionClient Client { get; init; }

tools/Az.Tools.Predictor/Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<TargetFramework>net6.0</TargetFramework>
55
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
66
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
7-
<Version>1.1.2</Version>
7+
<Version>1.1.3</Version>
88
<Authors>Microsoft Corporation</Authors>
99
<Company>Microsoft Corporation</Company>
1010
<Copyright>Microsoft Corporation. All rights reserved.</Copyright>

0 commit comments

Comments
 (0)