diff --git a/core/src/main/java/hudson/Functions.java b/core/src/main/java/hudson/Functions.java index d99a7674d2..0bba419f52 100644 --- a/core/src/main/java/hudson/Functions.java +++ b/core/src/main/java/hudson/Functions.java @@ -27,6 +27,7 @@ package hudson; import hudson.model.Slave; import hudson.security.*; +import jenkins.telemetry.impl.AutoRefresh; import jenkins.util.SystemProperties; import hudson.cli.CLICommand; import hudson.console.ConsoleAnnotationDescriptor; @@ -178,6 +179,7 @@ import org.kohsuke.accmod.restrictions.DoNotUse; @SuppressWarnings("rawtypes") public class Functions { private static final AtomicLong iota = new AtomicLong(); + private static Logger LOGGER = Logger.getLogger(Functions.class.getName()); public Functions() { } @@ -646,6 +648,12 @@ public class Functions { if (refresh) { response.addHeader("Refresh", SystemProperties.getString("hudson.Functions.autoRefreshSeconds", "10")); } + + try { + ExtensionList.lookupSingleton(AutoRefresh.class).recordRequest(request, refresh); + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Failed to record auto refresh status in telemetry", e); + } } public static boolean isAutoRefresh(HttpServletRequest request) { diff --git a/core/src/main/java/jenkins/telemetry/Telemetry.java b/core/src/main/java/jenkins/telemetry/Telemetry.java index d528f5e9ed..2817db937d 100644 --- a/core/src/main/java/jenkins/telemetry/Telemetry.java +++ b/core/src/main/java/jenkins/telemetry/Telemetry.java @@ -141,6 +141,17 @@ public abstract class Telemetry implements ExtensionPoint { return jenkins == null || !jenkins.isUsageStatisticsCollected(); } + /** + * Returns true iff we're in the time period during which this is supposed to collect data. + * @return true iff we're in the time period during which this is supposed to collect data + * + * @since TODO + */ + public boolean isActivePeriod() { + LocalDate now = LocalDate.now(); + return now.isAfter(getStart()) && now.isBefore(getEnd()); + } + @Extension public static class TelemetryReporter extends AsyncPeriodicWork { diff --git a/core/src/main/java/jenkins/telemetry/impl/AutoRefresh.java b/core/src/main/java/jenkins/telemetry/impl/AutoRefresh.java new file mode 100644 index 0000000000..cbbe31e3d8 --- /dev/null +++ b/core/src/main/java/jenkins/telemetry/impl/AutoRefresh.java @@ -0,0 +1,107 @@ +/* + * The MIT License + * + * Copyright (c) 2019, Daniel Beck + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package jenkins.telemetry.impl; + +import hudson.Extension; +import jenkins.telemetry.Telemetry; +import net.sf.json.JSONObject; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +import javax.annotation.Nonnull; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import java.time.LocalDate; +import java.util.HashSet; +import java.util.Set; + +@Extension +@Restricted(NoExternalUse.class) +public class AutoRefresh extends Telemetry { + + private static final Set sessionsWithAutoRefresh = new HashSet<>(); + private static final Set sessionsWithoutAutoRefresh = new HashSet<>(); + + @Nonnull + @Override + public String getDisplayName() { + return Messages.AutoRefresh_DisplayName(); + } + + @Nonnull + @Override + public LocalDate getStart() { + return LocalDate.of(2019, 10, 20); + } + + @Nonnull + @Override + public LocalDate getEnd() { + return LocalDate.of(2019, 12, 31); + } + + @Override + public JSONObject createContent() { + int sessionsWithAutoRefreshCount, sessionsWithoutAutoRefreshCount; + synchronized (sessionsWithAutoRefresh) { + sessionsWithAutoRefreshCount = sessionsWithAutoRefresh.size(); + sessionsWithAutoRefresh.clear(); + } + synchronized (sessionsWithoutAutoRefresh) { + sessionsWithoutAutoRefreshCount = sessionsWithoutAutoRefresh.size(); + sessionsWithoutAutoRefresh.clear(); + } + + if (sessionsWithAutoRefreshCount == 0 && sessionsWithoutAutoRefreshCount == 0) { + return null; + } + + JSONObject payload = new JSONObject(); + payload.put("enabled", sessionsWithAutoRefreshCount); + payload.put("disabled", sessionsWithoutAutoRefreshCount); + return payload; + } + + public void recordRequest(HttpServletRequest request, boolean enabled) { + if (Telemetry.isDisabled()) { + return; + } + if (!isActivePeriod()) { + return; + } + HttpSession session = request.getSession(false); + if (session != null) { + String sessionId = session.getId(); + if (enabled) { + synchronized (sessionsWithAutoRefresh) { + sessionsWithAutoRefresh.add(sessionId); + } + } else { + synchronized (sessionsWithoutAutoRefresh) { + sessionsWithoutAutoRefresh.add(sessionId); + } + } + } + } +} diff --git a/core/src/main/resources/jenkins/telemetry/impl/AutoRefresh/description.jelly b/core/src/main/resources/jenkins/telemetry/impl/AutoRefresh/description.jelly new file mode 100644 index 0000000000..e38f0f15cb --- /dev/null +++ b/core/src/main/resources/jenkins/telemetry/impl/AutoRefresh/description.jelly @@ -0,0 +1,5 @@ + + + This trial collects information about the "Auto Refresh" feature to determine whether the feature is used enough to not remove it in a future release of Jenkins. + We collect the number of HTTP sessions that have the feature (typically controlled via a cookie) enabled or disabled. + diff --git a/core/src/main/resources/jenkins/telemetry/impl/Messages.properties b/core/src/main/resources/jenkins/telemetry/impl/Messages.properties new file mode 100644 index 0000000000..da589e5dba --- /dev/null +++ b/core/src/main/resources/jenkins/telemetry/impl/Messages.properties @@ -0,0 +1 @@ +AutoRefresh.DisplayName = Use of auto refresh feature \ No newline at end of file