Skip to content

Started logging #32

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,17 @@ deploy:
server: https://www.myget.org/F/omnisharp/api/v2/package
api_key:
secure: eoBrSWDtOXSxyUOoCSTyQCeDkvU18W67pE3w26viEUBRi1K4Tru0cTjUtDUB7l9V
skip_symbols: true
skip_symbols: false
symbol_server: https://www.myget.org/F/omnisharp/symbols/api/v2/package
artifact: /.*\.nupkg/
on:
branch: master
- provider: NuGet
server: https://www.myget.org/F/omnisharp/api/v2/package
api_key:
secure: eoBrSWDtOXSxyUOoCSTyQCeDkvU18W67pE3w26viEUBRi1K4Tru0cTjUtDUB7l9V
skip_symbols: true
skip_symbols: false
symbol_server: https://www.myget.org/F/omnisharp/symbols/api/v2/package
artifact: /.*\.nupkg/
on:
appveyor_repo_tag: true
Expand Down
1 change: 1 addition & 0 deletions build.cake
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ Task("Pack")
DotNetCorePack(project.FullPath, new DotNetCorePackSettings
{
NoBuild = true,
IncludeSymbols = true,
Configuration = configuration,
EnvironmentVariables = GitVersionEnvironmentVariables,
OutputDirectory = artifacts + "/nuget"
Expand Down
3 changes: 2 additions & 1 deletion sample/SampleServer/Program.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using OmniSharp.Extensions.LanguageServer;
using OmniSharp.Extensions.LanguageServer.Abstractions;
using OmniSharp.Extensions.LanguageServer.Capabilities.Client;
Expand All @@ -25,7 +26,7 @@ static async Task MainAsync(string[] args)
// await Task.Delay(100);
//}

var server = new LanguageServer(Console.OpenStandardInput(), Console.OpenStandardOutput());
var server = new LanguageServer(Console.OpenStandardInput(), Console.OpenStandardOutput(), new LoggerFactory());

server.AddHandler(new TextDocumentHandler(server));

Expand Down
3 changes: 2 additions & 1 deletion sample/SampleServer/SampleServer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

<ItemGroup>
<ProjectReference Include="../../src/Lsp/Lsp.csproj" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
</ItemGroup>

</Project>
</Project>
7 changes: 5 additions & 2 deletions src/JsonRpc/Connection.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.IO;
using Microsoft.Extensions.Logging;

namespace OmniSharp.Extensions.JsonRpc
{
Expand All @@ -14,7 +15,8 @@ public Connection(
IReciever reciever,
IRequestProcessIdentifier requestProcessIdentifier,
IRequestRouter requestRouter,
IResponseRouter responseRouter)
IResponseRouter responseRouter,
ILoggerFactory loggerFactory)
{
_requestRouter = requestRouter;

Expand All @@ -24,7 +26,8 @@ public Connection(
reciever,
requestProcessIdentifier,
requestRouter,
responseRouter
responseRouter,
loggerFactory
);
}

Expand Down
4 changes: 2 additions & 2 deletions src/JsonRpc/IScheduler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ namespace OmniSharp.Extensions.JsonRpc
public interface IScheduler : IDisposable
{
void Start();
void Add(RequestProcessType type, Func<Task> request);
void Add(RequestProcessType type, string name, Func<Task> request);
}
}
}
11 changes: 8 additions & 3 deletions src/JsonRpc/InputHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using Microsoft.Extensions.Logging;
using OmniSharp.Extensions.JsonRpc.Server.Messages;

namespace OmniSharp.Extensions.JsonRpc
Expand All @@ -23,6 +24,7 @@ public class InputHandler : IInputHandler
private Thread _inputThread;
private readonly IRequestRouter _requestRouter;
private readonly IResponseRouter _responseRouter;
private readonly ILogger<InputHandler> _logger;
private readonly IScheduler _scheduler;

public InputHandler(
Expand All @@ -31,7 +33,8 @@ public InputHandler(
IReciever reciever,
IRequestProcessIdentifier requestProcessIdentifier,
IRequestRouter requestRouter,
IResponseRouter responseRouter
IResponseRouter responseRouter,
ILoggerFactory loggerFactory
)
{
if (!input.CanRead) throw new ArgumentException($"must provide a readable stream for {nameof(input)}", nameof(input));
Expand All @@ -41,8 +44,8 @@ IResponseRouter responseRouter
_requestProcessIdentifier = requestProcessIdentifier;
_requestRouter = requestRouter;
_responseRouter = responseRouter;

_scheduler = new ProcessScheduler();
_logger = loggerFactory.CreateLogger<InputHandler>();
_scheduler = new ProcessScheduler(loggerFactory);
_inputThread = new Thread(ProcessInputStream) { IsBackground = true, Name = "ProcessInputStream" };
}

Expand Down Expand Up @@ -163,6 +166,7 @@ private void HandleRequest(string request)
{
_scheduler.Add(
type,
item.Request.Method,
async () => {
var result = await _requestRouter.RouteRequest(item.Request);
_outputHandler.Send(result.Value);
Expand All @@ -173,6 +177,7 @@ private void HandleRequest(string request)
{
_scheduler.Add(
type,
item.Notification.Method,
() => {
_requestRouter.RouteNotification(item.Notification);
return Task.CompletedTask;
Expand Down
1 change: 1 addition & 0 deletions src/JsonRpc/JsonRpc.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="System.ValueTuple" Version="4.4.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="1.0.2" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.6' ">
<PackageReference Include="System.Diagnostics.Process" Version="4.3.0" />
Expand Down
52 changes: 36 additions & 16 deletions src/JsonRpc/ProcessScheduler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,21 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;

namespace OmniSharp.Extensions.JsonRpc
{
public class ProcessScheduler : IScheduler
{
private readonly BlockingCollection<(RequestProcessType type, Func<Task> request)> _queue;
private readonly ILogger<ProcessScheduler> _logger;
private readonly BlockingCollection<(RequestProcessType type, string name, Func<Task> request)> _queue;
private readonly CancellationTokenSource _cancel;
private readonly Thread _thread;

public ProcessScheduler()
public ProcessScheduler(ILoggerFactory loggerFactory)
{
_queue = new BlockingCollection<(RequestProcessType type, Func<Task> request)>();
_logger = loggerFactory.CreateLogger<ProcessScheduler>();
_queue = new BlockingCollection<(RequestProcessType type, string name, Func<Task> request)>();
_cancel = new CancellationTokenSource();
_thread = new Thread(ProcessRequestQueue) { IsBackground = true, Name = "ProcessRequestQueue" };
}
Expand All @@ -24,9 +27,9 @@ public void Start()
_thread.Start();
}

public void Add(RequestProcessType type, Func<Task> request)
public void Add(RequestProcessType type, string name, Func<Task> request)
{
_queue.Add((type, request));
_queue.Add((type, name, request));
}

private Task Start(Func<Task> request)
Expand All @@ -42,7 +45,7 @@ private List<Task> RemoveCompleteTasks(List<Task> list)
if (list.Count == 0) return list;

var result = new List<Task>();
foreach(var t in list)
foreach (var t in list)
{
if (t.IsFaulted)
{
Expand All @@ -69,20 +72,32 @@ private void ProcessRequestQueue()
{
if (_queue.TryTake(out var item, Timeout.Infinite, token))
{
var (type, request) = item;
if (type == RequestProcessType.Serial)
var (type, name, request) = item;
try
{
Task.WaitAll(waitables.ToArray(), token);
Start(request).Wait(token);
if (type == RequestProcessType.Serial)
{
Task.WaitAll(waitables.ToArray(), token);
Start(request).Wait(token);
}
else if (type == RequestProcessType.Parallel)
{
waitables.Add(Start(request));
}
else
throw new NotImplementedException("Only Serial and Parallel execution types can be handled currently");
waitables = RemoveCompleteTasks(waitables);
Interlocked.Exchange(ref _TestOnly_NonCompleteTaskCount, waitables.Count);
}
else if (type == RequestProcessType.Parallel)
catch (OperationCanceledException ex) when (ex.CancellationToken == token)
{
waitables.Add(Start(request));
throw;
}
catch (Exception e)
{
// TODO: Create proper event ids
_logger.LogCritical(Events.UnhandledRequest, e, "Unhandled exception executing request {Name}", name);
}
else
throw new NotImplementedException("Only Serial and Parallel execution types can be handled currently");
waitables = RemoveCompleteTasks(waitables);
Interlocked.Exchange(ref _TestOnly_NonCompleteTaskCount, waitables.Count);
}
}
}
Expand Down Expand Up @@ -112,4 +127,9 @@ public void Dispose()
_cancel.Dispose();
}
}

static class Events
{
public static EventId UnhandledRequest = new EventId(1337_100);
}
}
5 changes: 4 additions & 1 deletion src/Lsp/ILanguageServer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using OmniSharp.Extensions.JsonRpc;
using OmniSharp.Extensions.LanguageServer.Models;

Expand All @@ -7,8 +8,10 @@ namespace OmniSharp.Extensions.LanguageServer
public interface ILanguageServer : IResponseRouter
{
IDisposable AddHandler(IJsonRpcHandler handler);
IDisposable AddHandlers(IEnumerable<IJsonRpcHandler> handlers);
IDisposable AddHandlers(params IJsonRpcHandler[] handlers);

InitializeParams Client { get; }
InitializeResult Server { get; }
}
}
}
16 changes: 11 additions & 5 deletions src/Lsp/LanguageServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using OmniSharp.Extensions.LanguageServer.Handlers;
using OmniSharp.Extensions.LanguageServer.Models;
using OmniSharp.Extensions.LanguageServer.Protocol.Document;
using Microsoft.Extensions.Logging;

namespace OmniSharp.Extensions.LanguageServer
{
Expand All @@ -30,20 +31,25 @@ public class LanguageServer : ILanguageServer, IInitializeHandler, IInitializedH
private readonly HandlerCollection _collection = new HandlerCollection();
private readonly IResponseRouter _responseRouter;
private readonly LspReciever _reciever;
private readonly ILoggerFactory _loggerFactory;
private readonly TaskCompletionSource<InitializeResult> _initializeComplete = new TaskCompletionSource<InitializeResult>();
private readonly CompositeDisposable _disposable = new CompositeDisposable();

public LanguageServer(Stream input, Stream output)
: this(input, new OutputHandler(output), new LspReciever(), new RequestProcessIdentifier())
public LanguageServer(Stream input, Stream output, ILoggerFactory loggerFactory)
: this(input, new OutputHandler(output), new LspReciever(), new RequestProcessIdentifier(), loggerFactory)
{
}

internal LanguageServer(Stream input, IOutputHandler output, LspReciever reciever, IRequestProcessIdentifier requestProcessIdentifier)
internal LanguageServer(Stream input, IOutputHandler output, LspReciever reciever, IRequestProcessIdentifier requestProcessIdentifier, ILoggerFactory loggerFactory)
{
// TODO: This might not be the best
loggerFactory.AddProvider(new LanguageServerLoggerProvider(this));

_reciever = reciever;
_loggerFactory = loggerFactory;
_requestRouter = new LspRequestRouter(_collection);
_responseRouter = new ResponseRouter(output);
_connection = new Connection(input, output, reciever, requestProcessIdentifier, _requestRouter, _responseRouter);
_connection = new Connection(input, output, reciever, requestProcessIdentifier, _requestRouter, _responseRouter, loggerFactory);

_exitHandler = new ExitHandler(_shutdownHandler);

Expand All @@ -57,7 +63,7 @@ internal LanguageServer(Stream input, IOutputHandler output, LspReciever recieve

public IDisposable AddHandler(IJsonRpcHandler handler)
{
return AddHandler(handler);
return AddHandlers(handler);
}

public IDisposable AddHandlers(IEnumerable<IJsonRpcHandler> handlers)
Expand Down
64 changes: 64 additions & 0 deletions src/Lsp/LanguageServerLogger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System;
using OmniSharp.Extensions.LanguageServer.Models;
using Microsoft.Extensions.Logging;
using OmniSharp.Extensions.LanguageServer.Protocol;

namespace OmniSharp.Extensions.LanguageServer
{
class LanguageServerLogger : ILogger
{
private LanguageServer _languageServer;

public LanguageServerLogger(LanguageServer languageServer)
{
_languageServer = languageServer;
}

public IDisposable BeginScope<TState>(TState state)
{
// TODO
return new ImmutableDisposable();
}

public bool IsEnabled(LogLevel logLevel)
{
// TODO: setup as configuration somehwhere (from trace perhaps?)
return true;
}

public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
if (TryGetMessageType(logLevel, out var messageType))
{
_languageServer.Log(new LogMessageParams()
{
Type = messageType,
Message = formatter(state, exception)
});
}
}

private bool TryGetMessageType(LogLevel logLevel, out MessageType messageType)
{
switch (logLevel)
{
case LogLevel.Critical:
case LogLevel.Error:
messageType = MessageType.Error;
return true;
case LogLevel.Warning:
messageType = MessageType.Warning;
return true;
case LogLevel.Information:
messageType = MessageType.Info;
return true;
case LogLevel.Debug:
case LogLevel.Trace:
messageType = MessageType.Info;
return true;
}
messageType = MessageType.Log;
return false;
}
}
}
Loading