Skip to content

Commit 791bef9

Browse files
Added fault reporting in telemetry + added opt out for all events (#15778)
* Added fault reporting in telemetry + added opt out for all events for now * Removed accidentally added code * Missing namespaces * Automated command ran: fantomas Co-authored-by: vzarytovskii <[email protected]> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent c50c808 commit 791bef9

File tree

3 files changed

+47
-11
lines changed

3 files changed

+47
-11
lines changed

vsintegration/src/FSharp.Editor/Navigation/GoToDefinition.fs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@ open FSharp.Compiler.EditorServices
2525
open FSharp.Compiler.Text
2626
open FSharp.Compiler.Text.Range
2727
open FSharp.Compiler.Symbols
28-
open FSharp.Compiler.Tokenization
2928
open System.Composition
3029
open System.Text.RegularExpressions
3130
open CancellableTasks
31+
open Microsoft.VisualStudio.FSharp.Editor.Telemetry
32+
open Microsoft.VisualStudio.Telemetry
3233

3334
module private Symbol =
3435
let fullName (root: ISymbol) : string =
@@ -679,6 +680,9 @@ type internal FSharpNavigation(metadataAsSource: FSharpMetadataAsSourceService,
679680
// Task.Wait throws an exception if the task is cancelled, so be sure to catch it.
680681
try
681682
// This call to Wait() is fine because we want to be able to provide the error message in the status bar.
683+
use _ =
684+
TelemetryReporter.ReportSingleEventWithDuration(TelemetryEvents.GoToDefinition, [||])
685+
682686
gtdTask.Wait(cancellationToken)
683687

684688
if gtdTask.Status = TaskStatus.RanToCompletion && gtdTask.Result.IsSome then
@@ -695,6 +699,7 @@ type internal FSharpNavigation(metadataAsSource: FSharpMetadataAsSourceService,
695699
statusBar.TempMessage(SR.CannotDetermineSymbol())
696700
false
697701
with exc ->
702+
TelemetryReporter.ReportFault(TelemetryEvents.GoToDefinition, FaultSeverity.General, exc)
698703
statusBar.TempMessage(String.Format(SR.NavigateToFailed(), Exception.flattenMessage exc))
699704

700705
// Don't show the dialog box as it's most likely that the user cancelled.

vsintegration/src/FSharp.Editor/Navigation/NavigableSymbolsService.fs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ open Microsoft.VisualStudio.Language.Intellisense
1414
open Microsoft.VisualStudio.Text
1515
open Microsoft.VisualStudio.Text.Editor
1616
open Microsoft.VisualStudio.Utilities
17+
open Microsoft.VisualStudio.FSharp.Editor.Telemetry
18+
open Microsoft.VisualStudio.Telemetry
1719

1820
[<AllowNullLiteral>]
1921
type internal FSharpNavigableSymbol(item: FSharpNavigableItem, span: SnapshotSpan, gtd: GoToDefinition) =
@@ -52,6 +54,9 @@ type internal FSharpNavigableSymbolSource(metadataAsSource) =
5254
// Task.Wait throws an exception if the task is cancelled, so be sure to catch it.
5355
try
5456
// This call to Wait() is fine because we want to be able to provide the error message in the status bar.
57+
use _ =
58+
TelemetryReporter.ReportSingleEventWithDuration(TelemetryEvents.GoToDefinitionGetSymbol, [||])
59+
5560
gtdTask.Wait(cancellationToken)
5661
statusBar.Clear()
5762

@@ -88,6 +93,8 @@ type internal FSharpNavigableSymbolSource(metadataAsSource) =
8893
// The NavigableSymbols API accepts 'null' when there's nothing to navigate to.
8994
return null
9095
with exc ->
96+
TelemetryReporter.ReportFault(TelemetryEvents.GoToDefinitionGetSymbol, FaultSeverity.General, exc)
97+
9198
statusBar.TempMessage(String.Format(SR.NavigateToFailed(), Exception.flattenMessage exc))
9299

93100
// The NavigableSymbols API accepts 'null' when there's nothing to navigate to.

vsintegration/src/FSharp.Editor/Telemetry/TelemetryReporter.fs

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ module TelemetryEvents =
2525
let LanguageServiceStarted = "languageservicestarted"
2626

2727
[<Literal>]
28-
let GetSymbolUsesInProjectsStarted = "getSymbolUsesInProjectsStarted"
28+
let GetSymbolUsesInProjectsStarted = "getsymbolusesinprojectsstarted"
2929

3030
[<Literal>]
31-
let GetSymbolUsesInProjectsFinished = "getSymbolUsesInProjectsFinished"
31+
let GetSymbolUsesInProjectsFinished = "getsymbolusesinprojectsfinished"
3232

3333
[<Literal>]
3434
let AddSyntacticCalssifications = "addsyntacticclassifications"
@@ -42,6 +42,12 @@ module TelemetryEvents =
4242
[<Literal>]
4343
let ProvideCompletions = "providecompletions"
4444

45+
[<Literal>]
46+
let GoToDefinition = "gotodefinition"
47+
48+
[<Literal>]
49+
let GoToDefinitionGetSymbol = "gotodefinition/getsymbol"
50+
4551
// TODO: needs to be something more sophisticated in future
4652
[<Struct; RequireQualifiedAccess; NoComparison; NoEquality>]
4753
type TelemetryThrottlingStrategy =
@@ -92,26 +98,44 @@ type TelemetryReporter private (name: string, props: (string * obj) array, stopw
9298
(let componentModel =
9399
Package.GetGlobalService(typeof<ComponentModelHost.SComponentModel>) :?> ComponentModelHost.IComponentModel
94100

95-
if componentModel = null then
101+
if isNull componentModel then
96102
TelemetryService.DefaultSession.IsUserMicrosoftInternal
97103
else
98104
let workspace = componentModel.GetService<VisualStudioWorkspace>()
99-
workspace.Services.GetService<EditorOptions>().Advanced.SendAdditionalTelemetry)
105+
106+
TelemetryService.DefaultSession.IsUserMicrosoftInternal
107+
|| workspace.Services.GetService<EditorOptions>().Advanced.SendAdditionalTelemetry)
108+
109+
static member ReportFault(name, ?severity: FaultSeverity, ?e: exn) =
110+
if TelemetryReporter.SendAdditionalTelemetry.Value then
111+
let faultName = String.Concat(name, "/fault")
112+
113+
match severity, e with
114+
| Some s, Some e -> TelemetryService.DefaultSession.PostFault(faultName, name, s, e)
115+
| None, Some e -> TelemetryService.DefaultSession.PostFault(faultName, name, e)
116+
| Some s, None -> TelemetryService.DefaultSession.PostFault(faultName, name, s)
117+
| None, None -> TelemetryService.DefaultSession.PostFault(faultName, name)
118+
|> ignore
119+
120+
static member ReportCustomFailure(name, ?props) =
121+
if TelemetryReporter.SendAdditionalTelemetry.Value then
122+
let props = defaultArg props [||]
123+
let name = String.Concat(name, "/failure")
124+
let event = TelemetryReporter.createEvent name props
125+
TelemetryService.DefaultSession.PostEvent event
100126

101127
static member ReportSingleEvent(name, props) =
102-
let event = TelemetryReporter.createEvent name props
103-
TelemetryService.DefaultSession.PostEvent event
128+
if TelemetryReporter.SendAdditionalTelemetry.Value then
129+
let event = TelemetryReporter.createEvent name props
130+
TelemetryService.DefaultSession.PostEvent event
104131

105132
// A naïve implementation using stopwatch and returning an IDisposable
106133
// TODO: needs a careful review, since it will be a hot path when we are sending telemetry
107134
static member ReportSingleEventWithDuration(name, props, ?throttlingStrategy) : IDisposable =
108135

109136
let additionalTelemetryEnabled = TelemetryReporter.SendAdditionalTelemetry.Value
110137

111-
let isUserMicrosoftInternal =
112-
TelemetryService.DefaultSession.IsUserMicrosoftInternal
113-
114-
if additionalTelemetryEnabled || isUserMicrosoftInternal then
138+
if additionalTelemetryEnabled then
115139
let throttlingStrategy =
116140
defaultArg throttlingStrategy TelemetryThrottlingStrategy.Default
117141

0 commit comments

Comments
 (0)