Skip to content

Commit

Permalink
Transmit document telemetry in aggregate instead of on document open.
Browse files Browse the repository at this point in the history
- Fixes redhat-developer/vscode-xml#620

Signed-off-by: Roland Grunberg <rgrunber@redhat.com>
  • Loading branch information
rgrunber authored and angelozerr committed Dec 3, 2021
1 parent 261ebed commit fceb4c3
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 30 deletions.
Expand Up @@ -230,6 +230,7 @@ public CompletableFuture<Object> shutdown() {
if (capabilityManager.getClientCapabilities().getExtendedCapabilities().shouldLanguageServerExitOnShutdown()) {
delayer.schedule(() -> exit(0) , 1, TimeUnit.SECONDS);
}
getTelemetryManager().shutdown();
return computeAsync(cc -> new Object());
}

Expand Down
Expand Up @@ -14,9 +14,7 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.lemminx.dom.DOMDocument;
Expand All @@ -36,42 +34,39 @@ public class DocumentTelemetryInfo {
private static final String DOC_PROP_GRAMMAR_SCHEMALOC = "file.grammar.schemalocation";
private static final String DOC_PROP_GRAMMAR_NONSSCHEMALOC = "file.grammar.nonsschemalocation";

public static Map<String, Object> getDocumentTelemetryInfo (DOMDocument doc, ContentModelManager manager) {
public static void collectDocumentTelemetryInfo (DOMDocument doc, ContentModelManager manager, TelemetryCache cache) {
String uri = doc.getDocumentURI();
int index = uri.lastIndexOf('.');
String fileExtension = uri.substring(index + 1, uri.length()).toLowerCase();
boolean isXML = !DOMUtils.isXSD(doc) && !DOMUtils.isDTD(uri);
Set<ReferencedGrammarInfo> referencedGrammarInfos = manager.getReferencedGrammarInfos(doc);
HashMap<String, Object> props = new HashMap<>();
props.put(DOC_PROP_EXT, fileExtension);
cache.put(String.join(".", DOC_PROP_EXT, fileExtension));

if (referencedGrammarInfos.isEmpty()) {
if (isXML) {
props.put(DOC_PROP_GRAMMAR_NONE, true);
cache.put(DOC_PROP_GRAMMAR_NONE);
}
} else {
List<String> resolvers = new ArrayList<String>();
List<String> identifiers = new ArrayList<String>();
for (ReferencedGrammarInfo info : referencedGrammarInfos) {
String kind = info.getBindingKind() == null ? "none" : info.getBindingKind();
String resolver = info.getResolvedBy();
String identifier = info.getIdentifierURI();
if (isXML) {
switch (kind) {
case "none":
props.put(DOC_PROP_GRAMMAR_NONE, true);
cache.put(DOC_PROP_GRAMMAR_NONE);
break;
case "doctype":
props.put(DOC_PROP_GRAMMAR_DOCTYPE, true);
cache.put(DOC_PROP_GRAMMAR_DOCTYPE);
break;
case "xml-model":
props.put(DOC_PROP_GRAMMAR_XMLMODEL, true);
cache.put(DOC_PROP_GRAMMAR_XMLMODEL);
break;
case "xsi:schemaLocation":
props.put(DOC_PROP_GRAMMAR_SCHEMALOC, true);
cache.put(DOC_PROP_GRAMMAR_SCHEMALOC);
break;
case "xsi:noNamespaceSchemaLocation":
props.put(DOC_PROP_GRAMMAR_NONSSCHEMALOC, true);
cache.put(DOC_PROP_GRAMMAR_NONSSCHEMALOC);
break;
}
}
Expand All @@ -80,28 +75,15 @@ public static Map<String, Object> getDocumentTelemetryInfo (DOMDocument doc, Con
// non-local identifiers only
if (new URI(identifier).getScheme() != null && !URIUtils.isFileResource(identifier)) {
int limit = Math.min(identifier.length(), 200); // 200 char limit
identifiers.add(identifier.substring(0, limit));
String shortId = identifier.substring(0, limit);
cache.put(String.join(".", DOC_PROP_IDENTIFIER, shortId));
}
} catch (URISyntaxException e) {
// continue
}
}
resolvers.add(resolver == null ? "default" : resolver);
}

if (resolvers.size() == 1) {
props.put(DOC_PROP_RESOLVER, resolvers.iterator().next());
} else {
props.put(DOC_PROP_RESOLVER, resolvers);
}
if (!identifiers.isEmpty()) {
if (identifiers.size() == 1) {
props.put(DOC_PROP_IDENTIFIER, identifiers.iterator().next());
} else {
props.put(DOC_PROP_IDENTIFIER, identifiers);
}
cache.put(String.join(".", DOC_PROP_RESOLVER, resolver == null ? "default" : resolver));
}
}
return props;
}
}
@@ -0,0 +1,32 @@
/*******************************************************************************
* Copyright (c) 2021 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.lemminx.telemetry;

import java.util.HashMap;
import java.util.Map;

/**
* Store telemetry data for transmission at a later time
*/
public class TelemetryCache {

private Map<String, Integer> cache = new HashMap<>();

public void put (String key) {
cache.put(key, cache.getOrDefault(key, 0) + 1);
}

public Map<String, Integer> getProperties() {
return cache;
}

}
Expand Up @@ -25,15 +25,20 @@ public class TelemetryManager {
* "startup" telemetry event name
*/
private static final String STARTUP_EVENT_NAME = "server.initialized";
private static final String SHUTDOWN_EVENT_NAME = "server.shutdown";

@SuppressWarnings("unused")
private static final String DOC_OPEN_EVENT_NAME = "server.document.open";

private final LanguageClient languageClient;

private final TelemetryCache telemetryCache;

private boolean enabled;

public TelemetryManager(LanguageClient languageClient) {
this.languageClient = languageClient;
this.telemetryCache = new TelemetryCache();
}

public boolean isEnabled() {
Expand All @@ -56,7 +61,9 @@ public void onInitialized(InitializedParams params) {
}

public void onDidOpen(DOMDocument document, ContentModelManager manager) {
telemetryEvent(DOC_OPEN_EVENT_NAME, DocumentTelemetryInfo.getDocumentTelemetryInfo(document, manager));
if (isEnabled()) {
DocumentTelemetryInfo.collectDocumentTelemetryInfo(document, manager, telemetryCache);
}
}

/**
Expand All @@ -69,4 +76,10 @@ private void telemetryEvent(String eventName, Object object) {
}
}

public void shutdown() {
if (isEnabled()) {
telemetryEvent(SHUTDOWN_EVENT_NAME, telemetryCache.getProperties());
}
}

}

0 comments on commit fceb4c3

Please sign in to comment.