Skip to content

Commit

Permalink
CSharpLanguageServer.Program: add logging to ILspClient (not function…
Browse files Browse the repository at this point in the history
…al yet)
  • Loading branch information
razzmatazz committed Feb 20, 2024
1 parent 28b8437 commit ee32302
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 8 deletions.
20 changes: 14 additions & 6 deletions src/CSharpLanguageServer/Lsp/Server.fs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ module LspUtils =

open LspUtils

type CSharpLspServer(lspClient: CSharpLspClient, settings: ServerSettings) =
type CSharpLspServer(
lspClient: CSharpLspClient,
settings: ServerSettings,
lspClientLogEventSink: LspClientLogEventSink
) =

let logger = LogProvider.getLoggerByName "LSP"

Expand Down Expand Up @@ -148,14 +152,18 @@ type CSharpLspServer(lspClient: CSharpLspClient, settings: ServerSettings) =
override __.Dispose() = ()

override __.Initialize(p) =
lspClientLogEventSink.SetLspClient(Some lspClient)

let serverCapabilities = getServerCapabilities p
p |> withReadWriteScope (Initialization.handleInitialize setupTimer serverCapabilities)

override __.Initialized(p) =
p |> withReadWriteScope (Initialization.handleInitialized lspClient stateActor)
|> ignoreResult

override __.Shutdown() = ignoreNotification
override __.Shutdown() =
lspClientLogEventSink.SetLspClient(None)
() |> async.Return

override __.Exit() = ignoreNotification

Expand Down Expand Up @@ -363,12 +371,12 @@ module Server =
let private requestHandlings =
Map.union (defaultRequestHandlings ()) customRequestHandlings

let startCore settings =
let startCore settings lspClientLogEventSink =
use input = Console.OpenStandardInput()
use output = Console.OpenStandardOutput()

let serverCreator client =
new CSharpLspServer(client, settings) :> ICSharpLspServer
new CSharpLspServer(client, settings, lspClientLogEventSink) :> ICSharpLspServer

let clientCreator = CSharpLspClient

Expand All @@ -380,9 +388,9 @@ module Server =
serverCreator
createRpc

let start options =
let start options lspClientLogEventSink =
try
let result = startCore options
let result = startCore options lspClientLogEventSink
int result
with ex ->
logger.error (
Expand Down
6 changes: 5 additions & 1 deletion src/CSharpLanguageServer/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ open Serilog.Events
open CSharpLanguageServer.Types
open CSharpLanguageServer.Lsp
open CSharpLanguageServer.Logging
open CSharpLanguageServer.Util

[<EntryPoint>]
let entry args =
Expand All @@ -35,10 +36,13 @@ let entry args =
| "log" -> LogEventLevel.Verbose
| _ -> LogEventLevel.Information

let lspClientLogEventSink = LspClientLogEventSink(formatProvider = null)

let logConfig =
LoggerConfiguration()
.MinimumLevel.ControlledBy(LoggingLevelSwitch(logLevel))
.Enrich.FromLogContext()
.WriteTo.Sink(lspClientLogEventSink)
.WriteTo.Async(fun conf ->
conf.Console(
outputTemplate =
Expand All @@ -56,7 +60,7 @@ let entry args =
LogLevel = logLevelArg
}

Server.start settings
Server.start settings lspClientLogEventSink
with
| :? ArguParseException as ex ->
printfn "%s" ex.Message
Expand Down
39 changes: 38 additions & 1 deletion src/CSharpLanguageServer/Util.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@ module CSharpLanguageServer.Util
open System
open System.Runtime.InteropServices
open System.IO
open Microsoft.CodeAnalysis.Classification;

open Ionide.LanguageServerProtocol
open Ionide.LanguageServerProtocol.Types
open Microsoft.CodeAnalysis.Classification
open Serilog
open Serilog.Core
open Serilog.Sinks
open Serilog.Events
open Serilog.Configuration

let parseFileUri s: string =
Uri(s).LocalPath
Expand Down Expand Up @@ -121,3 +129,32 @@ let GetSemanticTokenModifierFlagFromClassification (classification: string) =

let curry f x y = f (x, y)
let uncurry f (x, y) = f x y


type LspClientLogEventSink(formatProvider: IFormatProvider) =
let mutable lspClientMaybe: ILspClient option = None

let mapLogEventLevel lel =
match lel with
| LogEventLevel.Verbose -> MessageType.Log
| LogEventLevel.Debug -> MessageType.Log
| LogEventLevel.Information -> MessageType.Info
| LogEventLevel.Warning -> MessageType.Warning
| LogEventLevel.Error -> MessageType.Error
| LogEventLevel.Fatal -> MessageType.Error
| _ -> MessageType.Info

member __.SetLspClient(newLspClient: ILspClient option) =
lspClientMaybe <- newLspClient

interface ILogEventSink with
member __.Emit(logEvent: LogEvent) =
match lspClientMaybe with
| Some lspClient ->
let messageParams: LogMessageParams =
{ Type = mapLogEventLevel logEvent.Level
Message = logEvent.RenderMessage(formatProvider) }

lspClient.WindowLogMessage(messageParams) |> Async.StartAsTask |> ignore

| None -> ()

0 comments on commit ee32302

Please sign in to comment.