Log Levels View
* fetch and display loglevels * change log levels for packages * clean up logs * address review comments * switch the CONNECT_TO_LS key * Avoid caching loggers data * add copyright headers --------- Co-authored-by: V Udayani <vudayani@vudayaniSMD6M.vmware.com>
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 Broadcom, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Broadcom, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.protocol;
|
||||
|
||||
public record LiveProcessLoggersSummary(String processType, String processKey, String processName, String processID,
|
||||
String packageName, String effectiveLevel, String configuredLevel) {
|
||||
|
||||
}
|
||||
@@ -51,6 +51,9 @@ public interface STS4LanguageClient extends LanguageClient, SpringIndexLanguageC
|
||||
|
||||
@JsonNotification("sts/liveprocess/gcpauses/metrics/updated")
|
||||
void liveProcessGcPausesMetricsDataUpdated(LiveProcessSummary processKey);
|
||||
|
||||
@JsonNotification("sts/liveprocess/loglevel/updated")
|
||||
void liveProcessLogLevelUpdated(LiveProcessLoggersSummary liveProcessLoggersSummary);
|
||||
|
||||
@JsonNotification("sts/highlight")
|
||||
void highlight(HighlightParams highlights);
|
||||
|
||||
@@ -114,6 +114,7 @@ import org.springframework.ide.vscode.commons.languageserver.util.Settings;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.protocol.CursorMovement;
|
||||
import org.springframework.ide.vscode.commons.protocol.HighlightParams;
|
||||
import org.springframework.ide.vscode.commons.protocol.LiveProcessLoggersSummary;
|
||||
import org.springframework.ide.vscode.commons.protocol.LiveProcessSummary;
|
||||
import org.springframework.ide.vscode.commons.protocol.STS4LanguageClient;
|
||||
import org.springframework.ide.vscode.commons.protocol.java.ClasspathListenerParams;
|
||||
@@ -437,6 +438,10 @@ public class LanguageServerHarness {
|
||||
receiveIndexUpdated();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void liveProcessLogLevelUpdated(LiveProcessLoggersSummary processKey) {
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@@ -33,4 +33,8 @@ public interface ActuatorConnection {
|
||||
Map<?, ?> getStartup() throws IOException;
|
||||
|
||||
String getLiveMetrics(String metricName, String tags) throws IOException;
|
||||
|
||||
String getLoggers() throws IOException;
|
||||
|
||||
String configureLogLevel(Map<String, String> args) throws IOException;
|
||||
}
|
||||
|
||||
@@ -80,6 +80,21 @@ public class HttpActuatorConnection implements ActuatorConnection {
|
||||
return restTemplate.getForObject("/beans", String.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLoggers() throws IOException {
|
||||
return restTemplate.getForObject("/loggers", String.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String configureLogLevel(Map<String, String> args) throws IOException {
|
||||
UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromPath("/loggers/"+args.get("packageName"));
|
||||
if (args != null) {
|
||||
uriBuilder.queryParam("configuredLevel", args.get("configuredLevel"));
|
||||
}
|
||||
String url = actuatorUrl + uriBuilder.toUriString();
|
||||
return restTemplate.postForObject(URI.create(url), null, String.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLiveMetrics(String metricName, String tags) throws IOException {
|
||||
UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromPath("/metrics/"+metricName);
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 Broadcom, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Broadcom, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.livehover.v2;
|
||||
|
||||
/**
|
||||
* @author Udayani V
|
||||
*/
|
||||
public class LoggerInfo {
|
||||
|
||||
private String configuredLevel;
|
||||
|
||||
private String effectiveLevel;
|
||||
|
||||
public String getConfiguredLevel() {
|
||||
return configuredLevel;
|
||||
}
|
||||
public String getEffectiveLevel() {
|
||||
return effectiveLevel;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 Broadcom, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Broadcom, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.livehover.v2;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
/**
|
||||
* @author Udayani V
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class Loggers {
|
||||
|
||||
private List<String> levels;
|
||||
private Map<String, LoggerInfo> loggers;
|
||||
|
||||
public List<String> getLevels() {
|
||||
return levels;
|
||||
}
|
||||
|
||||
public Map<String, LoggerInfo> getLoggers() {
|
||||
return loggers;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,6 +12,7 @@ package org.springframework.ide.vscode.boot.java.livehover.v2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -43,6 +44,8 @@ public class SpringProcessCommandHandler {
|
||||
private static final String COMMAND_LIST_CONNECTED = "sts/livedata/listConnected";
|
||||
private static final String COMMAND_GET_METRICS = "sts/livedata/get/metrics";
|
||||
private static final String COMMAND_GET_REFRESH_METRICS = "sts/livedata/refresh/metrics";
|
||||
private static final String COMMAND_GET_LOGGERS = "sts/livedata/getLoggers";
|
||||
private static final String COMMAND_CONFIGURE_LOGLEVEL = "sts/livedata/configure/logLevel";
|
||||
|
||||
private final SpringProcessConnectorService connectorService;
|
||||
private final SpringProcessConnectorLocal localProcessConnector;
|
||||
@@ -88,6 +91,16 @@ public class SpringProcessCommandHandler {
|
||||
return refreshMetrics(params);
|
||||
});
|
||||
log.info("Registered command handler: {}",COMMAND_GET_METRICS);
|
||||
|
||||
server.onCommand(COMMAND_GET_LOGGERS, (params) -> {
|
||||
return getLoggers(params);
|
||||
});
|
||||
log.info("Registered command handler: {}",COMMAND_GET_LOGGERS);
|
||||
|
||||
server.onCommand(COMMAND_CONFIGURE_LOGLEVEL, (params) -> {
|
||||
return configureLogLevel(params);
|
||||
});
|
||||
log.info("Registered command handler: {}",COMMAND_CONFIGURE_LOGLEVEL);
|
||||
|
||||
server.onCommand(COMMAND_LIST_CONNECTED, (params) -> {
|
||||
List<LiveProcessSummary> result = new ArrayList<>();
|
||||
@@ -320,4 +333,34 @@ public class SpringProcessCommandHandler {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
|
||||
private CompletableFuture<Object> getLoggers(ExecuteCommandParams params) {
|
||||
SpringProcessLoggersData loggersData = null;
|
||||
SpringProcessParams springProcessParams = new SpringProcessParams();
|
||||
springProcessParams.setProcessKey(getProcessKey(params));
|
||||
springProcessParams.setEndpoint(getArgumentByKey(params, "endpoint"));
|
||||
if (springProcessParams.getProcessKey() != null) {
|
||||
loggersData = connectorService.getLoggers(springProcessParams);
|
||||
return CompletableFuture.completedFuture(loggersData);
|
||||
}
|
||||
|
||||
return CompletableFuture.completedFuture(loggersData);
|
||||
}
|
||||
|
||||
private CompletableFuture<Object> configureLogLevel(ExecuteCommandParams params) {
|
||||
Map<String, String> args = new HashMap<>();
|
||||
args.put("packageName", getArgumentByKey(params, "packageName"));
|
||||
args.put("configuredLevel", getArgumentByKey(params, "configuredLevel"));
|
||||
args.put("effectiveLevel", getArgumentByKey(params, "effectiveLevel"));
|
||||
SpringProcessParams springProcessParams = new SpringProcessParams();
|
||||
springProcessParams.setProcessKey(getProcessKey(params));
|
||||
springProcessParams.setArgs(args);
|
||||
|
||||
if (springProcessParams.getProcessKey() != null) {
|
||||
connectorService.configureLogLevel(springProcessParams);
|
||||
}
|
||||
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.livehover.v2;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
@@ -29,4 +31,6 @@ public interface SpringProcessConnector {
|
||||
String getProcessName();
|
||||
SpringProcessGcPausesMetricsLiveData refreshGcPausesMetrics(SpringProcessLiveData current, String metricName, String tags) throws Exception;
|
||||
SpringProcessMemoryMetricsLiveData refreshMemoryMetrics(SpringProcessLiveData current, String metricName, String tags) throws Exception;
|
||||
SpringProcessLoggersData getLoggers(SpringProcessLiveData currentData) throws Exception;
|
||||
SpringProcessUpdatedLogLevelData configureLogLevel(SpringProcessLiveData currentData, Map<String, String> args) throws Exception;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.livehover.v2;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class SpringProcessConnectorOverHttp implements SpringProcessConnector {
|
||||
|
||||
private final ProcessType processType;
|
||||
@@ -157,6 +159,49 @@ public class SpringProcessConnectorOverHttp implements SpringProcessConnector {
|
||||
|
||||
throw new Exception("no live memory metrics data received, lets try again");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SpringProcessLoggersData getLoggers(SpringProcessLiveData currentData)
|
||||
throws Exception {
|
||||
if (actuatorConnection != null) {
|
||||
SpringProcessLoggersData loggersData = new SpringProcessLiveDataExtractorOverHttp().retrieveLoggersData(getProcessType(), actuatorConnection, processID, processName, currentData);
|
||||
|
||||
if (this.processID == null) {
|
||||
this.processID = loggersData.getProcessID();
|
||||
}
|
||||
|
||||
if (this.processName == null) {
|
||||
this.processName = loggersData.getProcessName();
|
||||
}
|
||||
|
||||
if (loggersData != null && loggersData.getLoggers() != null) {
|
||||
return loggersData;
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception("no loggers data received, lets try again");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SpringProcessUpdatedLogLevelData configureLogLevel(SpringProcessLiveData currentData, Map<String, String> args) throws Exception {
|
||||
if (actuatorConnection != null) {
|
||||
SpringProcessUpdatedLogLevelData springProcessUpdatedLoggersData = new SpringProcessLiveDataExtractorOverHttp().configureLogLevel(getProcessType(), actuatorConnection, processID, processName, currentData, args);
|
||||
|
||||
if (this.processID == null) {
|
||||
this.processID = springProcessUpdatedLoggersData.getProcessID();
|
||||
}
|
||||
|
||||
if (this.processName == null) {
|
||||
this.processName = springProcessUpdatedLoggersData.getProcessName();
|
||||
return springProcessUpdatedLoggersData;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
throw new Exception("configure log levels failed, lets try again");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -210,6 +210,50 @@ public class SpringProcessConnectorOverJMX implements SpringProcessConnector {
|
||||
log.error("error closing the JMX connection for: " + jmxURL, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpringProcessLoggersData getLoggers(SpringProcessLiveData currentData) throws Exception {
|
||||
log.info("try to open JMX connection to: " + jmxURL);
|
||||
|
||||
if (jmxConnection != null) {
|
||||
try {
|
||||
SpringProcessLiveDataExtractorOverJMX springJMXConnector = new SpringProcessLiveDataExtractorOverJMX();
|
||||
|
||||
log.info("retrieve live data from: " + jmxURL);
|
||||
SpringProcessLoggersData loggersData = springJMXConnector.retrieveLoggersData(getProcessType(), jmxConnection, processID, processName, currentData);
|
||||
|
||||
if (loggersData != null) {
|
||||
return loggersData;
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("exception while connecting to jmx: " + jmxURL, e);
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception("no loggers data received, lets try again");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpringProcessUpdatedLogLevelData configureLogLevel(SpringProcessLiveData currentData, Map<String, String> args) throws Exception {
|
||||
log.info("try to open JMX connection to: " + jmxURL);
|
||||
|
||||
if (jmxConnection != null) {
|
||||
try {
|
||||
SpringProcessLiveDataExtractorOverJMX springJMXConnector = new SpringProcessLiveDataExtractorOverJMX();
|
||||
|
||||
log.info("retrieve live data from: " + jmxURL);
|
||||
SpringProcessUpdatedLogLevelData springProcessUpdatedLoggersData = springJMXConnector.configureLogLevel(getProcessType(), jmxConnection, processID, processName, currentData, args);
|
||||
|
||||
return springProcessUpdatedLoggersData;
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("exception while connecting to jmx: " + jmxURL, e);
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception("configure log level failed, lets try again");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addConnectorChangeListener(SpringProcessConnectionChangeListener listener) {
|
||||
|
||||
@@ -10,8 +10,10 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.livehover.v2;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -34,6 +36,7 @@ public class SpringProcessConnectorService {
|
||||
public static final String MEMORY = "memory";
|
||||
public static final String HEAP_MEMORY = "heapMemory";
|
||||
public static final String NON_HEAP_MEMORY = "nonHeapMemory";
|
||||
private static final String LOGGERS = "loggers";
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(SpringProcessConnectorService.class);
|
||||
|
||||
@@ -292,4 +295,129 @@ public class SpringProcessConnectorService {
|
||||
private IndefiniteProgressTask getProgressTask(String prefixId, String title, String message) {
|
||||
return this.progressService.createIndefiniteProgressTask(prefixId + progressIdKey++, title, message);
|
||||
}
|
||||
|
||||
public SpringProcessLoggersData getLoggers(SpringProcessParams springProcessParams) {
|
||||
log.info("get loggers data: " + springProcessParams.getProcessKey());
|
||||
CompletableFuture<SpringProcessLoggersData> loggerData = new CompletableFuture<>();
|
||||
SpringProcessConnector connector = this.connectors.get(springProcessParams.getProcessKey());
|
||||
if (connector != null) {
|
||||
final IndefiniteProgressTask progressTask = getProgressTask(
|
||||
"spring-process-connector-service-get-loggers-data" + springProcessParams.getProcessKey(), "Loggers", null);
|
||||
getLoggersData(progressTask, springProcessParams, connector, loggerData, 0, TimeUnit.SECONDS, 0);
|
||||
try {
|
||||
return loggerData.get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
log.error("Failed to fetch loggers data for the process "+ springProcessParams.getProcessKey());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void getLoggersData(IndefiniteProgressTask progressTask, SpringProcessParams springProcessParams, SpringProcessConnector connector, CompletableFuture<SpringProcessLoggersData> loggerData, long delay, TimeUnit unit, int retryNo) {
|
||||
String processKey = springProcessParams.getProcessKey();
|
||||
String endpoint = springProcessParams.getEndpoint();
|
||||
|
||||
String progressMessage = "Get loggers for Spring process: " + processKey + " - retry no: " + retryNo;
|
||||
log.info(progressMessage);
|
||||
|
||||
this.scheduler.schedule(() -> {
|
||||
|
||||
try {
|
||||
progressTask.progressEvent(progressMessage);
|
||||
if(LOGGERS.equals(endpoint)) {
|
||||
SpringProcessLoggersData loggersData = connector.getLoggers(this.liveDataProvider.getCurrent(processKey));
|
||||
|
||||
if (loggersData != null) {
|
||||
loggerData.complete(loggersData);
|
||||
this.connectedSuccess.put(processKey, true);
|
||||
}
|
||||
|
||||
}
|
||||
progressTask.done();
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
||||
log.info("problem occured during process live data refresh", e);
|
||||
|
||||
if (retryNo < maxRetryCount && isKnownProcessKey(processKey)) {
|
||||
getLoggersData(progressTask, springProcessParams, connector, loggerData, retryDelayInSeconds, TimeUnit.SECONDS,
|
||||
retryNo + 1);
|
||||
}
|
||||
else {
|
||||
progressTask.done();
|
||||
|
||||
// Send message to client if maximum retries reached on error
|
||||
if (isKnownProcessKey(processKey)) {
|
||||
diagnosticService.diagnosticEvent(ShowMessageException
|
||||
.error("Failed to refresh live data from process " + processKey + " after retries: " + retryNo, e));
|
||||
|
||||
if (!connectedSuccess.containsKey(connector.getProcessKey())) {
|
||||
loggerData.complete(null);
|
||||
disconnectProcess(processKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}, 0, TimeUnit.SECONDS);
|
||||
|
||||
}
|
||||
|
||||
public void configureLogLevel(SpringProcessParams springProcessParams) {
|
||||
log.info("change log level: " + springProcessParams.getProcessKey());
|
||||
|
||||
SpringProcessConnector connector = this.connectors.get(springProcessParams.getProcessKey());
|
||||
if (connector != null) {
|
||||
final IndefiniteProgressTask progressTask = getProgressTask(
|
||||
"spring-process-connector-service-configure-log-level" + springProcessParams.getProcessKey(), "Loggers", null);
|
||||
configureLogLevel(progressTask, springProcessParams, connector, 0, TimeUnit.SECONDS, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void configureLogLevel(IndefiniteProgressTask progressTask, SpringProcessParams springProcessParams,
|
||||
SpringProcessConnector connector, long delay, TimeUnit unit, int retryNo) {
|
||||
String processKey = springProcessParams.getProcessKey();
|
||||
|
||||
String progressMessage = "configure log level for Spring process: " + processKey + " - retry no: " + retryNo;
|
||||
log.info(progressMessage);
|
||||
|
||||
this.scheduler.schedule(() -> {
|
||||
|
||||
try {
|
||||
progressTask.progressEvent(progressMessage);
|
||||
SpringProcessUpdatedLogLevelData springProcessUpdatedLoggersData = connector.configureLogLevel(this.liveDataProvider.getCurrent(processKey), springProcessParams.getArgs());
|
||||
|
||||
if(springProcessUpdatedLoggersData != null) {
|
||||
this.liveDataProvider.updateLogLevel(processKey, springProcessUpdatedLoggersData);
|
||||
this.connectedSuccess.put(processKey, true);
|
||||
}
|
||||
|
||||
progressTask.done();
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
||||
log.info("problem occured during process live data refresh", e);
|
||||
|
||||
if (retryNo < maxRetryCount && isKnownProcessKey(processKey)) {
|
||||
configureLogLevel(progressTask, springProcessParams, connector, retryDelayInSeconds, TimeUnit.SECONDS,
|
||||
retryNo + 1);
|
||||
}
|
||||
else {
|
||||
progressTask.done();
|
||||
|
||||
// Send message to client if maximum retries reached on error
|
||||
if (isKnownProcessKey(processKey)) {
|
||||
diagnosticService.diagnosticEvent(ShowMessageException
|
||||
.error("Failed to refresh live data from process " + processKey + " after retries: " + retryNo, e));
|
||||
|
||||
if (!connectedSuccess.containsKey(connector.getProcessKey())) {
|
||||
disconnectProcess(processKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}, 0, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -269,6 +269,114 @@ public class SpringProcessLiveDataExtractorOverHttp {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param processType
|
||||
* @param processID if null, will be determined searching existing mbeans for that information (for remote processes via platform beans runtime name)
|
||||
* @param processName if null, will be determined searching existing mbeans for that information (for remote processes inferring the java command from the system properties)
|
||||
* @param currentData currently stored live data
|
||||
* @param metricName
|
||||
* @param tags
|
||||
*/
|
||||
public SpringProcessLoggersData retrieveLoggersData(ProcessType processType, ActuatorConnection connection, String processID, String processName,
|
||||
SpringProcessLiveData currentData) {
|
||||
|
||||
try {
|
||||
|
||||
if (processID == null) {
|
||||
processID = connection.getProcessID();
|
||||
}
|
||||
|
||||
if (processName == null) {
|
||||
Properties systemProperties = connection.getSystemProperties();
|
||||
if (systemProperties != null) {
|
||||
String javaCommand = getJavaCommand(systemProperties);
|
||||
processName = getProcessName(javaCommand);
|
||||
}
|
||||
}
|
||||
|
||||
Loggers loggers = getLoggers(connection);
|
||||
|
||||
return new SpringProcessLoggersData(
|
||||
processType,
|
||||
processName,
|
||||
processID,
|
||||
loggers
|
||||
);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("error reading live metrics data from: " + processID + " - " + processName, e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
public Loggers getLoggers(ActuatorConnection connection) {
|
||||
try {
|
||||
String result = connection.getLoggers();
|
||||
|
||||
if (result instanceof String) {
|
||||
return gson.fromJson((String)result, Loggers.class);
|
||||
} else if(result != null){
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
return mapper.convertValue(result, Loggers.class);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
} catch (Exception e) {
|
||||
log.error("Error parsing loggers", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public SpringProcessUpdatedLogLevelData configureLogLevel(ProcessType processType, ActuatorConnection connection, String processID, String processName,
|
||||
SpringProcessLiveData currentData, Map<String, String> args) {
|
||||
|
||||
try {
|
||||
|
||||
if (processID == null) {
|
||||
processID = connection.getProcessID();
|
||||
}
|
||||
|
||||
if (processName == null) {
|
||||
Properties systemProperties = connection.getSystemProperties();
|
||||
if (systemProperties != null) {
|
||||
String javaCommand = getJavaCommand(systemProperties);
|
||||
processName = getProcessName(javaCommand);
|
||||
}
|
||||
}
|
||||
|
||||
configureLogLevel(connection, args);
|
||||
return new SpringProcessUpdatedLogLevelData(
|
||||
processType,
|
||||
processName,
|
||||
processID,
|
||||
args.get("packageName"),
|
||||
args.get("effectiveLevel"),
|
||||
args.get("configuredLevel")
|
||||
);
|
||||
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("error reading live metrics data from: " + processID + " - " + processName + " : "+ args.get("packageName"), e);
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
public void configureLogLevel(ActuatorConnection connection, Map<String, String> args) {
|
||||
try {
|
||||
connection.configureLogLevel(args);
|
||||
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
} catch (Exception e) {
|
||||
log.error("Error parsing response", e);
|
||||
throw e;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
private StartupMetricsModel getStartupMetrics(ActuatorConnection connection, StartupMetricsModel currentStartup) {
|
||||
if (currentStartup != null) {
|
||||
return currentStartup;
|
||||
@@ -415,7 +523,7 @@ public class SpringProcessLiveDataExtractorOverHttp {
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
} catch (Exception e) {
|
||||
log.error("Error parsing beans", e);
|
||||
log.error("Error parsing live metrics", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -299,6 +299,124 @@ public class SpringProcessLiveDataExtractorOverJMX {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param processType
|
||||
* @param processID if null, will be determined searching existing mbeans for that information (for remote processes via platform beans runtime name)
|
||||
* @param processName if null, will be determined searching existing mbeans for that information (for remote processes inferring the java command from the system properties)
|
||||
* @param currentData currently stored live data
|
||||
*/
|
||||
public SpringProcessLoggersData retrieveLoggersData(ProcessType processType, JMXConnector jmxConnector, String processID, String processName,
|
||||
SpringProcessLiveData currentData) {
|
||||
|
||||
try {
|
||||
MBeanServerConnection connection = jmxConnector.getMBeanServerConnection();
|
||||
String domain = getDomainForActuator(connection);
|
||||
|
||||
if (processID == null) {
|
||||
processID = getProcessID(connection);
|
||||
}
|
||||
|
||||
if (processName == null) {
|
||||
Properties systemProperties = getSystemProperties(connection);
|
||||
if (systemProperties != null) {
|
||||
String javaCommand = getJavaCommand(systemProperties);
|
||||
processName = getProcessName(javaCommand);
|
||||
}
|
||||
}
|
||||
|
||||
Loggers loggers = getLoggers(connection, domain);
|
||||
|
||||
return new SpringProcessLoggersData(
|
||||
processType,
|
||||
processName,
|
||||
processID,
|
||||
loggers
|
||||
);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("error reading live metrics data from: " + processID + " - " + processName, e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Loggers getLoggers(MBeanServerConnection connection, String domain) {
|
||||
|
||||
Object[] params1 = new Object[] {};
|
||||
String[] signature = new String[] {String.class.getName(), List.class.getName()};
|
||||
|
||||
try {
|
||||
Object loggersData = getActuatorDataFromOperation(connection,
|
||||
getObjectName(domain, "type=Endpoint,name=Loggers"),
|
||||
"loggers",
|
||||
params1,
|
||||
signature);
|
||||
if (loggersData instanceof String) {
|
||||
return gson.fromJson((String)loggersData, Loggers.class);
|
||||
} else if(loggersData != null){
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
return objectMapper.convertValue(loggersData, Loggers.class);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public SpringProcessUpdatedLogLevelData configureLogLevel(ProcessType processType, JMXConnector jmxConnector,
|
||||
String processID, String processName, SpringProcessLiveData currentData, Map<String, String> args) {
|
||||
try {
|
||||
MBeanServerConnection connection = jmxConnector.getMBeanServerConnection();
|
||||
String domain = getDomainForActuator(connection);
|
||||
|
||||
if (processID == null) {
|
||||
processID = getProcessID(connection);
|
||||
}
|
||||
|
||||
if (processName == null) {
|
||||
Properties systemProperties = getSystemProperties(connection);
|
||||
if (systemProperties != null) {
|
||||
String javaCommand = getJavaCommand(systemProperties);
|
||||
processName = getProcessName(javaCommand);
|
||||
}
|
||||
}
|
||||
|
||||
changeLogLevel(connection, domain, args);
|
||||
return new SpringProcessUpdatedLogLevelData(
|
||||
processType,
|
||||
processName,
|
||||
processID,
|
||||
args.get("packageName"),
|
||||
args.get("effectiveLevel"),
|
||||
args.get("configuredLevel")
|
||||
);
|
||||
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("error changing log level : " + processID + " - " + processName + " : "+args.get("packageName"), e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void changeLogLevel(MBeanServerConnection connection, String domain, Map<String, String> args) throws Exception {
|
||||
|
||||
Object[] params = new Object[] {args.get("packageName"), args.get("configuredLevel")};
|
||||
String[] signature = new String[] {String.class.getName(), List.class.getName()};
|
||||
|
||||
try {
|
||||
getActuatorDataFromOperation(connection,
|
||||
getObjectName(domain, "type=Endpoint,name=Loggers"),
|
||||
"configureLogLevel",
|
||||
params,
|
||||
signature);
|
||||
} catch (Exception e) {
|
||||
log.error("", e);
|
||||
throw e;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
private StartupMetricsModel getStartupMetrics(MBeanServerConnection connection, String domain, StartupMetricsModel currentStartup) {
|
||||
if (currentStartup != null) {
|
||||
return currentStartup;
|
||||
@@ -751,6 +869,4 @@ public class SpringProcessLiveDataExtractorOverJMX {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.protocol.LiveProcessLoggersSummary;
|
||||
import org.springframework.ide.vscode.commons.protocol.LiveProcessSummary;
|
||||
import org.springframework.ide.vscode.commons.protocol.STS4LanguageClient;
|
||||
import org.springframework.ide.vscode.commons.util.Assert;
|
||||
@@ -29,6 +30,7 @@ public class SpringProcessLiveDataProvider {
|
||||
private final ConcurrentMap<String, SpringProcessLiveData> liveData;
|
||||
private final ConcurrentMap<String, SpringProcessMemoryMetricsLiveData> memoryMetricsLiveData;
|
||||
private final ConcurrentMap<String, SpringProcessGcPausesMetricsLiveData> gcPausesMetricsLiveData;
|
||||
private final ConcurrentMap<String, SpringProcessLoggersData> loggersData;
|
||||
private final List<SpringProcessLiveDataChangeListener> listeners;
|
||||
private final SimpleLanguageServer server;
|
||||
|
||||
@@ -37,6 +39,7 @@ public class SpringProcessLiveDataProvider {
|
||||
this.liveData = new ConcurrentHashMap<>();
|
||||
this.memoryMetricsLiveData = new ConcurrentHashMap<>();
|
||||
this.gcPausesMetricsLiveData = new ConcurrentHashMap<>();
|
||||
this.loggersData = new ConcurrentHashMap<>();
|
||||
this.listeners = new CopyOnWriteArrayList<>();
|
||||
}
|
||||
|
||||
@@ -104,6 +107,11 @@ public class SpringProcessLiveDataProvider {
|
||||
getClient().liveProcessGcPausesMetricsDataUpdated(createGcPausesMetricsSummary(processKey, liveData));
|
||||
}
|
||||
|
||||
public void updateLogLevel(String processKey, SpringProcessUpdatedLogLevelData updatedLogLevelData) {
|
||||
getClient().liveProcessLogLevelUpdated(createUpdatedLogLevelSummary(processKey, updatedLogLevelData));
|
||||
}
|
||||
|
||||
|
||||
public void addLiveDataChangeListener(SpringProcessLiveDataChangeListener listener) {
|
||||
this.listeners.add(listener);
|
||||
}
|
||||
@@ -131,6 +139,10 @@ public class SpringProcessLiveDataProvider {
|
||||
public SpringProcessGcPausesMetricsLiveData getGcPausesMetrics(String processKey) {
|
||||
return this.gcPausesMetricsLiveData.get(processKey);
|
||||
}
|
||||
|
||||
public SpringProcessLoggersData getLoggersData(String processKey) {
|
||||
return this.loggersData.get(processKey);
|
||||
}
|
||||
|
||||
public static LiveProcessSummary createProcessSummary(String processKey, SpringProcessLiveData liveData) {
|
||||
LiveProcessSummary p = new LiveProcessSummary();
|
||||
@@ -159,4 +171,11 @@ public class SpringProcessLiveDataProvider {
|
||||
return p;
|
||||
}
|
||||
|
||||
public static LiveProcessLoggersSummary createUpdatedLogLevelSummary(String processKey, SpringProcessUpdatedLogLevelData updatedLogLevelData) {
|
||||
LiveProcessLoggersSummary p = new LiveProcessLoggersSummary(updatedLogLevelData.getProcessType().jsonName(),
|
||||
processKey, updatedLogLevelData.getProcessName(), updatedLogLevelData.getProcessID(),
|
||||
updatedLogLevelData.getPackageName(), updatedLogLevelData.getEffectiveLevel(),
|
||||
updatedLogLevelData.getConfiguredLevel());
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 Broadcom, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Broadcom, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.livehover.v2;
|
||||
|
||||
/**
|
||||
* @author Udayani V
|
||||
*/
|
||||
public class SpringProcessLoggersData {
|
||||
|
||||
private final ProcessType processType;
|
||||
private final String processName;
|
||||
private final String processID;
|
||||
private final Loggers loggers;
|
||||
|
||||
public SpringProcessLoggersData(ProcessType processType, String processName, String processID,
|
||||
Loggers loggers) {
|
||||
super();
|
||||
this.processType = processType;
|
||||
this.processName = processName;
|
||||
this.processID = processID;
|
||||
this.loggers = loggers;
|
||||
|
||||
}
|
||||
|
||||
public ProcessType getProcessType() {
|
||||
return processType;
|
||||
}
|
||||
|
||||
public String getProcessName() {
|
||||
return processName;
|
||||
}
|
||||
|
||||
public String getProcessID() {
|
||||
return processID;
|
||||
}
|
||||
|
||||
public Loggers getLoggers() {
|
||||
return loggers;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,6 +10,8 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.livehover.v2;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author V Udayani
|
||||
*/
|
||||
@@ -19,7 +21,7 @@ public class SpringProcessParams {
|
||||
private String endpoint;
|
||||
private String metricName;
|
||||
private String tags;
|
||||
|
||||
private Map<String, String> args;
|
||||
public SpringProcessParams() {
|
||||
}
|
||||
|
||||
@@ -62,4 +64,12 @@ public class SpringProcessParams {
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
public Map<String, String> getArgs() {
|
||||
return args;
|
||||
}
|
||||
|
||||
public void setArgs(Map<String, String> args) {
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 Broadcom, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Broadcom, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.livehover.v2;
|
||||
|
||||
public class SpringProcessUpdatedLogLevelData {
|
||||
|
||||
private final ProcessType processType;
|
||||
private final String processName;
|
||||
private final String processID;
|
||||
private final String packageName;
|
||||
private final String effectiveLevel;
|
||||
private final String configuredLevel;
|
||||
|
||||
public SpringProcessUpdatedLogLevelData(ProcessType processType, String processName, String processID,
|
||||
String packageName, String effectiveLevel, String configuredLevel) {
|
||||
super();
|
||||
this.processType = processType;
|
||||
this.processName = processName;
|
||||
this.processID = processID;
|
||||
this.packageName = packageName;
|
||||
this.effectiveLevel = effectiveLevel;
|
||||
this.configuredLevel = configuredLevel;
|
||||
|
||||
}
|
||||
|
||||
public ProcessType getProcessType() {
|
||||
return processType;
|
||||
}
|
||||
|
||||
public String getProcessName() {
|
||||
return processName;
|
||||
}
|
||||
|
||||
public String getProcessID() {
|
||||
return processID;
|
||||
}
|
||||
|
||||
public String getPackageName() {
|
||||
return packageName;
|
||||
}
|
||||
|
||||
public String getEffectiveLevel() {
|
||||
return effectiveLevel;
|
||||
}
|
||||
|
||||
public String getConfiguredLevel() {
|
||||
return configuredLevel;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import { ApiManager } from "./apiManager";
|
||||
import { ExtensionAPI } from "./api";
|
||||
import {registerClasspathService} from "@pivotal-tools/commons-vscode/lib/classpath";
|
||||
import {registerJavaDataService} from "@pivotal-tools/commons-vscode/lib/java-data";
|
||||
import * as setLogLevelUi from './set-log-levels-ui';
|
||||
|
||||
const PROPERTIES_LANGUAGE_ID = "spring-boot-properties";
|
||||
const YAML_LANGUAGE_ID = "spring-boot-properties-yaml";
|
||||
@@ -146,6 +147,7 @@ export function activate(context: VSCode.ExtensionContext): Thenable<ExtensionAP
|
||||
VSCode.commands.registerCommand('vscode-spring-boot.ls.stop', () => client.stop());
|
||||
liveHoverUi.activate(client, options, context);
|
||||
rewrite.activate(client, options, context);
|
||||
setLogLevelUi.activate(client, options, context);
|
||||
|
||||
VSCode.commands.registerCommand('vscode-spring-boot.spring.modulith.metadata.refresh', async () => {
|
||||
const modulithProjects = await VSCode.commands.executeCommand('sts/modulith/projects');
|
||||
|
||||
@@ -8,9 +8,8 @@ import {
|
||||
LiveProcessUpdatedNotification,
|
||||
LiveProcessGcPausesMetricsUpdatedNotification,
|
||||
LiveProcessMemoryMetricsUpdatedNotification,
|
||||
SpringIndexUpdatedNotification
|
||||
SpringIndexUpdatedNotification,
|
||||
} from "./notification";
|
||||
import VSCode from "vscode";
|
||||
import {RequestType} from "vscode-languageclient";
|
||||
|
||||
export class ApiManager {
|
||||
@@ -29,6 +28,7 @@ export class ApiManager {
|
||||
const onDidLiveProcessGcPausesMetricsUpdate = this.onDidLiveProcessGcPausesMetricsUpdateEmitter.event;
|
||||
const onDidLiveProcessMemoryMetricsUpdate = this.onDidLiveProcessMemoryMetricsUpdateEmitter.event;
|
||||
const onSpringIndexUpdated = this.onSpringIndexUpdateEmitter.event;
|
||||
// const onDidLiveProcessLoggersUpdate = this.onDidLiveProcessLoggersUpdateEmitter.event;
|
||||
|
||||
const COMMAND_LIVEDATA_GET = "sts/livedata/get";
|
||||
const getLiveProcessData = async (query) => {
|
||||
|
||||
@@ -10,6 +10,18 @@ export interface LiveProcess {
|
||||
processName: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Information returned by notification for updated log level for the live process
|
||||
*/
|
||||
export interface LiveProcessUpdatedLogLevel {
|
||||
type: string;
|
||||
processKey: string;
|
||||
processName: string;
|
||||
packageName: string;
|
||||
effectiveLevel: string;
|
||||
configuredLevel: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialized interface for type 'local' LiveProcess.
|
||||
*/
|
||||
@@ -40,4 +52,8 @@ export namespace LiveProcessMemoryMetricsUpdatedNotification {
|
||||
|
||||
export namespace SpringIndexUpdatedNotification {
|
||||
export const type = new NotificationType<void>('spring/index/updated');
|
||||
}
|
||||
|
||||
export namespace LiveProcessLogLevelUpdatedNotification {
|
||||
export const type = new NotificationType<LiveProcessUpdatedLogLevel>('sts/liveprocess/loglevel/updated');
|
||||
}
|
||||
133
vscode-extensions/vscode-spring-boot/lib/set-log-levels-ui.ts
Normal file
133
vscode-extensions/vscode-spring-boot/lib/set-log-levels-ui.ts
Normal file
@@ -0,0 +1,133 @@
|
||||
'use strict';
|
||||
|
||||
import * as VSCode from 'vscode';
|
||||
import { LanguageClient } from "vscode-languageclient/node";
|
||||
import { ActivatorOptions } from '@pivotal-tools/commons-vscode';
|
||||
import { LiveProcess, LiveProcessLogLevelUpdatedNotification, LiveProcessUpdatedLogLevel } from './notification';
|
||||
|
||||
interface ProcessCommandInfo {
|
||||
processKey : string;
|
||||
label: string;
|
||||
action: string;
|
||||
projectName: string;
|
||||
}
|
||||
|
||||
export interface Logger {
|
||||
configuredLevel: string;
|
||||
effectiveLevel: string;
|
||||
}
|
||||
|
||||
export interface Loggers {
|
||||
[propName: string]: Logger;
|
||||
}
|
||||
|
||||
export interface LoggersData {
|
||||
levels: string[];
|
||||
loggers: Loggers;
|
||||
}
|
||||
|
||||
export interface ProcessLoggersData {
|
||||
loggers: LoggersData;
|
||||
processID: string;
|
||||
processName: string;
|
||||
processType: number;
|
||||
}
|
||||
|
||||
export interface LoggerItem {
|
||||
logger: Logger;
|
||||
name: string;
|
||||
}
|
||||
|
||||
async function setLogLevelHandler() {
|
||||
|
||||
const processData : ProcessCommandInfo[] = await VSCode.commands.executeCommand('sts/livedata/listProcesses');
|
||||
const choiceMap = new Map<string, ProcessCommandInfo>();
|
||||
const choices : string[] = [];
|
||||
processData.forEach(p => {
|
||||
const slash = p.action.lastIndexOf('/');
|
||||
if (slash>=0) {
|
||||
const choiceLabel = p.label;
|
||||
choiceMap.set(choiceLabel, p);
|
||||
choices.push(choiceLabel);
|
||||
}
|
||||
});
|
||||
if (choices) {
|
||||
const picked = await VSCode.window.showQuickPick(choices);
|
||||
if (picked) {
|
||||
const chosen = choiceMap.get(picked);
|
||||
try {
|
||||
const loggers: ProcessLoggersData = await getLoggers(chosen);
|
||||
await displayLoggers(loggers, chosen.processKey);
|
||||
} catch (error) {
|
||||
VSCode.window.showErrorMessage("Failed to fetch loggers for the process " + chosen.processKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function getLoggers(processInfo: ProcessCommandInfo): Promise<ProcessLoggersData> {
|
||||
|
||||
return new Promise(async (resolve, reject) => {
|
||||
await VSCode.window.withProgress({
|
||||
location: VSCode.ProgressLocation.Window,
|
||||
title: "Fetching Loggers Data for process "+processInfo.processKey,
|
||||
cancellable: false
|
||||
}, async (progress) => {
|
||||
try {
|
||||
const loggers: ProcessLoggersData = await VSCode.commands.executeCommand('sts/livedata/getLoggers', processInfo, {"endpoint": "loggers"});
|
||||
progress.report({});
|
||||
resolve(loggers);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function displayLoggers(processLoggersData: ProcessLoggersData, processKey: string) {
|
||||
let items;
|
||||
const loggersData = processLoggersData.loggers;
|
||||
if(loggersData.loggers) {
|
||||
items = Object.keys(loggersData.loggers).map(packageName => {
|
||||
const logger: Logger = loggersData.loggers[packageName];
|
||||
const effectiveLevel = logger.effectiveLevel;
|
||||
const label = packageName + ' (' + effectiveLevel + ')';
|
||||
return {
|
||||
packageName,
|
||||
effectiveLevel,
|
||||
label
|
||||
};
|
||||
});
|
||||
}
|
||||
if(items) {
|
||||
const chosenPackage = await VSCode.window.showQuickPick(items);
|
||||
if (chosenPackage) {
|
||||
const chosenlogLevel = await VSCode.window.showQuickPick(loggersData.levels);
|
||||
await VSCode.commands.executeCommand('sts/livedata/configure/logLevel', {"processKey": processKey}, chosenPackage, {"configuredLevel":chosenlogLevel});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async function logLevelUpdated(process: LiveProcessUpdatedLogLevel) {
|
||||
VSCode.window.showInformationMessage("The Log level for " + process.packageName + " has been updated from " +
|
||||
process.effectiveLevel + " to " + process.configuredLevel);
|
||||
}
|
||||
|
||||
/** Called when extension is activated */
|
||||
export function activate(
|
||||
client: LanguageClient,
|
||||
options: ActivatorOptions,
|
||||
context: VSCode.ExtensionContext
|
||||
) {
|
||||
client.onNotification(LiveProcessLogLevelUpdatedNotification.type, logLevelUpdated)
|
||||
context.subscriptions.push(
|
||||
VSCode.commands.registerCommand('vscode-spring-boot.set.log-levels', () => {
|
||||
if (client.isRunning()) {
|
||||
return setLogLevelHandler();
|
||||
} else {
|
||||
VSCode.window.showErrorMessage("No Spring Boot project found. Action is only available for Spring Boot Projects");
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -129,6 +129,11 @@
|
||||
"command": "vscode-spring-boot.spring.modulith.metadata.refresh",
|
||||
"title": "Refresh Modulith Metadata",
|
||||
"category": "Spring Boot"
|
||||
},
|
||||
{
|
||||
"command": "vscode-spring-boot.set.log-levels",
|
||||
"title": "Set Log Levels",
|
||||
"category": "Spring Boot"
|
||||
}
|
||||
],
|
||||
"configuration": [
|
||||
|
||||
Reference in New Issue
Block a user