FUS: extract sending log into separate module (for IDEA-228935)

GitOrigin-RevId: 5152b1206f527ef784f6b13a1fcd95a5f2ce95c4
This commit is contained in:
Svetlana.Zemlyanskaya
2020-01-29 17:12:43 +00:00
committed by intellij-monorepo-bot
parent 6f7ab07726
commit 0a1ee59161
36 changed files with 327 additions and 148 deletions
+1
View File
@@ -662,6 +662,7 @@
<module fileurl="file://$PROJECT_DIR$/platform/smRunner/intellij.platform.smRunner.iml" filepath="$PROJECT_DIR$/platform/smRunner/intellij.platform.smRunner.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/statistics/intellij.platform.statistics.iml" filepath="$PROJECT_DIR$/platform/statistics/intellij.platform.statistics.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/statistics/devkit/intellij.platform.statistics.devkit.iml" filepath="$PROJECT_DIR$/platform/statistics/devkit/intellij.platform.statistics.devkit.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/statistics/sender/intellij.platform.statistics.sender.iml" filepath="$PROJECT_DIR$/platform/statistics/sender/intellij.platform.statistics.sender.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/structuralsearch/intellij.platform.structuralSearch.iml" filepath="$PROJECT_DIR$/platform/structuralsearch/intellij.platform.structuralSearch.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/structuralsearch/intellij.platform.structuralSearch.tests.iml" filepath="$PROJECT_DIR$/platform/structuralsearch/intellij.platform.structuralSearch.tests.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/structure-view-impl/intellij.platform.structureView.impl.iml" filepath="$PROJECT_DIR$/platform/structure-view-impl/intellij.platform.structureView.impl.iml" />
@@ -144,6 +144,7 @@ class DistributionJARsBuilder {
withModule("intellij.spellchecker")
withModule("intellij.platform.images")
withModule("intellij.platform.statistics")
withModule("intellij.platform.statistics.sender")
withModule("intellij.platform.statistics.devkit")
withModule("intellij.relaxng", "intellij-xml.jar")
@@ -328,7 +328,7 @@ class TestFeatureUsageEventWriter : StatisticsEventLogWriter {
}
override fun getActiveFile(): EventLogFile? = null
override fun getFiles(): List<EventLogFile> = emptyList()
override fun getLogFilesProvider(): EventLogFilesProvider = EmptyEventLogFilesProvider
override fun cleanup() = Unit
override fun rollOver() = Unit
}
@@ -33,7 +33,6 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import static com.intellij.internal.statistic.eventLog.EventLogStatisticsService.send;
import static com.intellij.openapi.command.WriteCommandAction.writeCommandAction;
public class SendEventLogAction extends AnAction {
@@ -49,7 +48,7 @@ public class SendEventLogAction extends AnAction {
ProgressManager.getInstance().run(new Task.Backgroundable(project, "Send Feature Usage Event Log", false) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
final StatisticsResult result = send(FUS_RECORDER, new EventLogTestSettingsService(), new EventLogTestResultDecorator());
final StatisticsResult result = send();
final StatisticsResult.ResultCode code = result.getCode();
if (code == StatisticsResult.ResultCode.SENT_WITH_ERRORS || code == StatisticsResult.ResultCode.SEND) {
final boolean succeed = tryToOpenInScratch(project, result.getDescription());
@@ -63,12 +62,21 @@ public class SendEventLogAction extends AnAction {
StringUtil.replace(result.getDescription(), ";", "\n"),
null, null), ModalityState.NON_MODAL, project.getDisposed());
}
private StatisticsResult send() {
return EventLogStatisticsService.send(
new DeviceConfiguration(EventLogConfiguration.INSTANCE.getDeviceId(), EventLogConfiguration.INSTANCE.getBucket()),
new EventLogRecorderConfigImpl(FUS_RECORDER),
new EventLogTestSettingsService(),
new EventLogTestResultDecorator()
);
}
});
}
private static class EventLogTestSettingsService extends EventLogExternalSettingsService implements EventLogSettingsService {
private static class EventLogTestSettingsService extends EventLogUploadSettingsService implements EventLogSettingsService {
private EventLogTestSettingsService() {
super(FUS_RECORDER, true);
super(FUS_RECORDER, new EventLogTestApplication());
}
@Override
@@ -82,6 +90,12 @@ public class SendEventLogAction extends AnAction {
final FUSWhitelist whitelist = getWhitelistedGroups();
return new LogEventWhitelistFilter(whitelist != null ? whitelist : FUSWhitelist.empty());
}
}
private static class EventLogTestApplication extends EventLogApplicationImpl {
private EventLogTestApplication() {
super(true);
}
@Override
public boolean isInternal() {
@@ -3,10 +3,7 @@ package com.intellij.internal.statistic.actions;
import com.intellij.ide.scratch.RootType;
import com.intellij.ide.scratch.ScratchFileService;
import com.intellij.internal.statistic.eventLog.LogEventFilter;
import com.intellij.internal.statistic.eventLog.LogEventRecordRequest;
import com.intellij.internal.statistic.eventLog.LogEventSerializer;
import com.intellij.internal.statistic.eventLog.LogEventWhitelistFilter;
import com.intellij.internal.statistic.eventLog.*;
import com.intellij.internal.statistic.service.fus.FUSWhitelist;
import com.intellij.internal.statistic.service.fus.FUStatisticsWhiteListGroupsService;
import com.intellij.lang.Language;
@@ -212,7 +209,8 @@ public class TestParseEventLogWhitelistDialog extends DialogWrapper {
final File log = FileUtil.createTempFile("feature-event-log", ".log");
try {
FileUtil.writeToFile(log, text);
final LogEventRecordRequest request = LogEventRecordRequest.Companion.create(log, "FUS", filter, true);
final String deviceId = EventLogConfiguration.INSTANCE.getDeviceId();
final LogEventRecordRequest request = LogEventRecordRequest.Companion.create(log, "FUS", deviceId, filter, true);
if (request == null) {
throw new ParseEventLogWhitelistException("Failed parsing event log");
}
@@ -15,5 +15,6 @@
<orderEntry type="library" name="JDOM" level="project" />
<orderEntry type="library" name="Guava" level="project" />
<orderEntry type="module" module-name="intellij.platform.ide" />
<orderEntry type="module" module-name="intellij.platform.statistics.sender" exported="" />
</component>
</module>
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/annotations/18.0.0/annotations-18.0.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module" module-name="intellij.platform.util" />
<orderEntry type="module" module-name="intellij.platform.ide" />
<orderEntry type="library" name="kotlin-stdlib-jdk8" level="project" />
<orderEntry type="library" name="gson" level="project" />
<orderEntry type="library" name="JDOM" level="project" />
</component>
</module>
@@ -1,4 +1,4 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.internal.statistic.connect;
import com.intellij.openapi.diagnostic.Logger;
@@ -0,0 +1,22 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.internal.statistic.eventLog;
import org.jetbrains.annotations.NotNull;
public class DeviceConfiguration {
private String myDeviceId;
private int myBucket;
public DeviceConfiguration(@NotNull String deviceId, int bucket) {
myDeviceId = deviceId;
myBucket = bucket;
}
public String getDeviceId() {
return myDeviceId;
}
public int getBucket() {
return myBucket;
}
}
@@ -0,0 +1,10 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.internal.statistic.eventLog;
public interface EventLogApplication {
String getTemplateUrl();
boolean isInternal();
boolean isTest();
}
@@ -0,0 +1,26 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.internal.statistic.eventLog
import com.intellij.openapi.util.text.StringUtil
import java.io.File
import java.nio.file.Path
interface EventLogRecorderConfig {
fun getRecorderId(): String
fun isSendEnabled(): Boolean
fun getLogFilesProvider(): EventLogFilesProvider
}
interface EventLogFilesProvider {
fun getLogFiles(): List<EventLogFile>
}
class DefaultEventLogFilesProvider(val dir: Path, private val activeFileProvider: () -> String?): EventLogFilesProvider {
override fun getLogFiles(): List<EventLogFile> {
val activeFile = activeFileProvider()
val files = File(dir.toUri()).listFiles { f: File -> activeFile == null || !StringUtil.equals(f.name, activeFile) }
return files?.map { EventLogFile(it) }?.toList() ?: emptyList()
}
}
@@ -1,4 +1,4 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.internal.statistic.eventLog;
import com.intellij.internal.statistic.connect.StatServiceException;
@@ -27,22 +27,27 @@ public class EventLogStatisticsService implements StatisticsService {
private static final int MAX_FILES_TO_SEND = 5;
private final String myRecorder;
private final DeviceConfiguration myDeviceConfiguration;
private final EventLogSettingsService mySettingsService;
private final EventLogRecorderConfig myRecorderConfiguration;
public EventLogStatisticsService(@NotNull String recorder) {
myRecorder = recorder;
mySettingsService = new EventLogExternalSettingsService(recorder);
public EventLogStatisticsService(@NotNull DeviceConfiguration device,
@NotNull EventLogRecorderConfig config,
@NotNull EventLogApplication application) {
myDeviceConfiguration = device;
myRecorderConfiguration = config;
mySettingsService = new EventLogUploadSettingsService(config.getRecorderId(), application);
}
@Override
public StatisticsResult send() {
return send(myRecorder, mySettingsService, new EventLogCounterResultDecorator());
return send(myDeviceConfiguration, myRecorderConfiguration, mySettingsService, new EventLogCounterResultDecorator());
}
public static StatisticsResult send(@NotNull String recorder, @NotNull EventLogSettingsService settings, @NotNull EventLogResultDecorator decorator) {
final StatisticsEventLoggerProvider config = StatisticsEventLoggerKt.getEventLogProvider(recorder);
public static StatisticsResult send(@NotNull DeviceConfiguration device,
@NotNull EventLogRecorderConfig config,
@NotNull EventLogSettingsService settings,
@NotNull EventLogResultDecorator decorator) {
final List<EventLogFile> logs = getLogFiles(config);
if (!config.isSendEnabled()) {
cleanupEventLogFiles(logs);
@@ -58,7 +63,7 @@ public class EventLogStatisticsService implements StatisticsService {
return new StatisticsResult(StatisticsResult.ResultCode.ERROR_IN_CONFIG, "ERROR: unknown Statistics Service URL.");
}
if (!isSendLogsEnabled(settings.getPermittedTraffic())) {
if (!isSendLogsEnabled(device, settings.getPermittedTraffic())) {
cleanupEventLogFiles(logs);
return new StatisticsResult(StatisticsResult.ResultCode.NOT_PERMITTED_SERVER, "NOT_PERMITTED");
}
@@ -70,7 +75,8 @@ public class EventLogStatisticsService implements StatisticsService {
int size = Math.min(MAX_FILES_TO_SEND, logs.size());
for (int i = 0; i < size; i++) {
final File file = logs.get(i).getFile();
final LogEventRecordRequest recordRequest = LogEventRecordRequest.Companion.create(file, config.getRecorderId(), filter, settings.isInternal());
final String deviceId = device.getDeviceId();
final LogEventRecordRequest recordRequest = LogEventRecordRequest.Companion.create(file, config.getRecorderId(), deviceId, filter, settings.isInternal());
final String error = validate(recordRequest, file);
if (StringUtil.isNotEmpty(error) || recordRequest == null) {
if (LOG.isTraceEnabled()) {
@@ -121,7 +127,8 @@ public class EventLogStatisticsService implements StatisticsService {
}
cleanupFiles(toRemove);
EventLogSystemLogger.logFilesSend(config.getRecorderId(), logs.size(), size, failed);
//TODO: add listeners
//EventLogSystemLogger.logFilesSend(config.getRecorderId(), logs.size(), size, failed);
return decorator.toResult();
}
catch (Exception e) {
@@ -140,11 +147,11 @@ public class EventLogStatisticsService implements StatisticsService {
}
}
private static boolean isSendLogsEnabled(int percent) {
private static boolean isSendLogsEnabled(@NotNull DeviceConfiguration userData, int percent) {
if (percent == 0) {
return false;
}
return EventLogConfiguration.INSTANCE.getBucket() < percent * 2.56;
return userData.getBucket() < percent * 2.56;
}
@Nullable
@@ -175,9 +182,9 @@ public class EventLogStatisticsService implements StatisticsService {
}
@NotNull
protected static List<EventLogFile> getLogFiles(StatisticsEventLoggerProvider config) {
protected static List<EventLogFile> getLogFiles(@NotNull EventLogRecorderConfig provider) {
try {
return config.getLogFiles();
return provider.getLogFilesProvider().getLogFiles();
}
catch (Exception e) {
LOG.info(e);
@@ -0,0 +1,89 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.internal.statistic.eventLog;
import com.intellij.internal.statistic.connect.SettingsConnectionService;
import com.intellij.internal.statistic.service.fus.FUSWhitelist;
import com.intellij.internal.statistic.service.fus.FUStatisticsWhiteListGroupsService;
import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import static com.intellij.util.ObjectUtils.notNull;
public class EventLogUploadSettingsService extends SettingsConnectionService implements EventLogSettingsService {
private static final Logger LOG = Logger.getInstance(EventLogUploadSettingsService.class);
private static final String APPROVED_GROUPS_SERVICE = "white-list-service";
private static final String DICTIONARY_SERVICE = "dictionary-service";
private static final String PERCENT_TRAFFIC = "percent-traffic";
private boolean myInternal;
public EventLogUploadSettingsService(@NotNull String recorderId, @NotNull EventLogApplication application) {
super(getConfigUrl(recorderId, application.getTemplateUrl(), application.isTest()), null);
myInternal = application.isInternal();
}
@NotNull
private static String getConfigUrl(@NotNull String recorderId, @NotNull String templateUrl, boolean isTest) {
if (isTest) {
return String.format(templateUrl, "test/" + recorderId);
}
return String.format(templateUrl, recorderId);
}
@Override
public String @NotNull [] getAttributeNames() {
return ArrayUtil.mergeArrays(super.getAttributeNames(), PERCENT_TRAFFIC, APPROVED_GROUPS_SERVICE, DICTIONARY_SERVICE);
}
@Override
public int getPermittedTraffic() {
final String permitted = getSettingValue(PERCENT_TRAFFIC);
if (permitted != null) {
try {
return Integer.parseInt(permitted);
}
catch (NumberFormatException e) {
LOG.trace("Permitted traffic is not defined or has invalid format: '" + permitted + "'");
}
}
return 0;
}
@Override
@Nullable
public String getDictionaryServiceUrl() {
return getSettingValue(DICTIONARY_SERVICE);
}
@Override
@NotNull
public LogEventFilter getEventFilter() {
final FUSWhitelist whitelist = notNull(getWhitelistedGroups(), FUSWhitelist.empty());
return new LogEventCompositeFilter(new LogEventWhitelistFilter(whitelist), LogEventSnapshotBuildFilter.INSTANCE);
}
@Override
public boolean isInternal() {
return myInternal;
}
@Nullable
protected FUSWhitelist getWhitelistedGroups() {
final String productUrl = getWhiteListProductUrl();
if (productUrl == null) return null;
return FUStatisticsWhiteListGroupsService.getApprovedGroups(productUrl);
}
@NonNls
@Nullable
public String getWhiteListProductUrl() {
final String approvedGroupsServiceUrl = getSettingValue(APPROVED_GROUPS_SERVICE);
if (approvedGroupsServiceUrl == null) return null;
return approvedGroupsServiceUrl + ApplicationInfo.getInstance().getBuild().getProductCode() + ".json";
}
}
@@ -1,4 +1,4 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.internal.statistic.eventLog
import com.intellij.internal.statistic.service.fus.FUSWhitelist
@@ -16,9 +16,9 @@ class LogEventRecordRequest(val recorder: String, val product : String, val devi
private const val RECORD_SIZE = 1000 * 1000 // 1000KB
private val LOG = Logger.getInstance(LogEventRecordRequest::class.java)
fun create(file: File, recorder: String, filter: LogEventFilter, internal: Boolean): LogEventRecordRequest? {
fun create(file: File, recorder: String, deviceId: String, filter: LogEventFilter, internal: Boolean): LogEventRecordRequest? {
try {
return create(file, recorder, ApplicationInfo.getInstance().build.productCode, EventLogConfiguration.deviceId, RECORD_SIZE, filter, internal)
return create(file, recorder, ApplicationInfo.getInstance().build.productCode, deviceId, RECORD_SIZE, filter, internal)
}
catch (e: Exception) {
LOG.warn("Failed reading event log file", e)
@@ -3,8 +3,8 @@
*/
package com.intellij.internal.statistic.eventLog
import com.google.common.reflect.TypeToken
import com.google.gson.*
import com.google.gson.reflect.TypeToken
import com.intellij.openapi.diagnostic.Logger
import java.io.OutputStreamWriter
import java.lang.reflect.Type
@@ -1,9 +1,8 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.internal.statistic.service.fus;
import com.google.common.annotations.VisibleForTesting;
import com.google.gson.GsonBuilder;
import com.intellij.internal.statistic.eventLog.EventLogExternalSettingsService;
import com.intellij.internal.statistic.eventLog.EventLogUploadSettingsService;
import com.intellij.internal.statistic.service.fus.FUSWhitelist.BuildRange;
import com.intellij.internal.statistic.service.fus.FUSWhitelist.GroupFilterCondition;
import com.intellij.internal.statistic.service.fus.FUSWhitelist.VersionRange;
@@ -54,11 +53,11 @@ public class FUStatisticsWhiteListGroupsService {
}
@Nullable
public static String loadWhiteListFromServer(@NotNull EventLogExternalSettingsService settingsService) {
public static String loadWhiteListFromServer(@NotNull EventLogUploadSettingsService settingsService) {
return getFUSWhiteListContent(settingsService.getWhiteListProductUrl());
}
public static long lastModifiedWhitelist(@NotNull EventLogExternalSettingsService settingsService) {
public static long lastModifiedWhitelist(@NotNull EventLogUploadSettingsService settingsService) {
return lastModifiedWhitelist(settingsService.getWhiteListProductUrl());
}
@@ -105,7 +104,6 @@ public class FUStatisticsWhiteListGroupsService {
return groups;
}
@VisibleForTesting
@NotNull
public static FUSWhitelist parseApprovedGroups(@Nullable String content) {
final WLGroups groups = parseWhiteListContent(content);
@@ -0,0 +1,28 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.internal.statistic.eventLog;
import com.intellij.internal.statistic.utils.StatisticsUploadAssistant;
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
public class EventLogApplicationImpl implements EventLogApplication {
private boolean myIsTest;
public EventLogApplicationImpl(boolean isTest) {
myIsTest = isTest;
}
@Override
public String getTemplateUrl() {
return ((ApplicationInfoImpl)ApplicationInfoImpl.getShadowInstance()).getEventLogSettingsUrl();
}
@Override
public boolean isInternal() {
return StatisticsUploadAssistant.isTestStatisticsEnabled();
}
@Override
public boolean isTest() {
return myIsTest;
}
}
@@ -1,26 +1,18 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.internal.statistic.eventLog;
import com.intellij.internal.statistic.connect.SettingsConnectionService;
import com.intellij.internal.statistic.service.fus.FUSWhitelist;
import com.intellij.internal.statistic.service.fus.FUStatisticsWhiteListGroupsService;
import com.intellij.internal.statistic.utils.StatisticsUploadAssistant;
import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.BuildNumber;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import static com.intellij.util.ObjectUtils.notNull;
public class EventLogExternalSettingsService extends SettingsConnectionService implements EventLogSettingsService {
private static final Logger LOG = Logger.getInstance(EventLogExternalSettingsService.class);
private static final String APPROVED_GROUPS_SERVICE = "white-list-service";
private static final String DICTIONARY_SERVICE = "dictionary-service";
private static final String PERCENT_TRAFFIC = "percent-traffic";
/**
* This class is a wrapper around {@link EventLogUploadSettingsService} it isn't deleted yet for backward compatibility.
*
* @deprecated Use {@link EventLogUploadSettingsService} directly.
*/
@Deprecated
public class EventLogExternalSettingsService extends EventLogUploadSettingsService {
public EventLogExternalSettingsService(@NotNull String recorderId) {
super(recorderId, new EventLogApplicationImpl(false));
}
/**
* @deprecated Use {@link EventLogExternalSettingsService#getFeatureUsageSettings()} or create new instance with custom recorder id.
@@ -34,77 +26,4 @@ public class EventLogExternalSettingsService extends SettingsConnectionService i
public static EventLogExternalSettingsService getFeatureUsageSettings() {
return new EventLogExternalSettingsService("FUS");
}
public EventLogExternalSettingsService(@NotNull String recorderId) {
super(getConfigUrl(recorderId, false), null);
}
public EventLogExternalSettingsService(@NotNull String recorderId, boolean isTest) {
super(getConfigUrl(recorderId, isTest), null);
}
@NotNull
private static String getConfigUrl(@NotNull String recorderId, boolean isTest) {
final String templateUrl = ((ApplicationInfoImpl)ApplicationInfoImpl.getShadowInstance()).getEventLogSettingsUrl();
if (isTest) {
return String.format(templateUrl, "test/" + recorderId);
}
return String.format(templateUrl, recorderId);
}
@Override
public String @NotNull [] getAttributeNames() {
return ArrayUtil.mergeArrays(super.getAttributeNames(), PERCENT_TRAFFIC, APPROVED_GROUPS_SERVICE, DICTIONARY_SERVICE);
}
@Override
public int getPermittedTraffic() {
final String permitted = getSettingValue(PERCENT_TRAFFIC);
if (permitted != null) {
try {
return Integer.parseInt(permitted);
}
catch (NumberFormatException e) {
LOG.trace("Permitted traffic is not defined or has invalid format: '" + permitted + "'");
}
}
return 0;
}
@Override
@Nullable
public String getDictionaryServiceUrl() {
return getSettingValue(DICTIONARY_SERVICE);
}
@Override
@NotNull
public LogEventFilter getEventFilter() {
final FUSWhitelist whitelist = notNull(getWhitelistedGroups(), FUSWhitelist.empty());
return new LogEventCompositeFilter(new LogEventWhitelistFilter(whitelist), LogEventSnapshotBuildFilter.INSTANCE);
}
@Override
public boolean isInternal() {
return StatisticsUploadAssistant.isTestStatisticsEnabled();
}
@Nullable
protected FUSWhitelist getWhitelistedGroups() {
final String productUrl = getWhiteListProductUrl();
if (productUrl == null) return null;
return FUStatisticsWhiteListGroupsService.getApprovedGroups(productUrl);
}
@Nullable
public String getWhiteListProductUrl() {
final String approvedGroupsServiceUrl = getSettingValue(APPROVED_GROUPS_SERVICE);
if (approvedGroupsServiceUrl == null) return null;
return approvedGroupsServiceUrl + ApplicationInfo.getInstance().getBuild().getProductCode() + ".json";
}
@NotNull
private static BuildNumber getCurrentBuild() {
return BuildNumber.fromString(EventLogConfiguration.INSTANCE.getBuild());
}
}
}
@@ -12,7 +12,7 @@ class EventLogNotificationProxy(private val writer: StatisticsEventLogWriter,
override fun getActiveFile(): EventLogFile? = writer.getActiveFile()
override fun getFiles(): List<EventLogFile> = writer.getFiles()
override fun getLogFilesProvider(): EventLogFilesProvider = writer.getLogFilesProvider()
override fun cleanup() = writer.cleanup()
@@ -0,0 +1,29 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.internal.statistic.eventLog;
import org.jetbrains.annotations.NotNull;
public class EventLogRecorderConfigImpl implements EventLogRecorderConfig {
private String myRecorderId;
public EventLogRecorderConfigImpl(@NotNull String recorderId) {
myRecorderId = recorderId;
}
@NotNull
@Override
public String getRecorderId() {
return myRecorderId;
}
@Override
public boolean isSendEnabled() {
return StatisticsEventLoggerKt.getEventLogProvider(myRecorderId).isSendEnabled();
}
@NotNull
@Override
public EventLogFilesProvider getLogFilesProvider() {
return StatisticsEventLoggerKt.getEventLogProvider(myRecorderId).getLogFilesProvider();
}
}
@@ -16,7 +16,7 @@ interface StatisticsEventLogWriter {
fun getActiveFile(): EventLogFile?
fun getFiles(): List<EventLogFile>
fun getLogFilesProvider(): EventLogFilesProvider
fun cleanup()
@@ -68,10 +68,8 @@ class StatisticsEventLogFileWriter(private val recorderId: String,
return EventLogFile(File(File(getEventLogDir().toUri()), activeLog))
}
override fun getFiles(): List<EventLogFile> {
val activeLog = fileAppender?.activeLogName
val files = File(getEventLogDir().toUri()).listFiles { f: File -> !StringUtil.equals(f.name, activeLog) }
return files?.map { EventLogFile(it) }?.toList() ?: emptyList()
override fun getLogFilesProvider(): EventLogFilesProvider {
return DefaultEventLogFilesProvider(getEventLogDir()) { fileAppender?.activeLogName }
}
override fun cleanup() {
@@ -14,7 +14,7 @@ interface StatisticsEventLogger {
fun log(group: EventLogGroup, eventId: String, isState: Boolean)
fun log(group: EventLogGroup, eventId: String, data: Map<String, Any>, isState: Boolean)
fun getActiveLogFile(): EventLogFile?
fun getLogFiles(): List<EventLogFile>
fun getLogFilesProvider(): EventLogFilesProvider
fun cleanup()
fun rollOver()
}
@@ -32,8 +32,8 @@ abstract class StatisticsEventLoggerProvider(val recorderId: String,
return logger.getActiveLogFile()
}
fun getLogFiles(): List<EventLogFile> {
return logger.getLogFiles()
fun getLogFilesProvider(): EventLogFilesProvider {
return logger.getLogFilesProvider()
}
private fun createLogger(): StatisticsEventLogger {
@@ -62,11 +62,15 @@ internal class EmptyStatisticsEventLogger : StatisticsEventLogger {
override fun log(group: EventLogGroup, eventId: String, isState: Boolean) = Unit
override fun log(group: EventLogGroup, eventId: String, data: Map<String, Any>, isState: Boolean) = Unit
override fun getActiveLogFile(): EventLogFile? = null
override fun getLogFiles(): List<EventLogFile> = emptyList()
override fun getLogFilesProvider(): EventLogFilesProvider = EmptyEventLogFilesProvider
override fun cleanup() = Unit
override fun rollOver() = Unit
}
object EmptyEventLogFilesProvider: EventLogFilesProvider {
override fun getLogFiles(): List<EventLogFile> = emptyList()
}
fun getEventLogProviders(): List<StatisticsEventLoggerProvider> {
return EP_NAME.extensionsIfPointIsRegistered
}
@@ -69,8 +69,8 @@ open class StatisticsFileEventLogger(private val recorderId: String,
return writer.getActiveFile()
}
override fun getLogFiles(): List<EventLogFile> {
return writer.getFiles()
override fun getLogFilesProvider(): EventLogFilesProvider {
return writer.getLogFilesProvider()
}
override fun cleanup() {
@@ -1,8 +1,9 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.internal.statistic.eventLog.validator.persistence;
import com.intellij.internal.statistic.eventLog.EventLogExternalSettingsService;
import com.intellij.internal.statistic.eventLog.EventLogUploadSettingsService;
import com.intellij.internal.statistic.service.fus.FUStatisticsWhiteListGroupsService;
import com.intellij.internal.statistic.utils.StatisticsUploadAssistant;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
@@ -22,11 +23,11 @@ public class EventLogWhitelistPersistence extends BaseEventLogWhitelistPersisten
@NotNull
private final String myRecorderId;
@NotNull
private final EventLogExternalSettingsService mySettingsService;
private final EventLogUploadSettingsService mySettingsService;
public EventLogWhitelistPersistence(@NotNull String recorderId) {
myRecorderId = recorderId;
mySettingsService = new EventLogExternalSettingsService(recorderId);
mySettingsService = StatisticsUploadAssistant.createExternalSettings(recorderId, false);
}
@Override
@@ -2,7 +2,7 @@
package com.intellij.internal.statistic.utils;
import com.intellij.internal.statistic.connect.StatisticsService;
import com.intellij.internal.statistic.eventLog.EventLogStatisticsService;
import com.intellij.internal.statistic.eventLog.*;
import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
@@ -13,7 +13,7 @@ public class StatisticsUploadAssistant {
public static final Object LOCK = new Object();
private StatisticsUploadAssistant(){}
private StatisticsUploadAssistant() {}
public static long getSendPeriodInMillis() {
return UsageStatisticsPersistenceComponent.getInstance().getPeriod().getMillis();
@@ -54,6 +54,14 @@ public class StatisticsUploadAssistant {
@NotNull
public static StatisticsService getEventLogStatisticsService(@NotNull String recorderId) {
return new EventLogStatisticsService(recorderId);
return new EventLogStatisticsService(
new DeviceConfiguration(EventLogConfiguration.INSTANCE.getDeviceId(), EventLogConfiguration.INSTANCE.getBucket()),
new EventLogRecorderConfigImpl(recorderId),
new EventLogApplicationImpl(false)
);
}
public static EventLogUploadSettingsService createExternalSettings(@NotNull String recorderId, boolean isTest) {
return new EventLogUploadSettingsService(recorderId, new EventLogApplicationImpl(isTest));
}
}