Skip to content

Commit

Permalink
feat: add new usage data collection for dev-mode (#12381) (#12550)
Browse files Browse the repository at this point in the history
Collects usage statistics once a day in development mode.
Can be opt out with `devmode.usageStatistics.enabled` configuration parameter.

Co-authored-by: Pekka Hyvönen <pekka@vaadin.com>
Co-authored-by: Artur Signell <artur@vaadin.com>

Co-authored-by: Sami Ekblad <sami@vaadin.com>
Co-authored-by: Pekka Hyvönen <pekka@vaadin.com>
Co-authored-by: Artur Signell <artur@vaadin.com>
  • Loading branch information
4 people committed Dec 9, 2021
1 parent 193d65b commit 161382b
Show file tree
Hide file tree
Showing 32 changed files with 2,504 additions and 4 deletions.
24 changes: 22 additions & 2 deletions flow-client/src/main/frontend/VaadinDevmodeGizmo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -803,8 +803,24 @@ export class VaadinDevmodeGizmo extends LitElement {

private transitionDuration: number = 0;

constructor() {
super();
elementTelemetry() {
let data = {};
try {
// localstorage data is collected by vaadin-usage-statistics.js
const localStorageStatsString = localStorage.getItem('vaadin.statistics.basket');
if (!localStorageStatsString) {
// Do not send empty data
return;
}
data = JSON.parse(localStorageStatsString);
} catch (e) {
// In case of parse errors don't send anything
return;
}

if (this.frontendConnection) {
this.frontendConnection.sendTelemetry(data);
}
}

openWebSocketConnection() {
Expand All @@ -830,6 +846,7 @@ export class VaadinDevmodeGizmo extends LitElement {
if (!VaadinDevmodeGizmo.isActive) {
frontendConnection.setActive(false);
}
this.elementTelemetry();
};
frontendConnection.onConnectionError = onConnectionError;
frontendConnection.onReload = onReload;
Expand Down Expand Up @@ -1484,6 +1501,9 @@ class Connection extends Object {
setFeature(featureId: string, enabled: boolean) {
this.send('setFeature', { featureId, enabled });
}
sendTelemetry(browserData: any) {
this.send('reportTelemetry', { browserData });
}
}

enum MessageType {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,21 @@ default boolean isGlobalPnpm() {
Constants.GLOBAL_PNPM_DEFAULT);
}

/**
* Returns whether development time usage statistics collection is enabled
* or not.
*
* Always return false if <code>isProductionMode</code> is {@code true}.
*
* @see #isProductionMode()
* @return {@code true} if enabled, {@code false} if not collected.
*/
default boolean isUsageStatisticsEnabled() {
return !isProductionMode() && getBooleanProperty(
InitParameters.SERVLET_PARAMETER_DEVMODE_STATISTICS,
Constants.DEFAULT_DEVMODE_STATS);
}

/**
* Returns whether cross-site request forgery protection is enabled.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,11 @@ public final class Constants implements Serializable {
*/
public static final boolean DEFAULT_REQUIRE_HOME_NODE_EXECUTABLE = false;

/**
* The default value for whether usage statistics is enabled.
*/
public static final boolean DEFAULT_DEVMODE_STATS = true;

/**
* @deprecated Use {@link InitParameters#REQUIRE_HOME_NODE_EXECUTABLE}
* instead.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,13 @@ public class InitParameters implements Serializable {
*/
public static final String SERVLET_PARAMETER_ENABLE_PNPM = "pnpm.enable";

/*
* Configuration parameter name for enabling usage statistics.
*
* @since
*/
public static final String SERVLET_PARAMETER_DEVMODE_STATISTICS = "devmode.usageStatistics.enabled";

/**
* Configuration parameter name for using globally installed pnpm or default
* one.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,13 @@ public boolean isPnpmEnabled() {
return parentConfig.isPnpmEnabled();
}

@Override
public boolean isUsageStatisticsEnabled() {
return !isProductionMode() && getBooleanProperty(
InitParameters.SERVLET_PARAMETER_DEVMODE_STATISTICS, true)
&& enableDevServer();
}

@Override
public boolean isGlobalPnpm() {
if (isOwnProperty(InitParameters.SERVLET_PARAMETER_GLOBAL_PNPM)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ protected Stream<String> getExcludedPatterns() {
"com\\.vaadin\\.flow\\.osgi\\.support\\..*",
"com\\.vaadin\\.flow\\.server\\.osgi\\..*",
"com\\.vaadin\\.base\\.devserver\\.DevServerOutputTracker.*",
"com\\.vaadin\\.base\\.devserver\\.stats..*",
"com\\.vaadin\\.flow\\.internal\\.VaadinContextInitializer",
"com\\.vaadin\\.flow\\.internal\\.ApplicationClassLoaderAccess",
"com\\.vaadin\\.base\\.devserver\\.BrowserLiveReloadAccessorImpl",
Expand Down
6 changes: 6 additions & 0 deletions vaadin-dev-server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<scope>test</scope>
</dependency>

</dependencies>


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
import javax.servlet.http.HttpServletResponse;

import com.vaadin.base.devserver.DevServerOutputTracker.Result;
import com.vaadin.base.devserver.stats.DevModeUsageStatistics;
import com.vaadin.base.devserver.stats.StatisticsConstants;
import com.vaadin.flow.di.Lookup;
import com.vaadin.flow.internal.BrowserLiveReload;
import com.vaadin.flow.internal.BrowserLiveReloadAccessor;
Expand All @@ -63,6 +65,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static com.vaadin.base.devserver.stats.StatisticsConstants.EVENT_LIVE_RELOAD;

/**
* Deals with most details of starting a frontend development server or
* connecting to an existing one.
Expand Down Expand Up @@ -218,6 +222,10 @@ private void doStartDevModeServer() throws ExecutionFailedException {

long ms = (System.nanoTime() - start) / 1000000;
getLogger().info("Started {}. Time: {}ms", getServerName(), ms);
DevModeUsageStatistics.collectEvent(
StatisticsConstants.EVENT_DEV_SERVER_START_PREFIX
+ getServerName(),
ms);
} finally {
if (devServerProcess.get() == null) {
removeRunningDevServerPort();
Expand Down Expand Up @@ -277,7 +285,8 @@ protected void validateFiles() throws ExecutionFailedException {
protected abstract File getServerConfig();

/**
* Gets the name of the dev server for outputting to the user.
* Gets the name of the dev server for outputting to the user and
* statistics.
*/
protected abstract String getServerName();

Expand Down Expand Up @@ -441,6 +450,7 @@ protected DevServerWatchDog getWatchDog() {
protected void triggerLiveReload() {
if (liveReload != null) {
liveReload.reload();
DevModeUsageStatistics.collectEvent(EVENT_LIVE_RELOAD);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.stream.Collectors;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.vaadin.base.devserver.stats.DevModeUsageStatistics;
import com.vaadin.experimental.FeatureFlags;
import com.vaadin.flow.internal.BrowserLiveReload;
import com.vaadin.flow.server.VaadinContext;
Expand Down Expand Up @@ -169,10 +170,14 @@ public void onMessage(String message) {
return;
}
JsonObject json = Json.parse(message);
if ("setFeature".equals(json.getString("command"))) {
String command = json.getString("command");
if ("setFeature".equals(command)) {
JsonObject data = json.getObject("data");
FeatureFlags.get(context).setEnabled(data.getString("featureId"),
data.getBoolean("enabled"));
} else if ("reportTelemetry".equals(command)) {
JsonObject data = json.getObject("data");
DevModeUsageStatistics.handleBrowserData(data);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@

import com.vaadin.base.devserver.ViteHandler;
import com.vaadin.base.devserver.WebpackHandler;
import com.vaadin.base.devserver.stats.DevModeUsageStatistics;
import com.vaadin.base.devserver.stats.StatisticsSender;
import com.vaadin.base.devserver.stats.StatisticsStorage;
import com.vaadin.experimental.FeatureFlags;
import com.vaadin.flow.di.Lookup;
import com.vaadin.flow.internal.DevModeHandler;
Expand Down Expand Up @@ -207,6 +210,13 @@ public static DevModeHandler initDevModeHandler(Set<Class<?>> classes,
baseDir = getBaseDirectoryFallback();
}

// Initialize the usage statistics if enabled
if (config.isUsageStatisticsEnabled()) {
StatisticsStorage storage = new StatisticsStorage();
DevModeUsageStatistics.init(baseDir, storage,
new StatisticsSender(storage));
}

String generatedDir = System.getProperty(PARAM_GENERATED_DIR,
Paths.get(config.getBuildFolder(), DEFAULT_GENERATED_DIR)
.toString());
Expand Down

0 comments on commit 161382b

Please sign in to comment.