From 52dc7f84251ad6840729937c7edb5720c5100c06 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Fri, 16 Feb 2024 10:29:16 -0600 Subject: [PATCH] quick hack to start the dashboard on Ionide startup if otel is requested --- src/Components/OTel.fs | 99 ++++++++++++++++++++++++++++++++++++++++ src/Ionide.FSharp.fsproj | 1 + src/fsharp.fs | 1 + 3 files changed, 101 insertions(+) create mode 100644 src/Components/OTel.fs diff --git a/src/Components/OTel.fs b/src/Components/OTel.fs new file mode 100644 index 00000000..06ce5b4d --- /dev/null +++ b/src/Components/OTel.fs @@ -0,0 +1,99 @@ +namespace Ionide.VSCode.FSharp + +module OTel = + open Fable.Import.VSCode.Vscode + open Node.Api + open Node.Base + + let private logger = + ConsoleAndOutputChannelLogger(Some "OTel", Level.DEBUG, None, Some Level.DEBUG) + + let private settingsString = "FSharp.openTelemetry" + let mutable private isOTelEnabled = false + + let mutable private hasDocker = false + + let mutable private runningContainerId: string = null + + type SpawnResult = + abstract pid: int + abstract output: string[][] + abstract stdout: string + abstract stderr: string + abstract status: int option + abstract signal: string option + abstract error: Error option + + let private runCommand command (args: string[]) = + let options = + {| cwd = None + env = None + encoding = "utf8" + shell = true |} + + let result = + childProcess.spawnSync (command, ResizeArray args, options) :?> SpawnResult + + match result.error with + | Some err -> + logger.Error("Error running command %s: %s", command, err.message) + failwithf "%A" err + | None -> result + + let private startContainer () = + let result = + runCommand + "docker" + [| "run" + "-d" + "--rm" + "-it" + "-p" + "18888:18888" + "-p" + "4317:18889" + "mcr.microsoft.com/dotnet/nightly/aspire-dashboard:8.0.0-preview.4" |] + + logger.Info("Container started with result %j", result) + runningContainerId <- result.stdout + isOTelEnabled <- true + + let enableOTelListener () = + isOTelEnabled <- true + + if hasDocker then + startContainer () + logger.Info("OpenTelemetry listener enabled") + () + else + logger.Warn("OpenTelemetry listener requires Docker to be installed") |> ignore + + () + + let stopContainer (containerId: string) = + runCommand "docker" [| "stop"; containerId |] |> ignore + + let disableOTelListener () = + isOTelEnabled <- false + + if hasDocker && not (System.String.IsNullOrEmpty runningContainerId) then + stopContainer runningContainerId |> ignore + logger.Info("OpenTelemetry listener disabled") + () + + let detectDocker () = + logger.Info("detecting presence of docker") + hasDocker <- true + + let activate (ctx: ExtensionContext) = + detectDocker () + + let settings = workspace.getConfiguration settingsString + let newEnablement = settings.get ("enabled") + + logger.Info("Configuration value is %j", newEnablement) + + match isOTelEnabled, newEnablement with + | true, (Some false | None) -> disableOTelListener () + | false, Some true -> enableOTelListener () + | _, _ -> () diff --git a/src/Ionide.FSharp.fsproj b/src/Ionide.FSharp.fsproj index 6389a4f4..f7f455a5 100644 --- a/src/Ionide.FSharp.fsproj +++ b/src/Ionide.FSharp.fsproj @@ -51,6 +51,7 @@ + diff --git a/src/fsharp.fs b/src/fsharp.fs index 1d01d7e0..0a89a3a5 100644 --- a/src/fsharp.fs +++ b/src/fsharp.fs @@ -107,6 +107,7 @@ let activate (context: ExtensionContext) : JS.Promise = tryActivate "testExplorer" TestExplorer.activate context tryActivate "inlayhints" InlayHints.activate context tryActivate "languageservice" activateLanguageServiceRestart context + tryActivate "otel" OTel.activate context let buildProject project = promise {