Skip to content

Commit

Permalink
Adds settings for OpenTelemetry
Browse files Browse the repository at this point in the history
  • Loading branch information
TheAngryByrd committed Feb 25, 2023
1 parent eaa04fb commit 731bc23
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 47 deletions.
30 changes: 29 additions & 1 deletion src/FsAutoComplete/LspHelpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,10 @@ type InlineValueDto =
{ Enabled: bool option
Prefix: string option }

type NotificationsDto =
{ Trace: bool option
TraceNamespaces: string array option }

type DebugDto =
{ DontCheckRelatedFiles: bool option
CheckFileDebouncerTimeout: int option
Expand Down Expand Up @@ -643,6 +647,7 @@ type FSharpConfigDto =
CodeLenses: CodeLensConfigDto option
PipelineHints: InlineValueDto option
InlayHints: InlayHintDto option
Notifications: NotificationsDto option
Debug: DebugDto option }

type FSharpConfigRequest = { FSharp: FSharpConfigDto }
Expand Down Expand Up @@ -673,6 +678,23 @@ type InlineValuesConfig =
{ Enabled = Some true
Prefix = Some "//" }

type NotificationsConfig =
{ Trace: bool
TraceNamespaces: string array }

static member Default =
{ Trace = false
TraceNamespaces = [||] }

static member FromDto(dto: NotificationsDto) : NotificationsConfig =
{ Trace = defaultArg dto.Trace NotificationsConfig.Default.Trace
TraceNamespaces = defaultArg dto.TraceNamespaces NotificationsConfig.Default.TraceNamespaces }


member this.AddDto(dto: NotificationsDto) : NotificationsConfig =
{ Trace = defaultArg dto.Trace this.Trace
TraceNamespaces = defaultArg dto.TraceNamespaces this.TraceNamespaces }

type DebugConfig =
{ DontCheckRelatedFiles: bool
CheckFileDebouncerTimeout: int
Expand Down Expand Up @@ -722,6 +744,7 @@ type FSharpConfig =
CodeLenses: CodeLensConfig
InlayHints: InlayHintsConfig
InlineValues: InlineValuesConfig
Notifications: NotificationsConfig
Debug: DebugConfig }

static member Default: FSharpConfig =
Expand Down Expand Up @@ -761,6 +784,7 @@ type FSharpConfig =
CodeLenses = CodeLensConfig.Default
InlayHints = InlayHintsConfig.Default
InlineValues = InlineValuesConfig.Default
Notifications = NotificationsConfig.Default
Debug = DebugConfig.Default }

static member FromDto(dto: FSharpConfigDto) : FSharpConfig =
Expand Down Expand Up @@ -825,7 +849,7 @@ type FSharpConfig =
| Some ivDto ->
{ Enabled = ivDto.Enabled |> Option.defaultValue true |> Some
Prefix = ivDto.Prefix |> Option.defaultValue "//" |> Some }

Notifications = dto.Notifications |> Option.map NotificationsConfig.FromDto |> Option.defaultValue NotificationsConfig.Default
Debug =
match dto.Debug with
| None -> DebugConfig.Default
Expand Down Expand Up @@ -908,6 +932,10 @@ type FSharpConfig =
InlineValues =
{ Enabled = defaultArg (dto.PipelineHints |> Option.map (fun n -> n.Enabled)) x.InlineValues.Enabled
Prefix = defaultArg (dto.PipelineHints |> Option.map (fun n -> n.Prefix)) x.InlineValues.Prefix }
Notifications =
dto.Notifications
|> Option.map x.Notifications.AddDto
|> Option.defaultValue NotificationsConfig.Default
Debug =
match dto.Debug with
| None -> DebugConfig.Default
Expand Down
18 changes: 13 additions & 5 deletions src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,15 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
/// in the future
let selectProject projs = projs |> List.tryHead

let mutable traceNotifications : ProgressListener option = None
let replaceTraceNotification shouldTrace traceNamespaces =
traceNotifications
|> Option.iter dispose
if shouldTrace then
traceNotifications <- Some(new ProgressListener(lspClient, traceNamespaces))
else
traceNotifications <- None

let mutableConfigChanges =
let toCompilerToolArgument (path: string) = sprintf "--compilertool:%s" path

Expand All @@ -204,6 +213,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
and! checker = checker
and! rootPath = rootPath

replaceTraceNotification config.Notifications.Trace config.Notifications.TraceNamespaces

checker.SetFSIAdditionalArguments
[| yield! config.FSICompilerToolLocations |> Array.map toCompilerToolArgument
yield! config.FSIExtraParameters |]
Expand Down Expand Up @@ -307,8 +318,6 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar

let fileChecked = Event<ParseAndCheckResults * VolatileFile * CancellationToken>()

do disposables.Add <| new ProgressListener(lspClient)

do
disposables.Add
<| fileParsed.Publish.Subscribe(fun (parseResults, proj, ct) ->
Expand Down Expand Up @@ -1703,8 +1712,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
percentage = percentage 0 checksToPerform.Length
)

let maxConcurrency = 3
// Math.Max(1.0, Math.Floor((float System.Environment.ProcessorCount) * 0.75))
let maxConcurrency =
Math.Max(1.0, Math.Floor((float System.Environment.ProcessorCount) * 0.75))
do! Async.Parallel(checksToPerform, int maxConcurrency) |> Async.Ignore<unit array>

}
Expand Down Expand Up @@ -2467,7 +2476,6 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
>> Log.addContextDestructured "parms" p
>> Log.addExn e
)

return! LspResult.internalError (string e)
}

Expand Down
67 changes: 40 additions & 27 deletions src/FsAutoComplete/LspServers/FSharpLspClient.fs
Original file line number Diff line number Diff line change
Expand Up @@ -149,25 +149,29 @@ open Ionide.ProjInfo.Logging


/// listener for the the events generated from the fsc ActivitySource
type ProgressListener(lspClient: FSharpLspClient) =

let isOneOf list string = list |> List.exists (fun f -> f string)
type ProgressListener(lspClient: FSharpLspClient, traceNamespace : string array) =

let isOneOf list string = list |> Array.exists (fun f -> f string)

let strEquals (other : string) (this : string) = this.Equals(other, StringComparison.InvariantCultureIgnoreCase)
let strContains (substring: string) (str: string) = str.Contains(substring)

let interestingActivities =
[

strContains "BoundModel."
strContains "IncrementalBuild."
strContains "CheckDeclarations."
strContains "ParseAndCheckInputs."
strContains "BackgroundCompiler."
strContains "IncrementalBuildSyntaxTree."
strContains "ParseAndCheckFile."
strContains "ParseAndCheckInputs."
strContains "CheckDeclarations." ]
traceNamespace
|> Array.map strContains
// [
// strEquals "BoundModel.TypeCheck"
// strContains "BackgroundCompiler."
// // strContains "BoundModel."
// // strContains "IncrementalBuild."
// // strContains "CheckDeclarations."
// // strContains "ParseAndCheckInputs."
// // strContains "BackgroundCompiler."
// // strContains "IncrementalBuildSyntaxTree."
// // strContains "ParseAndCheckFile."
// // strContains "ParseAndCheckInputs."
// // strContains "CheckDeclarations."
// ]

let logger = LogProvider.getLoggerByName "Compiler"

Expand All @@ -179,11 +183,13 @@ type ProgressListener(lspClient: FSharpLspClient) =
let isStopped (activity: Activity) =
#if NET6_0
false
||
#else
activity.IsStopped
||
#endif
// giving this 1 seconds to report something, otherwise assume it's a dead activity
|| ((DateTime.UtcNow - activity.StartTimeUtc) > TimeSpan.FromSeconds(1.)
((DateTime.UtcNow - activity.StartTimeUtc) > TimeSpan.FromSeconds(5.)
&& activity.Duration = TimeSpan.Zero)

let getTagItemSafe key (a: Activity) = a.GetTagItem key |> Option.ofObj
Expand All @@ -200,7 +206,6 @@ type ProgressListener(lspClient: FSharpLspClient) =
>> Option.map IO.Path.GetFileName
>> Option.defaultValue String.Empty


let getUserOpName =
getTagItemSafe Tracing.SemanticConventions.FCS.userOpName
>> Option.map string
Expand All @@ -218,9 +223,17 @@ type ProgressListener(lspClient: FSharpLspClient) =
inflightEvents.TryRemove(a.Id) |> ignore
else
// FSC doesn't start their spans with tags so we have to see if it's been added later https://github.com/dotnet/fsharp/issues/14776
let fileName = getFileName a
let userOpName = getUserOpName a
do! p.Report(message = $"{fileName} - {userOpName}")
let message =
String.Join(" - ",
[
getFileName a
getProject a
getUserOpName a
]
)


do! p.Report(message = message)

match! inbox.TryReceive(250) with
| None ->
Expand All @@ -233,10 +246,10 @@ type ProgressListener(lspClient: FSharpLspClient) =
let fileName = getFileName activity
let userOpName = getUserOpName activity

logger.debug (
Log.setMessageI
$"Started : {activity.DisplayName:DisplayName} - {userOpName:UserOpName} - {fileName:fileName}"
)
// logger.debug (
// Log.setMessageI
// $"Started : {activity.DisplayName:DisplayName} - {userOpName:UserOpName} - {fileName:fileName}"
// )

if
activity.DisplayName |> isOneOf interestingActivities
Expand All @@ -253,10 +266,10 @@ type ProgressListener(lspClient: FSharpLspClient) =
let userOpName = getUserOpName activity
let duration = activity.Duration.ToString()

logger.debug (
Log.setMessageI
$"Finished : {activity.DisplayName:DisplayName} - {userOpName:UserOpName} - {fileName:fileName} - took {duration:duration}"
)
// logger.debug (
// Log.setMessageI
// $"Finished : {activity.DisplayName:DisplayName} - {userOpName:UserOpName} - {fileName:fileName} - took {duration:duration}"
// )

if activity.DisplayName |> isOneOf interestingActivities then
match inflightEvents.TryRemove(activity.Id) with
Expand Down
38 changes: 24 additions & 14 deletions src/FsAutoComplete/Parser.fs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ module Parser =

let mutable tracerProvider = Unchecked.defaultof<_>



[<Struct>]
type Pos = { Line: int; Column: int }

Expand Down Expand Up @@ -95,6 +97,12 @@ module Parser =
"Enable LSP Server based on FSharp.Data.Adaptive. Should be more stable, but is experimental."
)

let otelTracingOption =
Option<bool>(
"--otel-tracing-enabled",
"Enabled OpenTelemetry exporter. See https://opentelemetry.io/docs/reference/specification/protocol/exporter/ for environment variables to configure for the exporter."
)

let stateLocationOption =
Option<DirectoryInfo>(
"--state-directory",
Expand All @@ -115,6 +123,7 @@ module Parser =
rootCommand.AddOption adaptiveLspServerOption
rootCommand.AddOption logLevelOption
rootCommand.AddOption stateLocationOption
rootCommand.AddOption otelTracingOption



Expand Down Expand Up @@ -178,20 +187,21 @@ module Parser =

let configureOTel =
Invocation.InvocationMiddleware(fun ctx next ->
let serviceName = FsAutoComplete.Utils.Tracing.serviceName
let version = FsAutoComplete.Utils.Version.info().Version

tracerProvider <-
Sdk
.CreateTracerProviderBuilder()
.AddSource(serviceName, Tracing.fscServiceName)
.SetResourceBuilder(
ResourceBuilder
.CreateDefault()
.AddService(serviceName = serviceName, serviceVersion = version)
)
.AddOtlpExporter()
.Build()

if ctx.ParseResult.HasOption otelTracingOption then
let serviceName = FsAutoComplete.Utils.Tracing.serviceName
let version = FsAutoComplete.Utils.Version.info().Version
tracerProvider <-
Sdk
.CreateTracerProviderBuilder()
.AddSource(serviceName, Tracing.fscServiceName)
.SetResourceBuilder(
ResourceBuilder
.CreateDefault()
.AddService(serviceName = serviceName, serviceVersion = version)
)
.AddOtlpExporter()
.Build()

next.Invoke(ctx))

Expand Down
1 change: 1 addition & 0 deletions test/FsAutoComplete.Tests.Lsp/Helpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ let defaultConfigDto: FSharpConfigDto =
Some
{ Enabled = Some true
Prefix = Some "//" }
Notifications = None
Debug = None }

let clientCaps: ClientCapabilities =
Expand Down

0 comments on commit 731bc23

Please sign in to comment.