diff --git a/CHANGELOG.md b/CHANGELOG.md
index b05ea793..efb9c158 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [Unreleased]
+* Rework logging to be based on Serilog
+ - PR by @tcx4c70 in https://github.com/razzmatazz/csharp-language-server/pull/134
* More refactoring by @tcx4c70
- PR by @tcx4c70 in https://github.com/razzmatazz/csharp-language-server/pull/102
* Change package management to CPM
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 3c0aa524..dc687824 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -35,5 +35,8 @@
+
+
+
diff --git a/src/CSharpLanguageServer/CSharpLanguageServer.fsproj b/src/CSharpLanguageServer/CSharpLanguageServer.fsproj
index 0aa60462..41950127 100644
--- a/src/CSharpLanguageServer/CSharpLanguageServer.fsproj
+++ b/src/CSharpLanguageServer/CSharpLanguageServer.fsproj
@@ -75,5 +75,8 @@
+
+
+
diff --git a/src/CSharpLanguageServer/Handlers/CodeAction.fs b/src/CSharpLanguageServer/Handlers/CodeAction.fs
index 64bee74f..33fe058b 100644
--- a/src/CSharpLanguageServer/Handlers/CodeAction.fs
+++ b/src/CSharpLanguageServer/Handlers/CodeAction.fs
@@ -12,9 +12,12 @@ open Microsoft.CodeAnalysis.Text
open CSharpLanguageServer
open CSharpLanguageServer.State
open CSharpLanguageServer.RoslynHelpers
+open CSharpLanguageServer.Logging
[]
module CodeAction =
+ let private logger = LogProvider.getLoggerByName "CodeAction"
+
type CSharpCodeActionResolutionData = {
TextDocumentUri: string
Range: Range
diff --git a/src/CSharpLanguageServer/Handlers/Rename.fs b/src/CSharpLanguageServer/Handlers/Rename.fs
index 334a884c..670579e1 100644
--- a/src/CSharpLanguageServer/Handlers/Rename.fs
+++ b/src/CSharpLanguageServer/Handlers/Rename.fs
@@ -21,9 +21,12 @@ open Microsoft.CodeAnalysis.Classification
open CSharpLanguageServer
open CSharpLanguageServer.State
open CSharpLanguageServer.RoslynHelpers
+open CSharpLanguageServer.Logging
[]
module Rename =
+ let private logger = LogProvider.getLoggerByName "CodeAction"
+
let provider (clientCapabilities: ClientCapabilities option) : U2 option =
let clientSupportsRenameOptions =
clientCapabilities
diff --git a/src/CSharpLanguageServer/Program.fs b/src/CSharpLanguageServer/Program.fs
index 384c7a53..fa730479 100644
--- a/src/CSharpLanguageServer/Program.fs
+++ b/src/CSharpLanguageServer/Program.fs
@@ -1,9 +1,15 @@
module CSharpLanguageServer.Program
open Argu
+open System
open System.Reflection
open CSharpLanguageServer.Types
open CSharpLanguageServer.Lsp
+open Serilog
+open Serilog.Core
+open Serilog.Events
+
+open CSharpLanguageServer.Logging
[]
let entry args =
@@ -16,20 +22,37 @@ let entry args =
(Assembly.GetExecutingAssembly().GetName().Version |> string)
exit 0)
- let parseLogLevel (s: string) =
- match s.ToLowerInvariant() with
- | "error" -> Ionide.LanguageServerProtocol.Types.MessageType.Error
- | "warning" -> Ionide.LanguageServerProtocol.Types.MessageType.Warning
- | "info" -> Ionide.LanguageServerProtocol.Types.MessageType.Info
- | "log" -> Ionide.LanguageServerProtocol.Types.MessageType.Log
- | _ -> Ionide.LanguageServerProtocol.Types.MessageType.Log
+ let logLevelArg =
+ serverArgs.TryGetResult(<@ Options.CLIArguments.LogLevel @>)
+ |> Option.defaultValue "log"
+
+ let logLevel =
+ match logLevelArg with
+ | "error" -> LogEventLevel.Error
+ | "warning" -> LogEventLevel.Warning
+ | "info" -> LogEventLevel.Information
+ | "log" -> LogEventLevel.Verbose
+ | _ -> LogEventLevel.Information
+
+ let logConfig =
+ LoggerConfiguration()
+ .MinimumLevel.ControlledBy(LoggingLevelSwitch(logLevel))
+ .Enrich.FromLogContext()
+ .WriteTo.Async(fun conf ->
+ conf.Console(
+ outputTemplate =
+ "[{Timestamp:HH:mm:ss.fff} {Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}",
+ // Redirect all logs to stderr since stdout is used to communicate with client.
+ standardErrorFromLevel = Nullable<_>(LogEventLevel.Verbose),
+ theme = Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme.Code
+ )
+ |> ignore)
+
+ Log.Logger <- logConfig.CreateLogger()
- // default the verbosity to warning
let settings: ServerSettings = {
SolutionPath = serverArgs.TryGetResult(<@ Options.CLIArguments.Solution @>)
- LogLevel = serverArgs.TryGetResult(<@ Options.CLIArguments.LogLevel @>)
- |> Option.defaultValue "log"
- |> parseLogLevel
+ LogLevel = logLevelArg
}
Server.start CSharpLanguageServer.Server.setupServerHandlers
diff --git a/src/CSharpLanguageServer/Server.fs b/src/CSharpLanguageServer/Server.fs
index 59a53c31..92827456 100644
--- a/src/CSharpLanguageServer/Server.fs
+++ b/src/CSharpLanguageServer/Server.fs
@@ -25,6 +25,7 @@ open Ionide.LanguageServerProtocol.Server
open Ionide.LanguageServerProtocol.Types
open CSharpLanguageServer
+open CSharpLanguageServer.Logging
open CSharpLanguageServer.RoslynHelpers
open CSharpLanguageServer.State
open CSharpLanguageServer.Lsp
@@ -50,6 +51,8 @@ let getDotnetCliVersion () : string =
"(could not launch `dotnet --version`)"
let setupServerHandlers settings (lspClient: LspClient) =
+ let logger = LogProvider.getLoggerByName "Server"
+
let success = LspResult.success
let mutable logMessageCurrent: AsyncLogFn = fun _ -> async { return() }
let logMessageInvoke m = logMessageCurrent(m)
@@ -101,13 +104,18 @@ let setupServerHandlers settings (lspClient: LspClient) =
do stateActor.Post(PeriodicTimerTick)),
null, dueTime=1000, period=250))
- let logMessageWithLevel l message = async {
- let messageParams = { Type = l ; Message = "csharp-ls: " + message }
+ // TODO: setup Serilog Sink instead
+ let logMessage message = async {
+ let messageParams = { Type = MessageType.Log ; Message = "csharp-ls: " + message }
do! lspClient.WindowShowMessage messageParams
+ logger.trace (Log.setMessage message)
}
- let logMessage = logMessageWithLevel MessageType.Log
- let infoMessage = logMessageWithLevel MessageType.Info
+ let infoMessage message = async {
+ let messageParams = { Type = MessageType.Info ; Message = "csharp-ls: " + message }
+ do! lspClient.WindowShowMessage messageParams
+ logger.info (Log.setMessage message)
+ }
let handleInitialize (scope: ServerRequestScope) (p: InitializeParams): AsyncLspResult = async {
do! infoMessage (sprintf "initializing, csharp-ls version %s; cwd: \"%s\""
diff --git a/src/CSharpLanguageServer/Types.fs b/src/CSharpLanguageServer/Types.fs
index a6288e50..dc42f741 100644
--- a/src/CSharpLanguageServer/Types.fs
+++ b/src/CSharpLanguageServer/Types.fs
@@ -5,11 +5,11 @@ open Ionide.LanguageServerProtocol.Types
type ServerSettings =
{ SolutionPath: string option
- LogLevel: MessageType }
+ LogLevel: string }
static member Default: ServerSettings =
{ SolutionPath = None
- LogLevel = MessageType.Log }
+ LogLevel = "log" }
type CSharpMetadataInformation =
{ ProjectName: string