Skip to content

Commit

Permalink
Server emits a telemetry event for initialization
Browse files Browse the repository at this point in the history
Please refer to `USAGE_DATA.md` for a full list of data collected.

Add `xml.telemetry.enable` to control if telemetry events are sent.

Closes #430

Rebase of #493

Signed-off-by: David Thompson <[email protected]>
  • Loading branch information
datho7561 committed Mar 8, 2021
1 parent 1b7f5c9 commit 3e0a56e
Show file tree
Hide file tree
Showing 21 changed files with 901 additions and 266 deletions.
18 changes: 18 additions & 0 deletions USAGE_DATA.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Telemetry data collection

If `xml.telemetry.enabled` is set to `true`, LemMinX emits telemetry events.
These events can be collected by the LSP client program.

When telemetry events are enabled, the following information is emitted when the language server starts:

* JVM information:
* Whether LemMinX is being run with Java or as a GraalVM native image (binary)
* The name of the vm (`java.vm.name`)
* The name of the runtime (`java.runtime.name`)
* The version of the JVM (`java.version`)
* The free, total, and max VM memory
* Version information:
* The server version number
* Note: Does NOT include the `JAVA_HOME` environment variable for privacy reasons

Currently, the startup event is the only telemetry event that is emitted.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import org.eclipse.lemminx.settings.InitializationOptionsSettings;
import org.eclipse.lemminx.settings.ServerSettings;
import org.eclipse.lemminx.settings.SharedSettings;
import org.eclipse.lemminx.settings.XMLTelemetrySettings;
import org.eclipse.lemminx.settings.XMLCodeLensSettings;
import org.eclipse.lemminx.settings.XMLCompletionSettings;
import org.eclipse.lemminx.settings.XMLFormattingOptions;
Expand All @@ -54,8 +55,9 @@
import org.eclipse.lemminx.settings.capabilities.InitializationOptionsExtendedClientCapabilities;
import org.eclipse.lemminx.settings.capabilities.ServerCapabilitiesInitializer;
import org.eclipse.lemminx.settings.capabilities.XMLCapabilityManager;
import org.eclipse.lemminx.telemetry.TelemetryManager;
import org.eclipse.lemminx.utils.FilesUtils;
import org.eclipse.lemminx.utils.ServerInfo;
import org.eclipse.lemminx.utils.platform.Platform;
import org.eclipse.lsp4j.Command;
import org.eclipse.lsp4j.InitializeParams;
import org.eclipse.lsp4j.InitializeResult;
Expand Down Expand Up @@ -86,17 +88,18 @@ public class XMLLanguageServer
private final ScheduledExecutorService delayer;
private Integer parentProcessId;
private XMLCapabilityManager capabilityManager;
private TelemetryManager telemetryManager;

public XMLLanguageServer() {
xmlTextDocumentService = new XMLTextDocumentService(this);
xmlWorkspaceService = new XMLWorkspaceService(this);

xmlLanguageService = new XMLLanguageService();
xmlLanguageService.setDocumentProvider(this);
xmlLanguageService.setNotificationService(this);
xmlLanguageService.setCommandService(xmlWorkspaceService);
xmlLanguageService.setValidationService(this);

delayer = Executors.newScheduledThreadPool(1);
}

Expand All @@ -108,7 +111,7 @@ public CompletableFuture<InitializeResult> initialize(InitializeParams params) {

LogHelper.initializeRootLogger(languageClient, settings == null? null : settings.getLogs());

LOGGER.info("Initializing XML Language server" + System.lineSeparator() + new ServerInfo().details());
LOGGER.info("Initializing XML Language server" + System.lineSeparator() + Platform.details());

this.parentProcessId = params.getProcessId();

Expand All @@ -135,18 +138,19 @@ public CompletableFuture<InitializeResult> initialize(InitializeParams params) {
* turn on/off
*
* (non-Javadoc)
*
*
* @see org.eclipse.lsp4j.services.LanguageServer#initialized(org.eclipse.lsp4j.
* InitializedParams)
*/
@Override
public void initialized(InitializedParams params) {
capabilityManager.initializeCapabilities();
getTelemetryManager().onInitialized(params);
}

/**
* Update XML settings configured from the client.
*
*
* @param initOptions the XML settings
*/
public synchronized void updateSettings(Object initOptions) {
Expand All @@ -155,7 +159,7 @@ public synchronized void updateSettings(Object initOptions) {

/**
* Update XML settings configured from the client.
*
*
* @param initOptions Settings the XML settings
* @param initLogs whether to initialize the log handlers
*/
Expand All @@ -168,10 +172,15 @@ private synchronized void updateSettings(Object initOptions, boolean initLogs) {
XMLGeneralClientSettings xmlClientSettings = XMLGeneralClientSettings.getGeneralXMLSettings(initSettings);
if (xmlClientSettings != null) {
if (initLogs) {
// Update logs settings
// Update logs settings
LogHelper.initializeRootLogger(languageClient, xmlClientSettings.getLogs());
}


XMLTelemetrySettings newTelemetry = xmlClientSettings.getTelemetry();
if (newTelemetry != null) {
getTelemetryManager().setEnabled(newTelemetry.isEnabled());
}

// Update format settings
XMLFormattingOptions formatterSettings = xmlClientSettings.getFormat();
if (formatterSettings != null) {
Expand Down Expand Up @@ -244,6 +253,7 @@ public WorkspaceService getWorkspaceService() {
public void setClient(LanguageClient languageClient) {
this.languageClient = (XMLLanguageClientAPI) languageClient;
capabilityManager = new XMLCapabilityManager(this.languageClient, xmlTextDocumentService);
telemetryManager = new TelemetryManager(languageClient);
}

public XMLLanguageClientAPI getLanguageClient() {
Expand Down Expand Up @@ -298,7 +308,7 @@ public void sendNotification(String message, MessageType messageType, Command...
// the open settings command is not supported by the client, display a simple
// message with LSP
languageClient.showMessage(new MessageParams(messageType, message));
}
}
}

@Override
Expand All @@ -322,5 +332,14 @@ public void validate(DOMDocument document) {
public XMLCapabilityManager getCapabilityManager() {
return capabilityManager;
}


/**
* Returns the telemetry manager.
*
* @return the telemetry manager.
*/
public TelemetryManager getTelemetryManager() {
return telemetryManager;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*******************************************************************************/
package org.eclipse.lemminx.commons;

import static org.eclipse.lemminx.utils.OSUtils.isWindows;
import static org.eclipse.lemminx.utils.platform.Platform.isWindows;

import java.io.IOException;
import java.util.concurrent.Executors;
Expand Down Expand Up @@ -113,9 +113,9 @@ private boolean parentProcessStillRunning() {
if (!finished) {
process.destroyForcibly();
}
// Terminating or destroying the Process doesn't close the process handle on Windows.
// Terminating or destroying the Process doesn't close the process handle on Windows.
// It is only closed when the Process object is garbage collected (in its finalize() method).
// On Windows, when the Java LS is idle, we need to explicitly request a GC,
// On Windows, when the Java LS is idle, we need to explicitly request a GC,
// to prevent an accumulation of zombie processes, as finalize() will be called.
if (isWindows) {
// Java >= 9 doesn't close the handle when the process is garbage collected
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
package org.eclipse.lemminx.extensions.general.completion;

import static org.eclipse.lemminx.utils.FilesUtils.getFilePathSlash;
import static org.eclipse.lemminx.utils.OSUtils.isWindows;
import static org.eclipse.lemminx.utils.StringUtils.isEmpty;
import static org.eclipse.lemminx.utils.platform.Platform.isWindows;

import java.io.File;
import java.io.FilenameFilter;
Expand Down Expand Up @@ -43,29 +43,29 @@

/**
* Extension to support completion for file, folder path in:
*
*
* <ul>
* <li>attribute value:
*
*
* <pre>
* &lt;item path="file:///C:/folder" /&gt;
* &lt;item path="file:///C:/folder file:///C:/file.txt" /&gt;
* &lt;item path="/folder" /&gt;
* </pre>
*
*
* </li>
* <li>DTD DOCTYPE SYSTEM
*
*
* <pre>
* &lt;!DOCTYPE parent SYSTEM "file.dtd"&gt;
* </pre>
*
*
* </li>
*
*
* </ul>
*
*
* <p>
*
*
* </p>
*/
public class FilePathCompletionParticipant extends CompletionParticipantAdapter {
Expand Down Expand Up @@ -152,7 +152,7 @@ private static void addCompletionItems(String value, ICompletionRequest request,

/**
* Returns the IO Path from the given value path.
*
*
* @param valuePath the value path
* @param xmlFileUri the XML file URI where completion has been triggered.
* @return the IO Path from the given value path.
Expand All @@ -179,7 +179,7 @@ private static Path getPath(String valuePath, String xmlFileUri) {
/**
* Returns a Range that covers trailing content after a slash, or if it already
* ends with a slash then a Range right after it.
*
*
* @param xmlDocument
* @param fullRange
* @param attributeValue
Expand Down Expand Up @@ -218,7 +218,7 @@ private static Range adjustReplaceRange(DOMDocument xmlDocument, Range fullRange

/**
* Creates the completion items based off the given absolute path
*
*
* @param pathToAttributeDirectory
* @param attributePath
* @param replaceRange
Expand Down
Loading

0 comments on commit 3e0a56e

Please sign in to comment.