FUS: add plugin information to action collector context

This commit is contained in:
Svetlana.Zemlyanskaya
2019-01-19 18:31:48 +01:00
parent 85ed2a9427
commit 6b050dec83
3 changed files with 103 additions and 30 deletions
@@ -2,22 +2,21 @@
package com.intellij.internal.statistic.collectors.fus.actions.persistence;
import com.intellij.ide.actions.ActionsCollector;
import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.internal.statistic.beans.ConvertUsagesUtil;
import com.intellij.internal.statistic.collectors.fus.ui.persistence.ShortcutsCollector;
import com.intellij.internal.statistic.eventLog.FeatureUsageDataBuilder;
import com.intellij.internal.statistic.eventLog.FeatureUsageGroup;
import com.intellij.internal.statistic.eventLog.FeatureUsageLogger;
import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent;
import com.intellij.internal.statistic.service.fus.collectors.FUSUsageContext;
import com.intellij.internal.statistic.utils.PluginInfo;
import com.intellij.internal.statistic.utils.StatisticsUtilKt;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.RoamingType;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -31,7 +30,7 @@ import java.util.Map;
value = UsageStatisticsPersistenceComponent.USAGE_STATISTICS_XML, roamingType = RoamingType.DISABLED, deprecated = true)
)
public class ActionsCollectorImpl extends ActionsCollector implements PersistentStateComponent<ActionsCollector.State> {
private static final FeatureUsageGroup GROUP = new FeatureUsageGroup("actions.v2", 1);
private static final FeatureUsageGroup GROUP = new FeatureUsageGroup("actions", 1);
private static final String DEFAULT_ID = "third.party.plugin.action";
private static final HashMap<String, String> ourPrefixesBlackList = new HashMap<>();
@@ -51,19 +50,24 @@ public class ActionsCollectorImpl extends ActionsCollector implements Persistent
boolean isContextMenu = event != null && event.isFromContextMenu();
final String place = event != null ? event.getPlace() : "";
final boolean isDevelopedByJB = isDevelopedByJetBrains(context);
String key = isDevelopedByJB ? toReportedId(actionId) : DEFAULT_ID;
final Map<String, Object> data = ContainerUtil.newHashMap(FUSUsageContext.OS_CONTEXT.getData());
data.put("context_menu", isContextMenu);
final PluginInfo info = StatisticsUtilKt.getPluginInfo(context);
final FeatureUsageDataBuilder builder = new FeatureUsageDataBuilder().
addFeatureContext(FUSUsageContext.OS_CONTEXT).
addPluginInfo(info).
addData("context_menu", isContextMenu);
final boolean isDevelopedByJB = info.getType().isDevelopedByJetBrains();
if (isContextMenu && isDevelopedByJB) {
data.put("place", place);
builder.addPlace(place);
}
final String inputEvent = ShortcutsCollector.getInputEventText(event);
if (StringUtil.isNotEmpty(inputEvent)) {
data.put("input_event", inputEvent);
builder.addData("input_event", inputEvent);
}
FeatureUsageLogger.INSTANCE.log(GROUP, key, data);
final String key = isDevelopedByJB ? toReportedId(actionId) : DEFAULT_ID;
FeatureUsageLogger.INSTANCE.log(GROUP, key, builder.createData());
}
@NotNull
@@ -77,11 +81,6 @@ public class ActionsCollectorImpl extends ActionsCollector implements Persistent
return key;
}
private static boolean isDevelopedByJetBrains(@NotNull Class aClass) {
final PluginId pluginId = PluginManagerCore.getPluginByClassName(aClass.getName());
return StatisticsUtilKt.isDevelopedByJetBrains(pluginId);
}
private State myState = new State();
@Nullable
@@ -0,0 +1,56 @@
// 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
import com.intellij.internal.statistic.service.fus.collectors.FUSUsageContext
import com.intellij.internal.statistic.utils.PluginInfo
import com.intellij.internal.statistic.utils.getProjectId
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.text.StringUtil
import com.intellij.util.containers.ContainerUtil
import java.util.*
class FeatureUsageDataBuilder {
private var data: MutableMap<String, Any> = ContainerUtil.newHashMap<String, Any>()
fun addFeatureContext(context: FUSUsageContext?): FeatureUsageDataBuilder {
if (context != null) {
data.putAll(context.data)
}
return this
}
fun addProject(project: Project?): FeatureUsageDataBuilder {
if (project != null) {
data["project"] = getProjectId(project)
}
return this
}
fun addPluginInfo(info: PluginInfo): FeatureUsageDataBuilder {
data["plugin_type"] = info.type.name
if (info.type.isSafeToReport() && info.id != null && StringUtil.isNotEmpty(info.id)) {
data["plugin"] = info.id
}
return this
}
fun addPlace(place: String): FeatureUsageDataBuilder {
data["place"] = place
return this
}
fun addData(key: String, value: Any): FeatureUsageDataBuilder {
data[key] = value
return this
}
fun createData(): Map<String, Any> {
return data
}
}
fun newData(project: Project?, context: FUSUsageContext?): Map<String, Any> {
if (project == null && context == null) return Collections.emptyMap()
return FeatureUsageDataBuilder().addProject(project).addFeatureContext(context).createData()
}
@@ -4,6 +4,7 @@ package com.intellij.internal.statistic.utils
import com.intellij.ide.plugins.*
import com.intellij.internal.statistic.beans.UsageDescriptor
import com.intellij.internal.statistic.eventLog.EventLogConfiguration
import com.intellij.internal.statistic.eventLog.newData
import com.intellij.internal.statistic.service.fus.collectors.FUSUsageContext
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ex.ApplicationInfoEx
@@ -28,17 +29,7 @@ fun getProjectId(project: Project): String {
}
fun createData(project: Project?, context: FUSUsageContext?): Map<String, Any> {
if (project == null && context == null) return Collections.emptyMap()
val data = ContainerUtil.newHashMap<String, Any>()
if (context != null) {
data.putAll(context.data)
}
if (project != null) {
data["project"] = getProjectId(project)
}
return data
return newData(project, context)
}
fun mergeWithEventData(data: Map<String, Any>, context: FUSUsageContext?, value : Int): Map<String, Any> {
@@ -295,22 +286,49 @@ fun getPluginType(clazz: Class<*>): PluginType {
return if (listed) PluginType.LISTED else PluginType.NOT_LISTED
}
fun getPluginInfo(clazz: Class<*>): PluginInfo {
val pluginId = PluginManagerCore.getPluginByClassName(clazz.name) ?: return PluginInfo(PluginType.PLATFORM, null)
val plugin = PluginManager.getPlugin(pluginId) ?: return PluginInfo(PluginType.UNKNOWN, null)
val id = plugin.pluginId.idString
if (PluginManagerMain.isDevelopedByJetBrains(plugin)) {
return if (plugin.isBundled) {
PluginInfo(PluginType.JB_BUNDLED, id)
}
else {
PluginInfo(PluginType.JB_NOT_BUNDLED, id)
}
}
// only plugins installed from some repository (not bundled and not provided via classpath in development IDE instance -
// they are also considered bundled) would be reported
val listed = !plugin.isBundled && isSafeToReport(pluginId.idString)
return if (listed) {
PluginInfo(PluginType.LISTED, id)
}
else {
PluginInfo(PluginType.NOT_LISTED, null)
}
}
enum class PluginType {
PLATFORM, JB_BUNDLED, JB_NOT_BUNDLED, LISTED, NOT_LISTED, UNKNOWN;
fun isPlatformOrJBBundled() : Boolean {
fun isPlatformOrJBBundled(): Boolean {
return this == PLATFORM || this == JB_BUNDLED
}
fun isDevelopedByJetBrains() : Boolean {
fun isDevelopedByJetBrains(): Boolean {
return isPlatformOrJBBundled() || this == JB_NOT_BUNDLED
}
fun isSafeToReport() : Boolean {
fun isSafeToReport(): Boolean {
return isDevelopedByJetBrains() || this == LISTED;
}
}
class PluginInfo(val type: PluginType, val id: String?)
private class DelayModificationTracker internal constructor(delay: Long, unit: TimeUnit) : ModificationTracker {
private val myStamp = System.currentTimeMillis()