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 eclipse#430

Rebase of eclipse#493

Signed-off-by: David Thompson <[email protected]>
  • Loading branch information
datho7561 committed Feb 12, 2021
1 parent 4f2ed3d commit 1df0098
Show file tree
Hide file tree
Showing 22 changed files with 985 additions and 266 deletions.
21 changes: 21 additions & 0 deletions USAGE_DATA.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# 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
* Does NOT include the `JAVA_HOME` environment variable for privacy reasons
* Version information:
* The Maven version number
* The branch of the build
* The short form of the commit id
* The short form of the commit message

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 @@ -42,29 +42,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 @@ -151,7 +151,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 @@ -178,7 +178,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 @@ -217,7 +217,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 1df0098

Please sign in to comment.