public async Task Handle(IClientWebSocket clientWebSocket, CancellationToken cancellationToken)
        {
            try
            {
                LogsStreamRequest streamRequest = await this.ReadLogsStreamingRequest(clientWebSocket, cancellationToken);

                Events.RequestData(streamRequest);

                if (ExpectedSchemaVersion.CompareMajorVersion(streamRequest.SchemaVersion, "logs stream request schema") != 0)
                {
                    Events.MismatchedMinorVersions(streamRequest.SchemaVersion, ExpectedSchemaVersion);
                }

                var socketCancellationTokenSource = new CancellationTokenSource();

                Task ProcessLogsFrame(ArraySegment <byte> bytes)
                {
                    if (clientWebSocket.State != WebSocketState.Open)
                    {
                        Events.WebSocketNotOpen(streamRequest, clientWebSocket.State);
                        socketCancellationTokenSource.Cancel();
                        return(Task.CompletedTask);
                    }
                    else
                    {
                        return(clientWebSocket.SendAsync(bytes, WebSocketMessageType.Binary, true, cancellationToken));
                    }
                }

                ILogsRequestToOptionsMapper requestToOptionsMapper = new LogsRequestToOptionsMapper(
                    this.runtimeInfoProvider,
                    streamRequest.Encoding,
                    streamRequest.ContentType,
                    LogOutputFraming.SimpleLength,
                    Option.None <LogsOutputGroupingConfig>(),
                    true);
                IList <(string id, ModuleLogOptions logOptions)> logOptionsList = await requestToOptionsMapper.MapToLogOptions(streamRequest.Items, cancellationToken);

                using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, socketCancellationTokenSource.Token))
                {
                    await this.logsProvider.GetLogsStream(logOptionsList, ProcessLogsFrame, linkedCts.Token);
                }

                Events.StreamingCompleted(streamRequest);
            }
            catch (Exception e)
            {
                Events.ErrorHandlingRequest(e);
            }
        }
        public async Task Handle(IClientWebSocket clientWebSocket, CancellationToken cancellationToken)
        {
            try
            {
                LogsStreamRequest streamRequest = await this.ReadLogsStreamingRequest(clientWebSocket, cancellationToken);

                Events.RequestData(streamRequest);

                var socketCancellationTokenSource = new CancellationTokenSource();

                Task ProcessLogsFrame(ArraySegment <byte> bytes)
                {
                    if (clientWebSocket.State != WebSocketState.Open)
                    {
                        Events.WebSocketNotOpen(streamRequest, clientWebSocket.State);
                        socketCancellationTokenSource.Cancel();
                        return(Task.CompletedTask);
                    }
                    else
                    {
                        return(clientWebSocket.SendAsync(bytes, WebSocketMessageType.Binary, true, cancellationToken));
                    }
                }

                IList <(string id, ModuleLogOptions logOptions)> logOptionsList = streamRequest.Items.Select(i => (i.Id, new ModuleLogOptions(streamRequest.Encoding, streamRequest.ContentType, i.Filter))).ToList();

                using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, socketCancellationTokenSource.Token))
                {
                    await this.logsProvider.GetLogsStream(logOptionsList, ProcessLogsFrame, linkedCts.Token);
                }

                Events.StreamingCompleted(streamRequest);
            }
            catch (Exception e)
            {
                Events.ErrorHandlingRequest(e);
            }
        }
 static string GetIds(LogsStreamRequest logStreamRequest) => logStreamRequest.Items.Select(i => i.Id).Join(",");
            public static void WebSocketNotOpen(LogsStreamRequest logStreamRequest, WebSocketState state)
            {
                string id = GetIds(logStreamRequest);

                Log.LogInformation((int)EventIds.WebSocketNotOpen, $"Terminating streaming logs for {id} because WebSocket state is {state}");
            }
            public static void StreamingCompleted(LogsStreamRequest logStreamRequest)
            {
                string id = GetIds(logStreamRequest);

                Log.LogInformation((int)EventIds.StreamingCompleted, $"Completed streaming logs for {id}");
            }
 public static void RequestData(LogsStreamRequest streamRequest)
 {
     Log.LogInformation((int)EventIds.RequestData, $"Logs streaming request data - {streamRequest.ToJson()}");
 }