diff --git a/Directory.Build.props b/Directory.Build.props
index 38d655380..511914bd1 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -4,7 +4,7 @@
FsAutoComplete
FsAutoComplete
Apache-2.0
- 3186
+ 3186,0042
true
$(MSBuildThisFileDirectory)CHANGELOG.md
diff --git a/README.md b/README.md
index 1b39b3e9c..18d811474 100644
--- a/README.md
+++ b/README.md
@@ -54,6 +54,41 @@ This repository is prepared to use Gitpod for a web-based VSCode-style IDE. Clic
* push this commit and tag to main
* the CI pipeline will publish a release from the tag.
+
+## OpenTelemetry
+
+FsAutocomplete is using [System.Diagnostics.Activity](https://learn.microsoft.com/en-us/dotnet/core/diagnostics/distributed-tracing-instrumentation-walkthroughs) to create traces.
+
+To export traces, run [Jaeger](https://www.jaegertracing.io/)
+
+```bash
+docker run -d --name jaeger \
+ -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \
+ -e COLLECTOR_OTLP_ENABLED=true \
+ -p 6831:6831/udp \
+ -p 6832:6832/udp \
+ -p 5778:5778 \
+ -p 16686:16686 \
+ -p 4317:4317 \
+ -p 4318:4318 \
+ -p 14250:14250 \
+ -p 14268:14268 \
+ -p 14269:14269 \
+ -p 9411:9411 \
+ jaegertracing/all-in-one:latest
+```
+Then configure your [environment](https://opentelemetry.io/docs/concepts/sdk-configuration/otlp-exporter-configuration/)
+
+```bash
+OTEL_EXPORTER_OTLP_ENDPOINT = "http://localhost:4317"
+```
+Start FsAutocomplete (either by `code .` or `dotnet fsautocomplete`)
+
+Do some actions like opening documents, saving, getting tooltips, etc.
+
+Then open `http://localhost:16686/` to inspect traces.
+
+
## Communication protocol
FsAutoComplete supports [LSP](https://microsoft.github.io/language-server-protocol/) as a communication protocol.
diff --git a/paket.dependencies b/paket.dependencies
index f5ce9d954..aa930516b 100644
--- a/paket.dependencies
+++ b/paket.dependencies
@@ -8,7 +8,9 @@ source https://api.nuget.org/v3/index.json
#source: ./libs
storage: none
-github TheAngryByrd/FsLibLog:f81cba440bf0476bb4e2262b57a067a0d6ab78a7 src/FsLibLog/FsLibLog.fs
+
+github TheAngryByrd/FsLibLog:64f118ae8df2f2944ef69758052cb3b148b87e79 src/FsLibLog/FsLibLog.fs
+github TheAngryByrd/FsOpenTelemetry src/FsOpenTelemetry/FsOpenTelemetry.fs
nuget Fantomas.Client
nuget FSharp.Compiler.Service
@@ -52,6 +54,7 @@ nuget AltCover
nuget GitHubActionsTestLogger
nuget Ionide.LanguageServerProtocol
nuget Microsoft.Extensions.Caching.Memory
+nuget OpenTelemetry.Exporter.OpenTelemetryProtocol
group Build
source https://api.nuget.org/v3/index.json
diff --git a/paket.lock b/paket.lock
index 8115bfe4d..f820c92d7 100644
--- a/paket.lock
+++ b/paket.lock
@@ -35,9 +35,10 @@ NUGET
FSharp.Core (>= 6.0.1) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net5.0))
McMaster.NETCore.Plugins (>= 1.4) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net5.0))
FSharp.Compiler.Service (43.7.200)
- FSharp.Core (7.0)
+ FSharp.Core (7.0.200)
System.Buffers (>= 4.5.1)
System.Collections.Immutable (>= 6.0)
+ System.Diagnostics.DiagnosticSource (>= 6.0)
System.Memory (>= 4.5.5)
System.Reflection.Emit (>= 4.7)
System.Reflection.Metadata (>= 6.0)
@@ -45,10 +46,10 @@ NUGET
FSharp.Control.AsyncSeq (3.2.1)
FSharp.Core (>= 4.7.2)
Microsoft.Bcl.AsyncInterfaces (>= 5.0)
- FSharp.Control.Reactive (5.0.5) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net5.0))
+ FSharp.Control.Reactive (5.0.5) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net6.0))
FSharp.Core (>= 4.7.2)
System.Reactive (>= 5.0 < 6.0)
- FSharp.Core (7.0) - content: none
+ FSharp.Core (7.0.200) - content: none
FSharp.Data.Adaptive (1.2.13)
FSharp.Core (>= 4.7)
System.Reflection.Emit.Lightweight (>= 4.6)
@@ -76,6 +77,21 @@ NUGET
FSharp.Core (>= 4.7.2)
GitHubActionsTestLogger (2.0.1)
Microsoft.TestPlatform.ObjectModel (>= 17.2)
+ Google.Protobuf (3.22)
+ System.Memory (>= 4.5.3) - restriction: || (&& (== net6.0) (>= net45)) (&& (== net6.0) (< net5.0)) (&& (== net6.0) (< netstandard2.0)) (&& (== net7.0) (>= net45)) (&& (== net7.0) (< net5.0)) (&& (== net7.0) (< netstandard2.0)) (== netstandard2.0)
+ System.Runtime.CompilerServices.Unsafe (>= 4.5.2) - restriction: || (&& (== net6.0) (< net5.0)) (&& (== net7.0) (< net5.0)) (== netstandard2.0)
+ Grpc (2.46.6) - restriction: || (&& (== net6.0) (>= net462)) (&& (== net6.0) (< netstandard2.1)) (&& (== net7.0) (>= net462)) (&& (== net7.0) (< netstandard2.1)) (== netstandard2.0)
+ Grpc.Core (>= 2.46.6)
+ Grpc.Core (2.46.6) - restriction: || (&& (== net6.0) (>= net45)) (&& (== net6.0) (>= net462)) (&& (== net6.0) (< netstandard2.1)) (&& (== net7.0) (>= net45)) (&& (== net7.0) (>= net462)) (&& (== net7.0) (< netstandard2.1)) (== netstandard2.0)
+ Grpc.Core.Api (>= 2.46.6)
+ System.Memory (>= 4.5.3)
+ Grpc.Core.Api (2.51)
+ System.Memory (>= 4.5.3)
+ Grpc.Net.Client (2.51) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= netstandard2.1))
+ Grpc.Net.Common (>= 2.51)
+ Microsoft.Extensions.Logging.Abstractions (>= 3.0.3)
+ Grpc.Net.Common (2.51) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= netstandard2.1))
+ Grpc.Core.Api (>= 2.51)
ICSharpCode.Decompiler (7.2.1.6856)
Microsoft.Win32.Registry (>= 5.0)
System.Collections.Immutable (>= 5.0)
@@ -85,25 +101,25 @@ NUGET
FSharp.Core (>= 6.0)
Newtonsoft.Json (>= 13.0.1)
StreamJsonRpc (>= 2.10.44)
- Ionide.ProjInfo (0.61)
+ Ionide.ProjInfo (0.61.2)
FSharp.Core (>= 6.0.5) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net6.0))
- Ionide.ProjInfo.Sln (>= 0.61) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net6.0))
+ Ionide.ProjInfo.Sln (>= 0.61.2) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net6.0))
Microsoft.Build (>= 17.2) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net6.0))
Microsoft.Build.Framework (>= 17.2) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net6.0))
SemanticVersioning (>= 2.0.2) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net6.0))
- Ionide.ProjInfo.FCS (0.61)
- FSharp.Compiler.Service (>= 41.0.5 < 42.0) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net6.0))
+ Ionide.ProjInfo.FCS (0.61.2)
+ FSharp.Compiler.Service (>= 41.0.5) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net6.0))
FSharp.Core (>= 6.0.5) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net6.0))
- Ionide.ProjInfo (>= 0.61) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net6.0))
- Ionide.ProjInfo.ProjectSystem (0.61)
- FSharp.Compiler.Service (>= 41.0.5 < 42.0) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net6.0))
+ Ionide.ProjInfo (>= 0.61.2) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net6.0))
+ Ionide.ProjInfo.ProjectSystem (0.61.2)
+ FSharp.Compiler.Service (>= 41.0.5) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net6.0))
FSharp.Control.Reactive (>= 5.0.5) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net6.0))
FSharp.Core (>= 6.0.5) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net6.0))
- Ionide.ProjInfo (>= 0.61) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net6.0))
- Ionide.ProjInfo.FCS (>= 0.61) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net6.0))
- Ionide.ProjInfo.Sln (>= 0.61) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net6.0))
+ Ionide.ProjInfo (>= 0.61.2) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net6.0))
+ Ionide.ProjInfo.FCS (>= 0.61.2) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net6.0))
+ Ionide.ProjInfo.Sln (>= 0.61.2) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net6.0))
Newtonsoft.Json (>= 13.0.1) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net6.0))
- Ionide.ProjInfo.Sln (0.61)
+ Ionide.ProjInfo.Sln (0.61.2)
McMaster.NETCore.Plugins (1.4) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net5.0))
Microsoft.DotNet.PlatformAbstractions (>= 3.1.6) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= netcoreapp2.1))
Microsoft.Extensions.DependencyModel (>= 5.0) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= netcoreapp2.1))
@@ -165,6 +181,18 @@ NUGET
Microsoft.Extensions.Logging.Abstractions (>= 6.0)
Microsoft.Extensions.Options (>= 6.0)
Microsoft.Extensions.Primitives (>= 6.0)
+ Microsoft.Extensions.Configuration (6.0.1)
+ Microsoft.Extensions.Configuration.Abstractions (>= 6.0)
+ Microsoft.Extensions.Primitives (>= 6.0)
+ Microsoft.Extensions.Configuration.Abstractions (6.0)
+ Microsoft.Extensions.Primitives (>= 6.0)
+ Microsoft.Extensions.Configuration.Binder (6.0)
+ Microsoft.Extensions.Configuration.Abstractions (>= 6.0)
+ Microsoft.Extensions.DependencyInjection (6.0.1)
+ Microsoft.Bcl.AsyncInterfaces (>= 6.0) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netstandard2.1)) (&& (== net7.0) (>= net461)) (&& (== net7.0) (< netstandard2.1)) (== netstandard2.0)
+ Microsoft.Extensions.DependencyInjection.Abstractions (>= 6.0)
+ System.Runtime.CompilerServices.Unsafe (>= 6.0)
+ System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netstandard2.1)) (&& (== net7.0) (>= net461)) (&& (== net7.0) (< netstandard2.1)) (== netstandard2.0)
Microsoft.Extensions.DependencyInjection.Abstractions (6.0)
Microsoft.Bcl.AsyncInterfaces (>= 6.0) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netstandard2.1)) (&& (== net7.0) (>= net461)) (&& (== net7.0) (< netstandard2.1)) (== netstandard2.0)
System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netstandard2.1)) (&& (== net7.0) (>= net461)) (&& (== net7.0) (< netstandard2.1)) (== netstandard2.0)
@@ -174,13 +202,35 @@ NUGET
System.Runtime.CompilerServices.Unsafe (>= 6.0)
System.Text.Encodings.Web (>= 6.0)
System.Text.Json (>= 6.0)
+ Microsoft.Extensions.Logging (6.0)
+ Microsoft.Bcl.AsyncInterfaces (>= 6.0) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netstandard2.1)) (&& (== net7.0) (>= net461)) (&& (== net7.0) (< netstandard2.1)) (== netstandard2.0)
+ Microsoft.Extensions.DependencyInjection (>= 6.0)
+ Microsoft.Extensions.DependencyInjection.Abstractions (>= 6.0)
+ Microsoft.Extensions.Logging.Abstractions (>= 6.0)
+ Microsoft.Extensions.Options (>= 6.0)
+ System.Diagnostics.DiagnosticSource (>= 6.0)
Microsoft.Extensions.Logging.Abstractions (6.0.2)
System.Buffers (>= 4.5.1) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net7.0) (>= net461)) (&& (== net7.0) (< net6.0)) (== netstandard2.0)
System.Memory (>= 4.5.4) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net7.0) (>= net461)) (&& (== net7.0) (< net6.0)) (== netstandard2.0)
+ Microsoft.Extensions.Logging.Configuration (6.0)
+ Microsoft.Extensions.Configuration (>= 6.0)
+ Microsoft.Extensions.Configuration.Abstractions (>= 6.0)
+ Microsoft.Extensions.Configuration.Binder (>= 6.0)
+ Microsoft.Extensions.DependencyInjection.Abstractions (>= 6.0)
+ Microsoft.Extensions.Logging (>= 6.0)
+ Microsoft.Extensions.Logging.Abstractions (>= 6.0)
+ Microsoft.Extensions.Options (>= 6.0)
+ Microsoft.Extensions.Options.ConfigurationExtensions (>= 6.0)
Microsoft.Extensions.Options (6.0)
Microsoft.Extensions.DependencyInjection.Abstractions (>= 6.0)
Microsoft.Extensions.Primitives (>= 6.0)
System.ComponentModel.Annotations (>= 5.0) - restriction: || (&& (== net6.0) (< netstandard2.1)) (&& (== net7.0) (< netstandard2.1)) (== netstandard2.0)
+ Microsoft.Extensions.Options.ConfigurationExtensions (6.0)
+ Microsoft.Extensions.Configuration.Abstractions (>= 6.0)
+ Microsoft.Extensions.Configuration.Binder (>= 6.0)
+ Microsoft.Extensions.DependencyInjection.Abstractions (>= 6.0)
+ Microsoft.Extensions.Options (>= 6.0)
+ Microsoft.Extensions.Primitives (>= 6.0)
Microsoft.Extensions.Primitives (6.0)
System.Memory (>= 4.5.4) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp3.1)) (&& (== net7.0) (>= net461)) (&& (== net7.0) (< netcoreapp3.1)) (== netstandard2.0)
System.Runtime.CompilerServices.Unsafe (>= 6.0)
@@ -233,6 +283,20 @@ NUGET
System.Runtime.CompilerServices.Unsafe (>= 5.0)
Newtonsoft.Json (13.0.2)
NuGet.Frameworks (6.3) - copy_local: false
+ OpenTelemetry (1.3.2)
+ Microsoft.Extensions.Logging (>= 3.1)
+ Microsoft.Extensions.Logging.Configuration (>= 3.1)
+ OpenTelemetry.Api (>= 1.3.2)
+ System.Collections.Immutable (>= 1.4)
+ System.Reflection.Emit.Lightweight (>= 4.7)
+ OpenTelemetry.Api (1.3.2)
+ System.Diagnostics.DiagnosticSource (>= 6.0 < 8.0)
+ System.Reflection.Emit.Lightweight (>= 4.7)
+ OpenTelemetry.Exporter.OpenTelemetryProtocol (1.3.2)
+ Google.Protobuf (>= 3.19.4 < 4.0)
+ Grpc (>= 2.44 < 3.0) - restriction: || (&& (== net6.0) (>= net462)) (&& (== net6.0) (< netstandard2.1)) (&& (== net7.0) (>= net462)) (&& (== net7.0) (< netstandard2.1)) (== netstandard2.0)
+ Grpc.Net.Client (>= 2.43 < 3.0) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= netstandard2.1))
+ OpenTelemetry (>= 1.3.2)
SemanticVersioning (2.0.2)
Serilog (2.11)
Serilog.Sinks.Async (1.5)
@@ -279,7 +343,7 @@ NUGET
System.Numerics.Vectors (>= 4.4) - restriction: || (&& (== net6.0) (< netcoreapp2.0)) (&& (== net7.0) (< netcoreapp2.0)) (== netstandard2.0)
System.Runtime.CompilerServices.Unsafe (>= 4.5.3) - restriction: || (&& (== net6.0) (>= monotouch)) (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp2.0)) (&& (== net6.0) (< netcoreapp2.1)) (&& (== net6.0) (< netstandard1.1)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (>= uap10.1)) (&& (== net6.0) (>= xamarinios)) (&& (== net6.0) (>= xamarinmac)) (&& (== net6.0) (>= xamarintvos)) (&& (== net6.0) (>= xamarinwatchos)) (&& (== net7.0) (>= monotouch)) (&& (== net7.0) (>= net461)) (&& (== net7.0) (< netcoreapp2.0)) (&& (== net7.0) (< netcoreapp2.1)) (&& (== net7.0) (< netstandard1.1)) (&& (== net7.0) (< netstandard2.0)) (&& (== net7.0) (>= uap10.1)) (&& (== net7.0) (>= xamarinios)) (&& (== net7.0) (>= xamarinmac)) (&& (== net7.0) (>= xamarintvos)) (&& (== net7.0) (>= xamarinwatchos)) (== netstandard2.0)
System.Numerics.Vectors (4.5) - restriction: || (&& (== net6.0) (< netcoreapp2.0)) (&& (== net7.0) (< netcoreapp2.0)) (== netstandard2.0)
- System.Reactive (5.0) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net5.0))
+ System.Reactive (5.0) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= net6.0))
System.Reflection.Emit (4.7)
System.Reflection.Emit.ILGeneration (>= 4.7) - restriction: || (&& (== net6.0) (< netcoreapp2.0) (< netstandard2.1)) (&& (== net6.0) (< netstandard1.1)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (>= uap10.1)) (&& (== net7.0) (< netcoreapp2.0) (< netstandard2.1)) (&& (== net7.0) (< netstandard1.1)) (&& (== net7.0) (< netstandard2.0)) (&& (== net7.0) (>= uap10.1)) (== netstandard2.0)
System.Reflection.Emit.ILGeneration (4.7) - restriction: || (&& (== net6.0) (< netcoreapp2.0) (< netstandard2.1)) (&& (== net6.0) (< netstandard1.1)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (>= uap10.1)) (&& (== net7.0) (< netcoreapp2.0) (< netstandard2.1)) (&& (== net7.0) (< netstandard1.1)) (&& (== net7.0) (< netstandard2.0)) (&& (== net7.0) (>= uap10.1)) (== netstandard2.0)
@@ -327,7 +391,9 @@ NUGET
System.Collections.Immutable (>= 6.0) - restriction: || (== net6.0) (== net7.0) (&& (== netstandard2.0) (>= netcoreapp3.1))
GITHUB
remote: TheAngryByrd/FsLibLog
- src/FsLibLog/FsLibLog.fs (f81cba440bf0476bb4e2262b57a067a0d6ab78a7)
+ src/FsLibLog/FsLibLog.fs (64f118ae8df2f2944ef69758052cb3b148b87e79)
+ remote: TheAngryByrd/FsOpenTelemetry
+ src/FsOpenTelemetry/FsOpenTelemetry.fs (fb24e8d4dc8ad14187b9b4631854fc8f17fb244d)
GROUP Build
STORAGE: NONE
RESTRICTION: || (== net6.0) (== net7.0)
diff --git a/src/FsAutoComplete.Core/Utils.fs b/src/FsAutoComplete.Core/Utils.fs
index f0b410b7e..5699b192c 100644
--- a/src/FsAutoComplete.Core/Utils.fs
+++ b/src/FsAutoComplete.Core/Utils.fs
@@ -10,6 +10,14 @@ open FSharp.Compiler.CodeAnalysis
open FSharp.UMX
open FSharp.Compiler.Symbols
+
+/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+let dispose (d: #IDisposable) = d.Dispose()
+
+/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources asynchronously.
+/// A task that represents the asynchronous dispose operation.
+let disposeAsync (d: #IAsyncDisposable) = d.DisposeAsync()
+
module Map =
/// Combine two maps of identical types by starting with the first map and overlaying the second one.
/// Because map updates shadow, any keys in the second map will have priority.
@@ -148,6 +156,7 @@ let projectOptionsToParseOptions (checkOptions: FSharpProjectOptions) =
{ FSharpParsingOptions.Default with
SourceFiles = files }
+
[]
module Option =
@@ -516,6 +525,9 @@ module List =
[]
[]
module String =
+ /// Concatenates all the elements of a string array, using the specified separator between each element.
+ let inline join (separator: string) (items: string seq) = String.Join(separator, items)
+
let inline toCharArray (str: string) = str.ToCharArray()
let lowerCaseFirstChar (str: string) =
@@ -822,3 +834,81 @@ type FSharpSymbol with
| :? FSharpStaticParameter as s -> s.DeclarationLocation
| :? FSharpParameter as p -> p.DeclarationLocation
| _ -> failwith $"cannot fetch DefinitionRange for unknown FSharpSymbol subtype {x.GetType().FullName}"
+
+module Tracing =
+
+ open System.Diagnostics
+ open FsOpenTelemetry
+ open StreamJsonRpc
+ open System.Collections.Generic
+
+ module SemanticConventions =
+ ///
+ /// From F# compiler
+ ///
+ module FCS =
+ []
+ let fileName = "fileName"
+
+ []
+ let project = "project"
+
+ []
+ let qualifiedNameOfFile = "qualifiedNameOfFile"
+
+ []
+ let userOpName = "userOpName"
+
+ []
+ let fsac_sourceCodePath = "fsac.sourceCodePath"
+
+ []
+ let projectFilePath = "fsac.projectFilePath"
+
+ []
+ let serviceName = "FsAutoComplete"
+
+ ///
+ /// From F# compiler
+ ///
+ []
+ let fscServiceName = "fsc"
+
+ let fsacActivitySource = new ActivitySource(serviceName, Version.info().Version)
+
+ ///
+ /// StreamJsonRpcTracingStrategy participates in and propagates trace context in vs-streamjsonrpc
+ ///
+ ///
+ ///
+ /// vs-streamjsonrpc tracecontext documentation
+ ///
+ type StreamJsonRpcTracingStrategy(activitySource: ActivitySource) =
+ interface IActivityTracingStrategy with
+ member this.ApplyInboundActivity(request: Protocol.JsonRpcRequest) : IDisposable =
+ let tags =
+ [ "rpc.system", box "jsonrpc"
+ "rpc.jsonrpc.is_notification", box request.IsNotification
+ "rpc.jsonrpc.is_response_expected", box request.IsResponseExpected
+ "rpc.jsonrpc.version", box request.Version
+ "rpc.jsonrpc.request_id", box request.RequestId
+ "rpc.method", box request.Method ]
+ |> Seq.map KeyValuePair
+
+ let activity =
+ activitySource.StartActivity(ActivityKind.Server, name = request.Method, tags = tags)
+
+ if activity <> null then
+ activity.TraceStateString <- request.TraceState
+
+ if request.TraceParent <> null then
+ activity.SetParentId(request.TraceParent) |> ignore
+
+ activity
+
+ member this.ApplyOutboundActivity(request: Protocol.JsonRpcRequest) : unit =
+ if Activity.Current <> null && Activity.Current.IdFormat = ActivityIdFormat.W3C then
+ request.TraceParent <- Activity.Current.Id
+ request.TraceState <- Activity.Current.TraceStateString
+
+ ()
diff --git a/src/FsAutoComplete.Logging/FsAutoComplete.Logging.fsproj b/src/FsAutoComplete.Logging/FsAutoComplete.Logging.fsproj
index a0fdf42e3..603d10d14 100644
--- a/src/FsAutoComplete.Logging/FsAutoComplete.Logging.fsproj
+++ b/src/FsAutoComplete.Logging/FsAutoComplete.Logging.fsproj
@@ -1,10 +1,14 @@
- netstandard2.0
+ net6.0
false
+
+ True
+ paket-files/FsOpenTelemetry.fs
+
True
paket-files/FsLibLog.fs
diff --git a/src/FsAutoComplete.Logging/paket.references b/src/FsAutoComplete.Logging/paket.references
index 6252aa3a0..9e581c8fb 100644
--- a/src/FsAutoComplete.Logging/paket.references
+++ b/src/FsAutoComplete.Logging/paket.references
@@ -1,6 +1,7 @@
FSharp.Core
File: FsLibLog.fs
+File: FsOpenTelemetry.fs
Microsoft.NETFramework.ReferenceAssemblies
-Ionide.KeepAChangelog.Tasks
\ No newline at end of file
+Ionide.KeepAChangelog.Tasks
diff --git a/src/FsAutoComplete/LspHelpers.fs b/src/FsAutoComplete/LspHelpers.fs
index 2aa996b30..69a6b945c 100644
--- a/src/FsAutoComplete/LspHelpers.fs
+++ b/src/FsAutoComplete/LspHelpers.fs
@@ -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
@@ -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 }
@@ -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
@@ -722,6 +744,7 @@ type FSharpConfig =
CodeLenses: CodeLensConfig
InlayHints: InlayHintsConfig
InlineValues: InlineValuesConfig
+ Notifications: NotificationsConfig
Debug: DebugConfig }
static member Default: FSharpConfig =
@@ -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 =
@@ -825,7 +849,10 @@ 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
@@ -908,6 +935,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
diff --git a/src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs b/src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs
index 176ad6cea..3756cc247 100644
--- a/src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs
+++ b/src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs
@@ -16,6 +16,8 @@ open Newtonsoft.Json.Linq
open Ionide.ProjInfo.ProjectSystem
open FsToolkit.ErrorHandling
+open FsOpenTelemetry
+open FsAutoComplete.Utils.Tracing
open FSharp.UMX
open FSharp.Compiler.Text
@@ -176,6 +178,8 @@ type AdaptiveWorkspaceChosen =
type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FSharpLspClient) =
+ let thisType = typeof
+
let disposables = new System.Reactive.Disposables.CompositeDisposable()
let rootPath = cval None
@@ -192,6 +196,16 @@ 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
@@ -200,6 +214,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 |]
@@ -303,7 +319,6 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
let fileChecked = Event()
-
do
disposables.Add
<| fileParsed.Publish.Subscribe(fun (parseResults, proj, ct) ->
@@ -821,8 +836,6 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
| (true, v) -> Some v
| _ -> None
-
-
let openFiles = cmap, cval> ()
let openFilesReadOnly = openFiles |> AMap.map (fun _ x -> x :> aval<_>)
@@ -1131,102 +1144,102 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
}
- static let semaphore = new SemaphoreSlim(1, 1)
-
let parseAndCheckFile (checker: FSharpCompilerServiceChecker) (file: VolatileFile) opts config =
async {
- try
- logger.info (
- Log.setMessage "Getting typecheck results for {file} - {hash} - {date}"
- >> Log.addContextDestructured "file" file.Lines.FileName
- >> Log.addContextDestructured "hash" (file.Lines.GetHashCode())
- >> Log.addContextDestructured "date" (file.Touched)
- )
+ let tags =
+ [ SemanticConventions.fsac_sourceCodePath, box (UMX.untag file.Lines.FileName)
+ SemanticConventions.projectFilePath, box (opts.ProjectFileName) ]
- let! ct = Async.CancellationToken
- do! semaphore.WaitAsync(ct) |> Async.AwaitTask
+ use _ = fsacActivitySource.StartActivityForType(thisType, tags = tags)
- use pgl = new ProgressListener(lspClient)
- use progressReport = new ServerProgressReport(lspClient)
- use _ = ct.Register(fun () -> pgl.Dispose())
+ logger.info (
+ Log.setMessage "Getting typecheck results for {file} - {hash} - {date}"
+ >> Log.addContextDestructured "file" file.Lines.FileName
+ >> Log.addContextDestructured "hash" (file.Lines.GetHashCode())
+ >> Log.addContextDestructured "date" (file.Touched)
+ )
- let simpleName = Path.GetFileName(UMX.untag file.Lines.FileName)
- do! progressReport.Begin($"Typechecking {simpleName}", message = $"{file.Lines.FileName}")
+ let! ct = Async.CancellationToken
+ use progressReport = new ServerProgressReport(lspClient)
- // HACK: Insurance for a bug where FCS invalidates graph nodes incorrectly and seems to typecheck forever
- use cts = new CancellationTokenSource()
- cts.CancelAfter(TimeSpan.FromSeconds(60.))
+ let simpleName = Path.GetFileName(UMX.untag file.Lines.FileName)
+ do! progressReport.Begin($"Typechecking {simpleName}", message = $"{file.Lines.FileName}")
- let! result =
- checker.ParseAndCheckFileInProject(file.Lines.FileName, (file.Lines.GetHashCode()), file.Lines, opts)
- |> Async.withCancellation cts.Token
- |> Debug.measureAsync $"checker.ParseAndCheckFileInProject - {file.Lines.FileName}"
- do! progressReport.End($"Typechecked {file.Lines.FileName}")
+ // HACK: Insurance for a bug where FCS invalidates graph nodes incorrectly and seems to typecheck forever
+ use cts = new CancellationTokenSource()
+ cts.CancelAfter(TimeSpan.FromSeconds(60.))
- notifications.Trigger(NotificationEvent.FileParsed(file.Lines.FileName), ct)
+ let! result =
+ checker.ParseAndCheckFileInProject(file.Lines.FileName, (file.Lines.GetHashCode()), file.Lines, opts)
+ |> Async.withCancellation cts.Token
+ |> Debug.measureAsync $"checker.ParseAndCheckFileInProject - {file.Lines.FileName}"
- match result with
- | Error e ->
- logger.info (
- Log.setMessage "Typecheck failed for {file} with {error}"
- >> Log.addContextDestructured "file" file
- >> Log.addContextDestructured "error" e
- )
+ do! progressReport.End($"Typechecked {file.Lines.FileName}")
- return failwith e
- | Ok parseAndCheck ->
- logger.info (
- Log.setMessage "Typecheck completed successfully for {file}"
- >> Log.addContextDestructured "file" file.Lines.FileName
- )
+ notifications.Trigger(NotificationEvent.FileParsed(file.Lines.FileName), ct)
- Async.Start(
- async {
+ match result with
+ | Error e ->
+ logger.info (
+ Log.setMessage "Typecheck failed for {file} with {error}"
+ >> Log.addContextDestructured "file" file
+ >> Log.addContextDestructured "error" e
+ )
- fileParsed.Trigger(parseAndCheck.GetParseResults, opts, ct)
- fileChecked.Trigger(parseAndCheck, file, ct)
- let checkErrors = parseAndCheck.GetParseResults.Diagnostics
- let parseErrors = parseAndCheck.GetCheckResults.Diagnostics
+ return failwith e
+ | Ok parseAndCheck ->
+ logger.info (
+ Log.setMessage "Typecheck completed successfully for {file}"
+ >> Log.addContextDestructured "file" file.Lines.FileName
+ )
- let errors =
- Array.append checkErrors parseErrors
- |> Array.distinctBy (fun e ->
- e.Severity, e.ErrorNumber, e.StartLine, e.StartColumn, e.EndLine, e.EndColumn, e.Message)
+ Async.Start(
+ async {
- notifications.Trigger(NotificationEvent.ParseError(errors, file.Lines.FileName), ct)
- },
- ct
- )
+ fileParsed.Trigger(parseAndCheck.GetParseResults, opts, ct)
+ fileChecked.Trigger(parseAndCheck, file, ct)
+ let checkErrors = parseAndCheck.GetParseResults.Diagnostics
+ let parseErrors = parseAndCheck.GetCheckResults.Diagnostics
- Async.Start(analyzeFile config (file.Lines.FileName, file.Version, file.Lines, parseAndCheck), ct)
+ let errors =
+ Array.append checkErrors parseErrors
+ |> Array.distinctBy (fun e ->
+ e.Severity, e.ErrorNumber, e.StartLine, e.StartColumn, e.EndLine, e.EndColumn, e.Message)
- return parseAndCheck
- finally
- try
- semaphore.Release() |> ignore
- with :? SemaphoreFullException ->
- ()
+ notifications.Trigger(NotificationEvent.ParseError(errors, file.Lines.FileName), ct)
+ },
+ ct
+ )
+
+ Async.Start(analyzeFile config (file.Lines.FileName, file.Version, file.Lines, parseAndCheck), ct)
+
+ return parseAndCheck
}
/// Bypass Adaptive checking and tell the checker to check a file
- let bypassAdaptiveTypeCheck f opts =
+ let bypassAdaptiveTypeCheck (filePath: string) opts =
async {
+
try
- logger.info (Log.setMessage "Forced Check : {file}" >> Log.addContextDestructured "file" f)
+ logger.info (
+ Log.setMessage "Forced Check : {file}"
+ >> Log.addContextDestructured "file" filePath
+ )
+
let checker = checker |> AVal.force
let config = config |> AVal.force
- match forceFindOpenFileOrRead f with
+ match forceFindOpenFileOrRead filePath with
| Ok(fileInfo) -> return! parseAndCheckFile checker fileInfo opts config |> Async.Ignore
| _ -> ()
with e ->
logger.warn (
Log.setMessage "Forced Check error : {file}"
- >> Log.addContextDestructured "file" f
+ >> Log.addContextDestructured "file" filePath
>> Log.addExn e
)
}
@@ -1315,12 +1328,12 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
|> AVal.force
|> Result.ofOption (fun () -> $"No typecheck results for {filePath}")
- let forceGetTypeCheckResults filePath =
+ let forceGetTypeCheckResults (filePath: string) =
getTypeCheckResults (filePath)
|> AVal.force
|> Result.ofOption (fun () -> $"No typecheck results for {filePath}")
- let forceGetTypeCheckResultsStale filePath =
+ let forceGetTypeCheckResultsStale (filePath: string) =
aval {
let! checker = checker
@@ -1635,8 +1648,10 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
Seq.toList allDependents
- let bypassAdaptiveAndCheckDepenenciesForFile filePath =
+ let bypassAdaptiveAndCheckDepenenciesForFile (filePath: string) =
async {
+ let tags = [ SemanticConventions.fsac_sourceCodePath, box (UMX.untag filePath) ]
+ use _ = fsacActivitySource.StartActivityForType(thisType, tags = tags)
let dependentFiles = getDependentFilesForFile filePath
let dependentProjects =
@@ -1661,7 +1676,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
let checksToPerform =
let innerChecks =
Array.concat [| dependentFiles; dependentProjects |]
- |> Array.filter (fun (_, file) -> file.Contains "AssemblyInfo.fs" |> not)
+ |> Array.filter (fun (_, file) ->
+ file.Contains "AssemblyInfo.fs" |> not
+ && file.Contains "AssemblyAttributes.fs" |> not)
let checksToPerformLength = innerChecks.Length
@@ -1696,7 +1713,10 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
percentage = percentage 0 checksToPerform.Length
)
- do! Async.Parallel(checksToPerform, 2) |> Async.Ignore
+ let maxConcurrency =
+ Math.Max(1.0, Math.Floor((float System.Environment.ProcessorCount) * 0.75))
+
+ do! Async.Parallel(checksToPerform, int maxConcurrency) |> Async.Ignore
}
@@ -1713,9 +1733,7 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
getProjectOptionsForFile file |> AVal.force
let getProjectOptionsForFsproj file =
- loadedProjectOptions
- |> AVal.force
- |> Seq.tryFind (fun x -> x.ProjectFileName = file)
+ forceLoadProjects () |> Seq.tryFind (fun x -> x.ProjectFileName = file)
let getDeclarationLocation (symUse, text) =
@@ -1763,7 +1781,12 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
handleFormattedRange: (NamedText * string * FormatSelectionRange) -> TextEdit[]
) : Async>> =
asyncResult {
+ let tags = [ SemanticConventions.fsac_sourceCodePath, box fileName ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
+
+
let! res = action () |> AsyncResult.ofStringErr
let rootPath = rootPath |> AVal.force
@@ -1893,6 +1916,7 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return! LspResult.internalError "Fantomas install not found."
| (FormatDocumentResponse.Error ex) -> return! LspResult.internalError ex
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
logger.error (Log.setMessage "HandleFormatting Request Errored {p}" >> Log.addExn e)
return! LspResult.internalError (string e)
}
@@ -1905,6 +1929,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override _.Initialize(p: InitializeParams) =
asyncResult {
+ let tags = [ "InitializeParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (Log.setMessage "Initialize Request {p}" >> Log.addContextDestructured "p" p)
@@ -1980,6 +2007,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
Capabilities = defaultSettings }
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "Initialize Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -1991,6 +2020,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override __.Initialized(p: InitializedParams) =
async {
+ let tags = [ "InitializedParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (Log.setMessage "Initialized request {p}" >> Log.addContextDestructured "p" p)
// Starts getting project options to cache
@@ -1998,6 +2030,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return ()
with e ->
+
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "Initialized Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -2009,7 +2044,12 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override __.TextDocumentDidOpen(p: DidOpenTextDocumentParams) =
async {
+ let tags = [ "InitializedParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
+ trace.SetTagSafe("DidOpenTextDocumentParams", p) |> ignore
+
logger.info (
Log.setMessage "TextDocumentDidOpen Request: {parms}"
>> Log.addContextDestructured "parms" p
@@ -2027,6 +2067,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
forceGetTypeCheckResults filePath |> ignore
return ()
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "TextDocumentDidOpen Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -2038,6 +2080,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override __.TextDocumentDidClose(p: DidCloseTextDocumentParams) =
async {
+ let tags = [ "DidCloseTextDocumentParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "TextDocumentDidClose Request: {parms}"
@@ -2049,6 +2094,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return ()
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "TextDocumentDidClose Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -2060,6 +2107,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override __.TextDocumentDidChange(p: DidChangeTextDocumentParams) =
async {
+ let tags = [ "DidChangeTextDocumentParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "TextDocumentDidChange Request: {parms}"
@@ -2076,6 +2126,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return ()
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "TextDocumentDidChange Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -2085,9 +2137,13 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return ()
}
- override __.TextDocumentDidSave(p) =
+ override __.TextDocumentDidSave(p: DidSaveTextDocumentParams) =
async {
+ let tags = [ "DidSaveTextDocumentParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
+
logger.info (
Log.setMessage "TextDocumentDidSave Request: {parms}"
>> Log.addContextDestructured "parms" p
@@ -2121,6 +2177,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return ()
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "TextDocumentDidSave Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -2131,8 +2189,10 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
}
override __.TextDocumentCompletion(p: CompletionParams) =
- Debug.measureAsync "TextDocumentCompletion"
- <| asyncResult {
+ asyncResult {
+ let tags = [ "CompletionParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "TextDocumentCompletion Request: {parms}"
@@ -2251,6 +2311,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
success (Some completionList)
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "TextDocumentCompletion Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -2324,8 +2386,11 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
CoreResponse.Res(HelpText.Full(sym, tip, n))
- Debug.measureAsync "CompletionItemResolve"
- <| asyncResult {
+
+ asyncResult {
+ let tags = [ "CompletionItem", box ci ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "CompletionItemResolve Request: {parms}"
@@ -2342,6 +2407,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
|> success
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "CompletionItemResolve Request Errored {p}"
>> Log.addContextDestructured "p" ci
@@ -2353,6 +2420,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override x.TextDocumentSignatureHelp(p: SignatureHelpParams) =
asyncResult {
+ let tags = [ "SignatureHelpParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "TextDocumentSignatureHelp Request: {parms}"
@@ -2402,6 +2472,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return! success (Some res)
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "TextDocumentSignatureHelp Request: {parms}"
>> Log.addContextDestructured "parms" p
@@ -2413,6 +2485,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override x.TextDocumentHover(p: TextDocumentPositionParams) =
asyncResult {
+ let tags = [ "TextDocumentPositionParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "TextDocumentHover Request: {parms}"
@@ -2480,9 +2555,12 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return! LspResult.internalError $"No TryGetToolTipEnhanced results for {filePath}"
| Error e ->
+ trace.RecordError(e, "TextDocumentHover.Error") |> ignore
logger.error (Log.setMessage "Failed with {error}" >> Log.addContext "error" e)
return! LspResult.internalError e
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "TextDocumentHover Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -2494,6 +2572,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override x.TextDocumentRename(p: RenameParams) =
asyncResult {
+ let tags = [ "RenameParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "TextDocumentRename Request: {parms}"
@@ -2537,6 +2618,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
let clientCapabilities = clientCapabilities |> AVal.force |> Option.get
return WorkspaceEdit.Create(documentChanges, clientCapabilities) |> Some
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "TextDocumentRename Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -2548,6 +2631,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override x.TextDocumentDefinition(p: TextDocumentPositionParams) =
asyncResult {
+ let tags = [ "TextDocumentPositionParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "TextDocumentDefinition Request: {parms}"
@@ -2562,6 +2648,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
let! decl = tyRes.TryFindDeclaration pos lineStr |> AsyncResult.ofStringErr
return decl |> findDeclToLspLocation |> GotoResult.Single |> Some
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "TextDocumentDefinition Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -2573,6 +2661,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override x.TextDocumentTypeDefinition(p: TextDocumentPositionParams) =
asyncResult {
+ let tags = [ "TextDocumentPositionParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "TextDocumentTypeDefinition Request: {parms}"
@@ -2587,6 +2678,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
let! decl = tyRes.TryFindTypeDeclaration pos lineStr |> AsyncResult.ofStringErr
return decl |> findDeclToLspLocation |> GotoResult.Single |> Some
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "TextDocumentTypeDefinition Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -2598,6 +2691,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override x.TextDocumentReferences(p: ReferenceParams) =
asyncResult {
+ let tags = [ "ReferenceParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "TextDocumentReferences Request: {parms}"
@@ -2627,6 +2723,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
|> Seq.toArray
|> Some
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "TextDocumentReferences Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -2636,8 +2734,11 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return! LspResult.internalError (string e)
}
- override x.TextDocumentDocumentHighlight(p) =
+ override x.TextDocumentDocumentHighlight(p: TextDocumentPositionParams) =
asyncResult {
+ let tags = [ "TextDocumentPositionParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "TextDocumentDocumentHighlight Request: {parms}"
@@ -2658,6 +2759,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
Kind = None })
|> Some
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "TextDocumentDocumentHighlight Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -2668,8 +2771,11 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
}
- override x.TextDocumentImplementation(p) =
+ override x.TextDocumentImplementation(p: TextDocumentPositionParams) =
asyncResult {
+ let tags = [ "TextDocumentPositionParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "TextDocumentImplementation Request: {parms}"
@@ -2720,6 +2826,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
| [| single |] -> return Some(GotoResult.Single single)
| multiple -> return Some(GotoResult.Multiple multiple)
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "TextDocumentImplementation Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -2729,8 +2837,11 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return! LspResult.internalError (string e)
}
- override __.TextDocumentDocumentSymbol(p) =
+ override __.TextDocumentDocumentSymbol(p: DocumentSymbolParams) =
asyncResult {
+ let tags = [ "DocumentSymbolParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "TextDocumentDocumentSymbol Request: {parms}"
@@ -2752,6 +2863,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
|> Some
| None -> return! LspResult.internalError $"No declarations for {fn}"
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "TextDocumentDocumentSymbol Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -2764,6 +2877,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override __.WorkspaceSymbol(symbolRequest: WorkspaceSymbolParams) =
asyncResult {
+ let tags = [ "WorkspaceSymbolParams", box symbolRequest ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "WorkspaceSymbol Request: {parms}"
@@ -2786,6 +2902,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return res
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "WorkspaceSymbol Request Errored {p}"
>> Log.addContextDestructured "p" symbolRequest
@@ -2797,6 +2915,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override x.TextDocumentFormatting(p: DocumentFormattingParams) =
asyncResult {
+ let tags = [ "DocumentFormattingParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
let doc = p.TextDocument
let fileName = doc.GetFilePath() |> Utils.normalizePath
@@ -2823,6 +2944,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return! x.HandleFormatting(fileName, action, handlerFormattedDoc, (fun (_, _, _) -> [||]))
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "TextDocumentFormatting Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -2834,6 +2957,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override x.TextDocumentRangeFormatting(p: DocumentRangeFormattingParams) =
asyncResult {
+ let tags = [ "DocumentRangeFormattingParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
let doc = p.TextDocument
let fileName = doc.GetFilePath() |> Utils.normalizePath
@@ -2871,6 +2997,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return! x.HandleFormatting(fileName, action, (fun (_, _) -> [||]), handlerFormattedRangeDoc)
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "TextDocumentRangeFormatting Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -2883,6 +3011,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override x.TextDocumentCodeAction(codeActionParams: CodeActionParams) =
asyncResult {
+ let tags = [ "CodeActionParams", box codeActionParams ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "TextDocumentCodeAction Request: {parms}"
@@ -2931,6 +3062,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
|> List.toArray
|> Some
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "TextDocumentCodeAction Request Errored {p}"
>> Log.addContextDestructured "p" codeActionParams
@@ -2942,6 +3075,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override __.TextDocumentCodeLens(p: CodeLensParams) =
asyncResult {
+ let tags = [ "CodeLensParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "TextDocumentCodeLens Request: {parms}"
@@ -2964,6 +3100,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return Some res
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "TextDocumentCodeLens Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -2973,7 +3111,7 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return! LspResult.internalError (string e)
}
- override __.CodeLensResolve(p) =
+ override __.CodeLensResolve(p: CodeLens) =
// JB:TODO see how to reuse existing code
logger.info (
Log.setMessage "CodeLensResolve Request: {parms}"
@@ -2982,6 +3120,10 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
let handler (f) (arg: CodeLens) : Async> =
asyncResult {
+
+ let tags = [ "CodeLens", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
let pos = protocolPosToPos arg.Range.Start
let data = arg.Data.Value.ToObject()
@@ -3027,6 +3169,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return codeLens
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "CodeLensResolve - Operation failed on {file}"
>> Log.addContextDestructured "file" filePath
@@ -3139,8 +3283,12 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
})
p
- override __.WorkspaceDidChangeWatchedFiles(p) =
+ override __.WorkspaceDidChangeWatchedFiles(p: DidChangeWatchedFilesParams) =
async {
+
+ let tags = [ "DidChangeWatchedFilesParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "WorkspaceDidChangeWatchedFiles Request: {parms}"
@@ -3154,6 +3302,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
())
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "WorkspaceDidChangeWatchedFiles Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -3163,6 +3313,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override __.WorkspaceDidChangeConfiguration(p: DidChangeConfigurationParams) =
async {
+ let tags = [ "DidChangeConfigurationParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "WorkspaceDidChangeConfiguration Request: {parms}"
@@ -3175,6 +3328,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
updateConfig c
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "WorkspaceDidChangeConfiguration Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -3184,6 +3339,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override __.TextDocumentFoldingRange(rangeP: FoldingRangeParams) =
asyncResult {
+ let tags = [ "FoldingRangeParams", box rangeP ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "TextDocumentFoldingRange Request: {parms}"
@@ -3202,6 +3360,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
let! scopes = Commands.scopesForFile getParseResultsForFile file |> AsyncResult.ofStringErr
return scopes |> Seq.map Structure.toFoldingRange |> Set.ofSeq |> List.ofSeq |> Some
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "TextDocumentFoldingRange Request Errored {p}"
>> Log.addContextDestructured "p" rangeP
@@ -3213,6 +3373,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override __.TextDocumentSelectionRange(selectionRangeP: SelectionRangeParams) =
asyncResult {
+ let tags = [ "SelectionRangeParams", box selectionRangeP ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "TextDocumentSelectionRange Request: {parms}"
@@ -3243,6 +3406,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return ranges |> List.choose mkSelectionRanges |> Some
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "TextDocumentSelectionRange Request Errored {p}"
>> Log.addContextDestructured "p" selectionRangeP
@@ -3254,6 +3419,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override x.TextDocumentSemanticTokensFull(p: SemanticTokensParams) : AsyncLspResult =
asyncResult {
+ let tags = [ "SemanticTokensParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "TextDocumentSemanticTokensFull request: {parms}"
@@ -3264,6 +3432,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return! x.handleSemanticTokens fn None
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "TextDocumentSemanticTokensFull Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -3277,6 +3447,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override x.TextDocumentSemanticTokensRange(p: SemanticTokensRangeParams) : AsyncLspResult =
asyncResult {
+ let tags = [ "SemanticTokensRangeParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "TextDocumentSemanticTokensRange request: {parms}"
@@ -3287,6 +3460,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
let fcsRange = protocolRangeToRange (UMX.untag fn) p.Range
return! x.handleSemanticTokens fn (Some fcsRange)
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "TextDocumentSemanticTokensRange Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -3298,6 +3473,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override x.TextDocumentInlayHint(p: InlayHintParams) : AsyncLspResult =
asyncResult {
+ let tags = [ "InlayHintParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "TextDocumentInlayHint Request: {parms}"
@@ -3387,6 +3565,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return (Some hints)
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "TextDocumentInlayHint Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -3396,8 +3576,11 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return! LspResult.internalError (string e)
}
- override x.TextDocumentInlineValue(p) =
+ override x.TextDocumentInlineValue(p: InlineValueParams) =
asyncResult {
+ let tags = [ "InlineValueParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "TextDocumentInlineValue Request: {parms}"
@@ -3424,6 +3607,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return hints
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "TextDocumentInlineValue Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -3604,6 +3789,10 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override x.FSharpSignature(p: TextDocumentPositionParams) =
asyncResult {
+
+ let tags = [ "TextDocumentPositionParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "FSharpSignature Request: {parms}"
@@ -3619,6 +3808,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return { Content = CommandResponse.typeSig FsAutoComplete.JsonSerializer.writeJson tip }
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "FSharpSignature Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -3630,6 +3821,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override x.FSharpSignatureData(p: TextDocumentPositionParams) =
asyncResult {
+ let tags = [ "TextDocumentPositionParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "FSharpSignatureData Request: {parms}"
@@ -3650,6 +3844,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
{ Content = CommandResponse.signatureData FsAutoComplete.JsonSerializer.writeJson (typ, parms, generics) }
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "FSharpSignatureData Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -3662,6 +3858,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override x.FSharpDocumentationGenerator(p: OptionallyVersionedTextDocumentPositionParams) =
asyncResult {
+ let tags = [ "OptionallyVersionedTextDocumentPositionParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "FSharpDocumentationGenerator Request: {parms}"
@@ -3694,6 +3893,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return ()
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "FSharpDocumentationGenerator Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -3703,8 +3904,11 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return! LspResult.internalError (string e)
}
- override __.FSharpLineLense(p) =
+ override __.FSharpLineLense(p: ProjectParms) =
asyncResult {
+ let tags = [ "ProjectParms", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "FSharpLineLense Request: {parms}"
@@ -3721,6 +3925,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return { Content = CommandResponse.declarations FsAutoComplete.JsonSerializer.writeJson decls }
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "FSharpLineLense Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -3730,8 +3936,10 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return! LspResult.internalError (string e)
}
- override __.FSharpCompilerLocation(p) =
+ override __.FSharpCompilerLocation(p: obj) =
asyncResult {
+ use trace = fsacActivitySource.StartActivityForType(thisType)
+
try
logger.info (
Log.setMessage "FSharpCompilerLocation Request: {parms}"
@@ -3750,6 +3958,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
msbuild
(sdk |> Option.map (fun (di: DirectoryInfo) -> di.FullName)) }
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "FSharpCompilerLocation Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -3761,6 +3971,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override __.FSharpWorkspaceLoad(p: WorkspaceLoadParms) =
asyncResult {
+ let tags = [ "WorkspaceLoadParms", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "FSharpWorkspaceLoad Request: {parms}"
@@ -3778,6 +3991,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return { Content = CommandResponse.workspaceLoad FsAutoComplete.JsonSerializer.writeJson true }
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "FSharpWorkspaceLoad Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -3791,6 +4006,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override __.FSharpWorkspacePeek(p: WorkspacePeekRequest) =
asyncResult {
+ let tags = [ "WorkspacePeekRequest", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "FSharpWorkspacePeek Request: {parms}"
@@ -3811,6 +4029,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return! res
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "FSharpWorkspacePeek Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -3820,8 +4040,11 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return! LspResult.internalError (string e)
}
- override __.FSharpProject(p) =
+ override __.FSharpProject(p: ProjectParms) =
asyncResult {
+ let tags = [ "ProjectParms", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "FSharpProject Request: {parms}"
@@ -3850,6 +4073,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return! Helpers.notImplemented
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "FSharpWorkspacePeek Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -3870,6 +4095,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override __.FSharpDotnetNewList(p: DotnetNewListRequest) =
asyncResult {
+ let tags = [ "DotnetNewListRequest", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "FSharpDotnetNewList Request: {parms}"
@@ -3879,6 +4107,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
let! funcs = Commands.DotnetNewList() |> AsyncResult.ofCoreResponse
return { Content = CommandResponse.dotnetnewlist FsAutoComplete.JsonSerializer.writeJson funcs }
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "FSharpDotnetNewList Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -3890,6 +4120,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override __.FSharpDotnetNewRun(p: DotnetNewRunRequest) =
asyncResult {
+ let tags = [ "DotnetNewRunRequest", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "FSharpDotnetNewRun Request: {parms}"
@@ -3902,6 +4135,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return { Content = "" }
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "FSharpDotnetNewRun Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -3913,6 +4148,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override __.FSharpDotnetAddProject(p: DotnetProjectRequest) =
asyncResult {
+ let tags = [ "DotnetProjectRequest", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "FSharpDotnetAddProject Request: {parms}"
@@ -3923,6 +4161,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
forceLoadProjects () |> ignore
return { Content = "" }
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "FSharpDotnetAddProject Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -3934,6 +4174,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override __.FSharpDotnetRemoveProject(p: DotnetProjectRequest) =
asyncResult {
+ let tags = [ "DotnetProjectRequest", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "FSharpDotnetRemoveProject Request: {parms}"
@@ -3944,6 +4187,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
forceLoadProjects () |> ignore
return { Content = "" }
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "FSharpDotnetRemoveProject Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -3955,6 +4200,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override __.FSharpDotnetSlnAdd(p: DotnetProjectRequest) =
asyncResult {
+ let tags = [ "DotnetProjectRequest", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "FSharpDotnetSlnAdd Request: {parms}"
@@ -3965,6 +4213,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
forceLoadProjects () |> ignore
return { Content = "" }
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "FSharpDotnetSlnAdd Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -3976,6 +4226,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override x.FSharpHelp(p: TextDocumentPositionParams) =
asyncResult {
+ let tags = [ "TextDocumentPositionParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "FSharpHelp Request: {parms}"
@@ -3989,6 +4242,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
let! t = Commands.Help tyRes pos lineStr |> Result.ofCoreResponse
return { Content = CommandResponse.help FsAutoComplete.JsonSerializer.writeJson t }
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "FSharpHelp Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -4000,6 +4255,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override x.FSharpDocumentation(p: TextDocumentPositionParams) =
asyncResult {
+ let tags = [ "TextDocumentPositionParams", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "FSharpDocumentation Request: {parms}"
@@ -4014,6 +4272,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
let! t = Commands.FormattedDocumentation tyRes pos lineStr |> Result.ofCoreResponse
return { Content = CommandResponse.formattedDocumentation FsAutoComplete.JsonSerializer.writeJson t }
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "FSharpDocumentation Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -4025,6 +4285,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override x.FSharpDocumentationSymbol(p: DocumentationForSymbolReuqest) =
asyncResult {
+ let tags = [ "DocumentationForSymbolReuqest", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "FSharpDocumentationSymbol Request: {parms}"
@@ -4055,6 +4318,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
xmldoc
(signature, footer, cn) }
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "FSharpDocumentationSymbol Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -4065,15 +4330,34 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
}
override __.LoadAnalyzers(path) =
- logger.info (
- Log.setMessage "LoadAnalyzers Request: {parms}"
- >> Log.addContextDestructured "parms" path
- )
+ async {
- Helpers.notImplemented
+ use trace = fsacActivitySource.StartActivityForType(thisType)
+
+ logger.info (
+ Log.setMessage "LoadAnalyzers Request: {parms}"
+ >> Log.addContextDestructured "parms" path
+ )
+
+ try
+ // since the analyzer state handling code is in `updateConfig`, re-trigger it here
+ transact
+ <| fun () ->
+ config.MarkOutdated()
+ updateConfig config.Value
+
+ return LspResult.success ()
+ with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+ Loggers.analyzers.error (Log.setMessage "Loading failed" >> Log.addExn e)
+ return LspResult.success ()
+ }
override x.FSharpPipelineHints(p: FSharpPipelineHintRequest) =
asyncResult {
+ let tags = [ "FSharpPipelineHintRequest", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "FSharpPipelineHints Request: {parms}"
@@ -4086,6 +4370,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return { Content = CommandResponse.pipelineHint FsAutoComplete.JsonSerializer.writeJson res }
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "FSharpPipelineHints Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -4097,6 +4383,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override __.FsProjMoveFileUp(p: DotnetFileRequest) =
asyncResult {
+ let tags = [ "DotnetFileRequest", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "FsProjMoveFileUp Request: {parms}"
@@ -4110,6 +4399,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
forceLoadProjects () |> ignore
return { Content = "" }
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "FsProjMoveFileUp Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -4122,6 +4413,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override __.FsProjMoveFileDown(p: DotnetFileRequest) =
asyncResult {
+ let tags = [ "DotnetFileRequest", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "FsProjMoveFileDown Request: {parms}"
@@ -4135,6 +4429,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
forceLoadProjects () |> ignore
return { Content = "" }
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "FsProjMoveFileDown Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -4147,6 +4443,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override __.FsProjAddFileAbove(p: DotnetFile2Request) =
asyncResult {
+ let tags = [ "DotnetFile2Request", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "FsProjAddFileAbove Request: {parms}"
@@ -4160,6 +4459,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
forceLoadProjects () |> ignore
return { Content = "" }
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "FsProjAddFileAbove Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -4171,6 +4472,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override __.FsProjAddFileBelow(p: DotnetFile2Request) =
asyncResult {
+ let tags = [ "DotnetFile2Request", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "FsProjAddFileBelow Request: {parms}"
@@ -4184,6 +4488,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
forceLoadProjects () |> ignore
return { Content = "" }
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "FsProjAddFileBelow Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -4196,6 +4502,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override __.FsProjAddFile(p: DotnetFileRequest) =
asyncResult {
+ let tags = [ "DotnetFileRequest", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "FsProjAddFile Request: {parms}"
@@ -4206,6 +4515,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
forceLoadProjects () |> ignore
return { Content = "" }
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "FsProjAddFile Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -4217,6 +4528,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override _.FsProjRemoveFile(p: DotnetFileRequest) =
asyncResult {
+ let tags = [ "DotnetFileRequest", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "FsProjRemoveFile Request: {parms}"
@@ -4231,6 +4545,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return { Content = "" }
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "FsProjRemoveFile Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -4242,6 +4558,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
override _.FsProjAddExistingFile(p: DotnetFileRequest) =
asyncResult {
+ let tags = [ "DotnetFileRequest", box p ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
try
logger.info (
Log.setMessage "FsProjAddExistingFile Request: {parms}"
@@ -4255,6 +4574,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
forceLoadProjects () |> ignore
return { Content = "" }
with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
logger.error (
Log.setMessage "FsProjAddExistingFile Request Errored {p}"
>> Log.addContextDestructured "p" p
@@ -4268,10 +4589,24 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
member this.WorkDoneProgessCancel(token: ProgressToken) : Async =
async {
- logger.info (
- Log.setMessage "WorkDoneProgessCancel Request: {parms}"
- >> Log.addContextDestructured "parms" token
- )
+
+ let tags = [ "ProgressToken", box token ]
+ use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
+
+ try
+ logger.info (
+ Log.setMessage "WorkDoneProgessCancel Request: {parms}"
+ >> Log.addContextDestructured "parms" token
+ )
+
+ with e ->
+ trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
+
+ logger.error (
+ Log.setMessage "WorkDoneProgessCancel Request Errored {p}"
+ >> Log.addContextDestructured "token" token
+ >> Log.addExn e
+ )
return ()
}
@@ -4294,7 +4629,9 @@ module AdaptiveFSharpLspServer =
None
| _ -> None
- { new JsonRpc(handler) with
+ let strategy = StreamJsonRpcTracingStrategy(Tracing.fsacActivitySource)
+
+ { new JsonRpc(handler, ActivityTracingStrategy = strategy) with
member this.IsFatalException(ex: Exception) =
match ex with
| HandleableException -> false
diff --git a/src/FsAutoComplete/LspServers/FSharpLspClient.fs b/src/FsAutoComplete/LspServers/FSharpLspClient.fs
index 919b28fd3..2bebff8bb 100644
--- a/src/FsAutoComplete/LspServers/FSharpLspClient.fs
+++ b/src/FsAutoComplete/LspServers/FSharpLspClient.fs
@@ -8,6 +8,7 @@ open Ionide.LanguageServerProtocol.Types
open FsAutoComplete.LspHelpers
open System
open System.Threading.Tasks
+open FsAutoComplete.Utils
type FSharpLspClient(sendServerNotification: ClientNotificationSender, sendServerRequest: ClientRequestSender) =
@@ -143,74 +144,157 @@ type ServerProgressReport(lspClient: FSharpLspClient, ?token: ProgressToken) =
open System.Diagnostics.Tracing
open System.Collections.Concurrent
+open System.Diagnostics
+open Ionide.ProjInfo.Logging
+
+
+/// listener for the the events generated from the fsc ActivitySource
+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 = traceNamespace |> Array.map strContains
+
+ let logger = LogProvider.getLoggerByName "Compiler"
-/// listener for the the events generated by the `FSharp.Compiler.FSharpCompilerEventSource`
-type ProgressListener(lspClient) =
- inherit EventListener()
let mutable isDisposed = false
- let tryDispose (d: #IDisposable) =
- try
- d.Dispose()
- with _ ->
- ()
-
- let mutable source = null
-
- let mutable inflightEvents = ConcurrentDictionary<_, ServerProgressReport>()
-
- member _.EnableEvents(eventSource, level, matchAnyKeyword) =
- ``base``.EnableEvents(eventSource, level, matchAnyKeyword)
-
- override x.OnEventSourceCreated newSource =
- lock x
- <| fun () ->
- if newSource.Name = "FSharpCompiler" then
- x.EnableEvents(newSource, EventLevel.LogAlways, EventKeywords.All)
- source <- newSource
-
- override x.OnEventWritten eventArgs =
-
- lock x
- <| fun () ->
- try
- if isDisposed then
- ()
- else
- let message =
- match eventArgs.EventId with
- | 5 ->
- let progressReport = new ServerProgressReport(lspClient)
- let message = eventArgs.Payload.[0] |> string
- let fileName = IO.Path.GetFileName message
-
- if inflightEvents.TryAdd(eventArgs.Task, progressReport) then
- progressReport.Begin($"Dependent Typecheck {fileName}", message = message)
- |> Async.Start
- | 6 ->
- let message = eventArgs.Payload.[0] |> string
-
- match inflightEvents.TryRemove(eventArgs.Task) with
- | true, report ->
- report.End($"Finished {message}") |> Async.Start
- tryDispose report
- ()
- | false, _ ->
-
- ()
- | other -> ()
-
- message
- with e ->
- ()
-
- member _.DisableEvents(source) = ``base``.DisableEvents(source)
-
- interface System.IDisposable with
- member this.Dispose() =
- lock this
- <| fun () ->
- if isNull source then () else this.DisableEvents(source)
- isDisposed <- true
- inflightEvents.Values |> Seq.iter (tryDispose)
- inflightEvents <- null
+ let inflightEvents =
+ ConcurrentDictionary<_, System.Diagnostics.Activity * ServerProgressReport>()
+
+ let isStopped (activity: Activity) =
+#if NET7_0_OR_GREATER
+ activity.IsStopped
+ ||
+#endif
+ // giving this 2 seconds to report something, otherwise assume it's a dead activity
+ ((DateTime.UtcNow - activity.StartTimeUtc) > TimeSpan.FromSeconds(2.)
+ && activity.Duration = TimeSpan.Zero)
+
+ let getTagItemSafe key (a: Activity) = a.GetTagItem key |> Option.ofObj
+
+ let getFileName =
+ getTagItemSafe Tracing.SemanticConventions.FCS.fileName
+ >> Option.map string
+ >> Option.map IO.Path.GetFileName
+ >> Option.defaultValue String.Empty
+
+ let getProject =
+ getTagItemSafe Tracing.SemanticConventions.FCS.project
+ >> Option.map string
+ >> Option.map IO.Path.GetFileName
+ >> Option.defaultValue String.Empty
+
+ let getUserOpName =
+ getTagItemSafe Tracing.SemanticConventions.FCS.userOpName
+ >> Option.map string
+ >> Option.defaultValue String.Empty
+
+ let mbp =
+ MailboxProcessor.Start(fun inbox ->
+ async {
+ while not isDisposed do
+ for (a, p) in inflightEvents.Values do
+ // We don't get always get a corresponding ActivityStopped for a given Activity event so this looks at anything that hasn't had a duration incresed at all
+ // We don't seem to get a corresponding ActivityStopped on cancelled typechecks.
+ if isStopped a then
+ do! p.End()
+ 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 message =
+ [ getFileName a; getProject a; getUserOpName a ]
+ |> List.filter (String.IsNullOrEmpty >> not)
+ |> String.join " - "
+
+ do! p.Report(message = message)
+
+ match! inbox.TryReceive(250) with
+ | None ->
+ // if we don't get an event in 250 ms just loop again so we can analyze inflightEvents
+ ()
+ | Some(action, activity: Activity, reply: AsyncReplyChannel) ->
+
+ match action with
+ | "start" ->
+ let fileName = getFileName activity
+ let userOpName = getUserOpName activity
+
+ logger.trace (
+ Log.setMessageI
+ $"Started : {activity.DisplayName:DisplayName} - {userOpName:UserOpName} - {fileName:fileName}"
+ )
+
+ if
+ activity.DisplayName |> isOneOf interestingActivities
+ && not (isStopped activity)
+ then
+ let progressReport = new ServerProgressReport(lspClient)
+
+ if inflightEvents.TryAdd(activity.Id, (activity, progressReport)) then
+
+ do! progressReport.Begin($"{activity.DisplayName}")
+
+ | "stop" ->
+ let fileName = getFileName activity
+ let userOpName = getUserOpName activity
+ let duration = activity.Duration.ToString()
+
+ logger.trace (
+ 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
+ | true, (old, progressReport) -> do! progressReport.End()
+ | _ -> ()
+
+ | _ -> ()
+
+ reply.Reply()
+ })
+
+
+ let shouldListenTo (act: ActivitySource) = act.Name = Tracing.fscServiceName
+
+ let activityStarted (act: Activity) =
+ mbp.PostAndReply(fun reply -> "start", act, reply)
+
+ let activityStopped (act: Activity) =
+ mbp.PostAndReply(fun reply -> "stop", act, reply)
+
+ let listener =
+ new ActivityListener(
+ ShouldListenTo = shouldListenTo,
+ Sample = (fun _ -> ActivitySamplingResult.AllDataAndRecorded),
+ ActivityStarted = activityStarted,
+ ActivityStopped = activityStopped
+ )
+
+ do ActivitySource.AddActivityListener listener
+
+ interface IDisposable with
+ member this.Dispose() : unit =
+ (this :> IAsyncDisposable).DisposeAsync().GetAwaiter().GetResult()
+
+ interface IAsyncDisposable with
+ member this.DisposeAsync() : ValueTask =
+ // was getting a compile error for the statemachine in CI to `task`
+ async {
+ if not isDisposed then
+ isDisposed <- true
+ dispose listener
+
+ for (a, p) in inflightEvents.Values do
+ do! (disposeAsync p).AsTask() |> Async.AwaitTask
+ inflightEvents.TryRemove(a.Id) |> ignore
+ }
+ |> Async.StartImmediateAsTask
+ |> ValueTask
diff --git a/src/FsAutoComplete/Parser.fs b/src/FsAutoComplete/Parser.fs
index 4739e4b38..655a3a466 100644
--- a/src/FsAutoComplete/Parser.fs
+++ b/src/FsAutoComplete/Parser.fs
@@ -12,9 +12,17 @@ open Serilog.Filters
open System.Runtime.InteropServices
open System.Threading.Tasks
open FsAutoComplete.Lsp
+open OpenTelemetry
+open OpenTelemetry.Resources
+open OpenTelemetry.Trace
module Parser =
open FsAutoComplete.Core
+ open System.Diagnostics
+
+ let mutable tracerProvider = Unchecked.defaultof<_>
+
+
[]
type Pos = { Line: int; Column: int }
@@ -89,6 +97,12 @@ module Parser =
"Enable LSP Server based on FSharp.Data.Adaptive. Should be more stable, but is experimental."
)
+ let otelTracingOption =
+ Option(
+ "--otel-exporter-enabled",
+ "Enabled OpenTelemetry exporter. See https://opentelemetry.io/docs/reference/specification/protocol/exporter/ for environment variables to configure for the exporter."
+ )
+
let stateLocationOption =
Option(
"--state-directory",
@@ -109,6 +123,7 @@ module Parser =
rootCommand.AddOption adaptiveLspServerOption
rootCommand.AddOption logLevelOption
rootCommand.AddOption stateLocationOption
+ rootCommand.AddOption otelTracingOption
@@ -170,6 +185,27 @@ module Parser =
next.Invoke(ctx))
+ let configureOTel =
+ Invocation.InvocationMiddleware(fun ctx next ->
+
+ if ctx.ParseResult.GetValueForOption 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))
+
let configureLogging =
Invocation.InvocationMiddleware(fun ctx next ->
let isCategory (category: string) (e: LogEvent) =
@@ -275,4 +311,5 @@ module Parser =
.AddMiddleware(immediateAttach)
.AddMiddleware(serilogFlush)
.AddMiddleware(configureLogging)
+ .AddMiddleware(configureOTel)
.Build()
diff --git a/src/FsAutoComplete/paket.references b/src/FsAutoComplete/paket.references
index a5df50b03..5abb22b62 100644
--- a/src/FsAutoComplete/paket.references
+++ b/src/FsAutoComplete/paket.references
@@ -22,3 +22,4 @@ System.CommandLine
System.Configuration.ConfigurationManager
FSharp.Data.Adaptive
Microsoft.Extensions.Caching.Memory
+OpenTelemetry.Exporter.OpenTelemetryProtocol
diff --git a/test/FsAutoComplete.Tests.Lsp/Helpers.fs b/test/FsAutoComplete.Tests.Lsp/Helpers.fs
index 62e5bbc99..e3d8e315a 100644
--- a/test/FsAutoComplete.Tests.Lsp/Helpers.fs
+++ b/test/FsAutoComplete.Tests.Lsp/Helpers.fs
@@ -269,6 +269,7 @@ let defaultConfigDto: FSharpConfigDto =
Some
{ Enabled = Some true
Prefix = Some "//" }
+ Notifications = None
Debug = None }
let clientCaps: ClientCapabilities =