Skip to content
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

Аппендер вывода логов в LanguageClient, если он подключен #3118

Merged
merged 7 commits into from
Jul 28, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import com.github._1c_syntax.bsl.languageserver.cli.WebsocketCommand;
import com.github._1c_syntax.utils.CaseInsensitivePattern;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.ExitCodeGenerator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
Expand Down Expand Up @@ -71,7 +70,7 @@
havingValue = "true",
matchIfMissing = true)
@RequiredArgsConstructor
public class BSLLSPLauncher implements Callable<Integer>, CommandLineRunner, ExitCodeGenerator {
public class BSLLSPLauncher implements Callable<Integer>, ExitCodeGenerator {

private static final String DEFAULT_COMMAND = "lsp";

Expand Down Expand Up @@ -106,15 +105,17 @@ public static void main(String[] args) {
var applicationContext = new SpringApplicationBuilder(BSLLSPLauncher.class)
.web(getWebApplicationType(args))
.run(args);

var launcher = applicationContext.getBean(BSLLSPLauncher.class);
launcher.run(args);

if (launcher.getExitCode() >= 0) {
System.exit(
SpringApplication.exit(applicationContext)
);
}
}

@Override
public void run(String... args) {
var cmd = new CommandLine(this, picocliFactory);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,7 @@ private List<Diagnostic> internalCompute(DocumentContext documentContext) {
try {
return diagnostic.getDiagnostics(documentContext).stream();
} catch (RuntimeException e) {
/*
TODO:
В случае если подключен ленг клиент, то логирование ошибки в консоль приводит к падению сервера
т.к данный лог идёт в выхлоп не по протоколу.
Требуется обернуть логгер в случае подключенного ленг клиента и слать прокольное событие
которое запишет ошибку в лог.
*/
String message = String.format(
var message = String.format(
"Diagnostic computation error.%nFile: %s%nDiagnostic: %s",
documentContext.getUri(),
diagnostic.getInfo().getCode()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* This file is a part of BSL Language Server.
*
* Copyright (c) 2018-2023
* Alexey Sosnoviy <[email protected]>, Nikita Fedkin <[email protected]> and contributors
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*
* BSL Language Server is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* BSL Language Server is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with BSL Language Server.
*/
package com.github._1c_syntax.bsl.languageserver.infrastructure;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.ConsoleAppender;
import com.github._1c_syntax.bsl.languageserver.LanguageClientHolder;
import jakarta.annotation.Nullable;
import lombok.Setter;
import org.eclipse.lsp4j.MessageParams;
import org.eclipse.lsp4j.MessageType;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.util.Map;

/**
* Расширение штатного {@link ConsoleAppender}, выводящего сообщения
* в {@link org.eclipse.lsp4j.services.LanguageClient}, если он подключен,
* или в штатные потоки вывода в обратном случае.
*/
public class LanguageClientAwareAppender
extends ConsoleAppender<ILoggingEvent> {

/**
* Singletone-like хранилище проинициализированного инфраструктурой Logback аппендера
* для последующего возврата его через {@link LogbackConfiguration#languageClientAwareAppender()}.
*/
protected static LanguageClientAwareAppender INSTANCE;

private static final Map<Level, MessageType> loggingLevels = Map.of(
Level.TRACE, MessageType.Log,
Level.DEBUG, MessageType.Log,
Level.ERROR, MessageType.Error,
Level.INFO, MessageType.Info,
Level.WARN, MessageType.Warning
);

/**
* Хранилище возможно подключенного LanguageClient.
*/
@Nullable
@Setter(onMethod_ = {@Autowired})
private LanguageClientHolder clientHolder;

/**
* Конструктор по умолчанию.
* <p>
* Сохраняет сконструированный объект в переменную {@link LanguageClientAwareAppender#INSTANCE}.
*/
public LanguageClientAwareAppender() {
super();
// hacky hack
INSTANCE = this;
}

/**
* Общий метод вывода информации, проверяющий наличие подключенного LanguageClient.
*
* @param event Логируемое событие
* @throws IOException Выбрасывает исключение в случае ошибок записи в стандартные потоки вывода.
*/
@Override
protected void writeOut(ILoggingEvent event) throws IOException {
if (clientHolder != null && clientHolder.isConnected()) {
var languageClient = clientHolder.getClient().orElseThrow();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

фуфу. Говоришь что проверяешь наличие, а сам небезопасно Optional вскрываешь

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isConnected внутри проверяет наличие опшионала :)


var messageType = loggingLevels.getOrDefault(event.getLevel(), MessageType.Log);
String message = "[%s - %s] [%s] [%s]: %s".formatted(
event.getLevel(),
event.getInstant(),
event.getThreadName(),
event.getLoggerName(),
event.getFormattedMessage()
);
var params = new MessageParams(messageType, message);
languageClient.logMessage(params);

return;
}
super.writeOut(event);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* This file is a part of BSL Language Server.
*
* Copyright (c) 2018-2023
* Alexey Sosnoviy <[email protected]>, Nikita Fedkin <[email protected]> and contributors
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*
* BSL Language Server is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* BSL Language Server is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with BSL Language Server.
*/
package com.github._1c_syntax.bsl.languageserver.infrastructure;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* Spring-конфигурация для настройки logback.
*/
@Configuration
public class LogbackConfiguration {

/**
* @return Настроенный аппендер сообщений в LanguageClient.
*/
@Bean
public LanguageClientAwareAppender languageClientAwareAppender() {
return LanguageClientAwareAppender.INSTANCE;
}
}
12 changes: 12 additions & 0 deletions src/main/resources/language-client-aware-appender.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<included>
<appender name="LANGUAGE_CLIENT_AWARE" class="com.github._1c_syntax.bsl.languageserver.infrastructure.LanguageClientAwareAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>${CONSOLE_LOG_THRESHOLD}</level>
</filter>
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>${CONSOLE_LOG_CHARSET}</charset>
</encoder>
</appender>
</included>
8 changes: 8 additions & 0 deletions src/main/resources/logback-spring.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="language-client-aware-appender.xml" />
<root level="INFO">
<appender-ref ref="LANGUAGE_CLIENT_AWARE" />
</root>
</configuration>