Skip to content

Commit

Permalink
Log Levels View
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
vudayani and V Udayani authored Dec 20, 2023
1 parent f27c423 commit e319e43
Show file tree
Hide file tree
Showing 23 changed files with 894 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -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) {

}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@
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;
Expand Down Expand Up @@ -437,6 +438,10 @@ public void indexUpdated() {
receiveIndexUpdated();
}

@Override
public void liveProcessLogLevelUpdated(LiveProcessLoggersSummary processKey) {
}

});

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,21 @@ public String getBeans() throws IOException {
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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}

}
Original file line number Diff line number Diff line change
@@ -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;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -88,6 +91,16 @@ public SpringProcessCommandHandler(SimpleLanguageServer server, SpringProcessCon
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<>();
Expand Down Expand Up @@ -320,4 +333,34 @@ private CompletableFuture<Object> handleLiveMetricsProcessRequest(ExecuteCommand
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);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.livehover.v2;

import java.util.Map;

/**
* @author Martin Lippert
*/
Expand All @@ -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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -157,6 +159,49 @@ public SpringProcessMemoryMetricsLiveData refreshMemoryMetrics(SpringProcessLive

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");
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,50 @@ public void disconnect() throws Exception {
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) {
Expand Down
Loading

0 comments on commit e319e43

Please sign in to comment.