mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-CR-62611: IDEA-237602 Report settings when they are changed
GitOrigin-RevId: 1997fbe84fa451e0f906d4eb441097bb8b2a3166
This commit is contained in:
committed by
intellij-monorepo-bot
parent
89873c8d4f
commit
ecd5ac3f6e
@@ -202,7 +202,7 @@ abstract class ComponentStoreImpl : IComponentStore {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
var modificationCountChanged = false
|
||||
if (info.isModificationTrackingSupported) {
|
||||
currentModificationCount = info.currentModificationCount
|
||||
if (currentModificationCount == info.lastModificationCount) {
|
||||
@@ -211,9 +211,12 @@ abstract class ComponentStoreImpl : IComponentStore {
|
||||
continue
|
||||
}
|
||||
}
|
||||
else {
|
||||
modificationCountChanged = true
|
||||
}
|
||||
}
|
||||
|
||||
commitComponent(session, info, name)
|
||||
commitComponent(session, info, name, modificationCountChanged)
|
||||
info.updateModificationCount(currentModificationCount)
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
@@ -243,7 +246,7 @@ abstract class ComponentStoreImpl : IComponentStore {
|
||||
val stateSpec = getStateSpec(component)
|
||||
LOG.debug { "saveComponent is called for ${stateSpec.name}" }
|
||||
val saveManager = createSaveSessionProducerManager()
|
||||
commitComponent(saveManager, ComponentInfoImpl(component, stateSpec), null)
|
||||
commitComponent(saveManager, ComponentInfoImpl(component, stateSpec), null, false)
|
||||
val absolutePath = Paths.get(storageManager.expandMacros(findNonDeprecated(getStorageSpecs(component, stateSpec, StateStorageOperation.WRITE)).path)).toAbsolutePath().toString()
|
||||
Disposer.newDisposable().use {
|
||||
VfsRootAccess.allowRootAccess(it, absolutePath)
|
||||
@@ -260,7 +263,10 @@ abstract class ComponentStoreImpl : IComponentStore {
|
||||
|
||||
open fun createSaveSessionProducerManager() = SaveSessionProducerManager()
|
||||
|
||||
private fun commitComponent(session: SaveSessionProducerManager, info: ComponentInfo, componentName: String?) {
|
||||
private fun commitComponent(session: SaveSessionProducerManager,
|
||||
info: ComponentInfo,
|
||||
componentName: String?,
|
||||
modificationCountChanged: Boolean) {
|
||||
val component = info.component
|
||||
@Suppress("DEPRECATION")
|
||||
if (component is com.intellij.openapi.util.JDOMExternalizable) {
|
||||
@@ -306,6 +312,12 @@ abstract class ComponentStoreImpl : IComponentStore {
|
||||
state = (info.component as PersistentStateComponent<*>).state
|
||||
}
|
||||
|
||||
if (modificationCountChanged && stateSpec.reportStatistic && state != null) {
|
||||
LOG.runAndLogException {
|
||||
FeatureUsageSettingsEvents.logConfigurationChanged(effectiveComponentName, state, project)
|
||||
}
|
||||
}
|
||||
|
||||
setStateToSaveSessionProducer(state, info, effectiveComponentName, sessionProducer)
|
||||
}
|
||||
}
|
||||
|
||||
+137
-95
@@ -3,23 +3,24 @@ package com.intellij.configurationStore.statistic.eventLog
|
||||
|
||||
import com.intellij.configurationStore.jdomSerializer
|
||||
import com.intellij.internal.statistic.eventLog.EventLogGroup
|
||||
import com.intellij.internal.statistic.eventLog.FeatureUsageData
|
||||
import com.intellij.internal.statistic.eventLog.fus.FeatureUsageLogger
|
||||
import com.intellij.internal.statistic.service.fus.collectors.FUCounterUsageLogger
|
||||
import com.intellij.internal.statistic.utils.PluginInfo
|
||||
import com.intellij.internal.statistic.utils.StatisticsUtil
|
||||
import com.intellij.internal.statistic.utils.addPluginInfoTo
|
||||
import com.intellij.internal.statistic.utils.getPluginInfo
|
||||
import com.intellij.openapi.components.ReportValue
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.serialization.MutableAccessor
|
||||
import com.intellij.util.concurrency.NonUrgentExecutor
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import com.intellij.util.xmlb.Accessor
|
||||
import com.intellij.util.xmlb.BeanBinding
|
||||
import org.jdom.Element
|
||||
import java.util.*
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
private val LOG = Logger.getInstance("com.intellij.configurationStore.statistic.eventLog.FeatureUsageSettingsEventPrinter")
|
||||
private val GROUP = EventLogGroup("settings", 5)
|
||||
private val GROUP = EventLogGroup("settings", 6)
|
||||
private const val CHANGES_GROUP = "settings.changes"
|
||||
|
||||
private val recordedComponents: MutableSet<String> = ContainerUtil.newConcurrentSet()
|
||||
private val recordedOptionNames: MutableSet<String> = ContainerUtil.newConcurrentSet()
|
||||
@@ -50,20 +51,31 @@ internal object FeatureUsageSettingsEvents {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun logConfigurationChanged(componentName: String, state: Any, project: Project?) {
|
||||
NonUrgentExecutor.getInstance().execute {
|
||||
if (FeatureUsageLogger.isEnabled()) {
|
||||
printer.logConfigurationStateChanged(componentName, state, project)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open class FeatureUsageSettingsEventPrinter(private val recordDefault: Boolean) {
|
||||
private val valuesExtractor = ConfigurationStateExtractor(recordDefault)
|
||||
|
||||
fun logDefaultConfigurationState(componentName: String, clazz: Class<*>, project: Project?) {
|
||||
try {
|
||||
if (recordDefault) {
|
||||
val default = jdomSerializer.getDefaultSerializationFilter().getDefaultValue(clazz)
|
||||
logConfigurationState(componentName, default, project)
|
||||
}
|
||||
else if (clazz != Element::class.java && getPluginInfo(clazz).isDevelopedByJetBrains()) {
|
||||
recordedComponents.add(componentName)
|
||||
val isDefaultProject = project?.isDefault == true
|
||||
val hash = if (!isDefaultProject) toHash(project) else null
|
||||
logSettingCollectorWasInvoked(componentName, isDefaultProject, hash)
|
||||
else if (clazz != Element::class.java) {
|
||||
val pluginInfo = getPluginInfo(clazz)
|
||||
if (pluginInfo.isDevelopedByJetBrains()) {
|
||||
recordedComponents.add(componentName)
|
||||
logConfig(GROUP, "invoked", createComponentData(project, componentName, pluginInfo))
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e: Exception) {
|
||||
@@ -71,118 +83,148 @@ open class FeatureUsageSettingsEventPrinter(private val recordDefault: Boolean)
|
||||
}
|
||||
}
|
||||
|
||||
fun logConfigurationStateChanged(componentName: String, state: Any?, project: Project?) {
|
||||
val (optionsValues, pluginInfo) = valuesExtractor.extract(project, componentName, state) ?: return
|
||||
val id = counter.incrementAndGet()
|
||||
for (data in optionsValues) {
|
||||
logSettingsChanged("component_changed_option", data, id)
|
||||
}
|
||||
|
||||
if (!recordDefault) {
|
||||
logSettingsChanged("component_changed", createComponentData(project, componentName, pluginInfo), id)
|
||||
}
|
||||
}
|
||||
|
||||
fun logConfigurationState(componentName: String, state: Any?, project: Project?) {
|
||||
val (optionsValues, pluginInfo) = valuesExtractor.extract(project, componentName, state) ?: return
|
||||
val eventId = if (recordDefault) "option" else "not.default"
|
||||
for (data in optionsValues) {
|
||||
logConfig(GROUP, eventId, data)
|
||||
}
|
||||
|
||||
if (!recordDefault) {
|
||||
logConfig(GROUP, "invoked", createComponentData(project, componentName, pluginInfo))
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun logConfig(group: EventLogGroup, eventId: String, data: FeatureUsageData) {
|
||||
FeatureUsageLogger.logState(group, eventId, data.build())
|
||||
}
|
||||
|
||||
protected open fun logSettingsChanged(eventId: String, data: FeatureUsageData, id: Int) {
|
||||
FUCounterUsageLogger.getInstance().logEvent(CHANGES_GROUP, eventId, data.addData("id", id))
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val counter = AtomicInteger(0)
|
||||
|
||||
fun createComponentData(project: Project?, componentName: String, pluginInfo: PluginInfo): FeatureUsageData {
|
||||
val data = FeatureUsageData()
|
||||
.addData("component", componentName)
|
||||
.addPluginInfo(pluginInfo)
|
||||
if (project?.isDefault == true) {
|
||||
data.addData("default_project", true)
|
||||
}
|
||||
else {
|
||||
data.addProject(project)
|
||||
}
|
||||
return data
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal data class ConfigurationState(val optionsValues: List<FeatureUsageData>, val pluginInfo: PluginInfo)
|
||||
|
||||
internal data class ConfigurationStateExtractor(val recordDefault: Boolean) {
|
||||
internal fun extract(project: Project?, componentName: String, state: Any?): ConfigurationState? {
|
||||
if (state == null || state is Element) {
|
||||
return
|
||||
return null
|
||||
}
|
||||
|
||||
val pluginInfo = getPluginInfo(state.javaClass)
|
||||
if (!pluginInfo.isDevelopedByJetBrains()) {
|
||||
return
|
||||
return null
|
||||
}
|
||||
|
||||
val accessors = BeanBinding.getAccessors(state.javaClass)
|
||||
if (accessors.isEmpty()) {
|
||||
return
|
||||
return null
|
||||
}
|
||||
|
||||
recordedComponents.add(componentName)
|
||||
val eventId = if (recordDefault) "option" else "not.default"
|
||||
val isDefaultProject = project?.isDefault == true
|
||||
val hash = if (!isDefaultProject) toHash(project) else null
|
||||
|
||||
for (accessor in accessors) {
|
||||
val type = accessor.genericType
|
||||
if (type === Boolean::class.javaPrimitiveType) {
|
||||
logConfigValue(accessor, state, "bool", eventId, isDefaultProject, true, hash, componentName, pluginInfo)
|
||||
}
|
||||
else if (type === Int::class.javaPrimitiveType || type === Long::class.javaPrimitiveType) {
|
||||
logConfigValue(accessor, state, "int", eventId, isDefaultProject, shouldReportValue(accessor), hash, componentName, pluginInfo)
|
||||
}
|
||||
else if (type === Float::class.javaPrimitiveType || type === Double::class.javaPrimitiveType) {
|
||||
logConfigValue(accessor, state, "float", eventId, isDefaultProject, shouldReportValue(accessor), hash, componentName, pluginInfo)
|
||||
}
|
||||
else if (type is Class<*> && type.isEnum) {
|
||||
logConfigValue(accessor, state, "enum", eventId, isDefaultProject, shouldReportValue(accessor), hash, componentName, pluginInfo) {
|
||||
(it as? Enum<*>)?.name
|
||||
}
|
||||
}
|
||||
else if (type == String::class.java) {
|
||||
val annotation = accessor.getAnnotation(ReportValue::class.java)
|
||||
logConfigValue(accessor, state, "string", eventId, isDefaultProject, shouldReportValue(accessor), hash, componentName, pluginInfo) {
|
||||
if (it in annotation.possibleValues) it else null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!recordDefault) {
|
||||
logSettingCollectorWasInvoked(componentName, isDefaultProject, hash)
|
||||
}
|
||||
val optionsValues = accessors.mapNotNull { extractOptionValue(project, it, state, componentName, pluginInfo) }
|
||||
return ConfigurationState(optionsValues, pluginInfo)
|
||||
}
|
||||
|
||||
private fun shouldReportValue(accessor: MutableAccessor): Boolean = accessor.getAnnotation(ReportValue::class.java) != null
|
||||
|
||||
private fun logConfigValue(accessor: MutableAccessor,
|
||||
state: Any,
|
||||
type: String,
|
||||
eventId: String,
|
||||
isDefaultProject: Boolean,
|
||||
reportValue: Boolean,
|
||||
hash: String?,
|
||||
componentName: String,
|
||||
pluginInfo: PluginInfo,
|
||||
transformValue: ((Any?) -> Any?)? = null) {
|
||||
private fun extractOptionValue(project: Project?,
|
||||
accessor: Accessor,
|
||||
state: Any,
|
||||
componentName: String,
|
||||
pluginInfo: PluginInfo): FeatureUsageData? {
|
||||
val isDefault = !jdomSerializer.getDefaultSerializationFilter().accepts(accessor, state)
|
||||
if (!isDefault || recordDefault) {
|
||||
val data = FeatureUsageSettingsEventPrinter.createComponentData(project, componentName, pluginInfo)
|
||||
recordedOptionNames.add(accessor.name)
|
||||
val content = HashMap<String, Any>()
|
||||
content["type"] = type
|
||||
content["component"] = componentName
|
||||
content["name"] = accessor.name
|
||||
if (reportValue) {
|
||||
val value = accessor.readUnsafe(state)
|
||||
val transformedValue = if (transformValue != null) transformValue(value) else value
|
||||
if (transformedValue != null) {
|
||||
content["value"] = transformedValue
|
||||
data.addData("name", accessor.name)
|
||||
if (tryAddTypedValue(data, accessor, state)) {
|
||||
if (recordDefault) {
|
||||
data.addData("default", isDefault)
|
||||
}
|
||||
}
|
||||
if (recordDefault) {
|
||||
content["default"] = isDefault
|
||||
}
|
||||
addProjectOptions(content, isDefaultProject, hash)
|
||||
addPluginInfoTo(pluginInfo, content)
|
||||
logConfig(GROUP, eventId, content)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addProjectOptions(content: HashMap<String, Any>,
|
||||
isDefaultProject: Boolean,
|
||||
projectHash: String?) {
|
||||
if (isDefaultProject) {
|
||||
content["default_project"] = true
|
||||
}
|
||||
else {
|
||||
projectHash?.let {
|
||||
content["project"] = projectHash
|
||||
return data
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
@Suppress("SameParameterValue")
|
||||
protected open fun logConfig(group: EventLogGroup, eventId: String, data: Map<String, Any>) {
|
||||
FeatureUsageLogger.logState(group, eventId, data)
|
||||
private fun tryAddTypedValue(data: FeatureUsageData, accessor: Accessor, state: Any): Boolean {
|
||||
val type = accessor.genericType
|
||||
when {
|
||||
type === Boolean::class.javaPrimitiveType -> {
|
||||
data.addData("type", "bool")
|
||||
val value = accessor.readUnsafe(state) as? Boolean
|
||||
value?.let { data.addData("value", it) }
|
||||
}
|
||||
type === Int::class.javaPrimitiveType -> addValue<Int>(data, accessor, state, "int") { data.addData("value", it) }
|
||||
type === Long::class.javaPrimitiveType -> addValue<Long>(data, accessor, state, "int") { data.addData("value", it) }
|
||||
type === Float::class.javaPrimitiveType -> addValue<Float>(data, accessor, state, "float") { data.addData("value", it) }
|
||||
type === Double::class.javaPrimitiveType -> addValue<Double>(data, accessor, state, "float") { data.addData("value", it) }
|
||||
type is Class<*> && type.isEnum -> {
|
||||
data.addData("type", "enum")
|
||||
readValue(accessor, state) { (it as? Enum<*>)?.name }?.let { data.addData("value", it) }
|
||||
}
|
||||
type == String::class.java -> {
|
||||
data.addData("type", "string")
|
||||
val value = readValue(accessor, state) { value ->
|
||||
if (value is String && value in accessor.getAnnotation(ReportValue::class.java).possibleValues) {
|
||||
value
|
||||
}
|
||||
else null
|
||||
}
|
||||
value?.let { data.addData("value", it) }
|
||||
}
|
||||
else -> return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun logSettingCollectorWasInvoked(componentName: String, isDefaultProject: Boolean, projectHash: String?) {
|
||||
val content = HashMap<String, Any>()
|
||||
content["component"] = componentName
|
||||
addProjectOptions(content, isDefaultProject, projectHash)
|
||||
logConfig(GROUP, "invoked", content)
|
||||
private inline fun <reified T> readValue(accessor: Accessor, state: Any, noinline transformValue: ((Any?) -> T?)? = null): T? {
|
||||
if (accessor.getAnnotation(ReportValue::class.java) != null) {
|
||||
val value = accessor.readUnsafe(state)
|
||||
return if (transformValue != null) {
|
||||
transformValue(value)
|
||||
}
|
||||
else {
|
||||
value as? T
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
internal fun toHash(project: Project?): String? {
|
||||
return project?.let {
|
||||
return StatisticsUtil.getProjectId(project)
|
||||
private inline fun <reified T> addValue(data: FeatureUsageData, accessor: Accessor, state: Any, type: String, add: (T) -> Unit) {
|
||||
data.addData("type", type)
|
||||
val value = readValue<T>(accessor, state)
|
||||
if (value != null) {
|
||||
add(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+66
-15
@@ -1,9 +1,10 @@
|
||||
// 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.configurationStore.statistics.eventLog
|
||||
|
||||
import com.intellij.configurationStore.getStateSpec
|
||||
import com.intellij.configurationStore.statistic.eventLog.FeatureUsageSettingsEventPrinter
|
||||
import com.intellij.internal.statistic.eventLog.EventLogGroup
|
||||
import com.intellij.internal.statistic.eventLog.FeatureUsageData
|
||||
import com.intellij.openapi.components.PersistentStateComponent
|
||||
import com.intellij.openapi.components.ReportValue
|
||||
import com.intellij.openapi.components.State
|
||||
@@ -23,18 +24,6 @@ class FeatureUsageSettingsEventsTest {
|
||||
val projectRule = ProjectRule()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `project name to hash`() {
|
||||
val printer = TestFeatureUsageSettingsEventsPrinter(true)
|
||||
assertThat(printer.toHash(projectRule.project)).isNotNull
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `no project name to hash`() {
|
||||
val printer = TestFeatureUsageSettingsEventsPrinter(true)
|
||||
assertThat(printer.toHash(null)).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `record all default application component with enabled default recording`() {
|
||||
val component = TestComponent()
|
||||
@@ -402,6 +391,54 @@ class FeatureUsageSettingsEventsTest {
|
||||
"string", recordDefault, withProject, defaultProject)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `same project hash in invoke and state action`() {
|
||||
val component = TestComponent()
|
||||
component.loadState(ComponentState(bool = true))
|
||||
val printer = TestFeatureUsageSettingsEventsPrinter(false)
|
||||
printer.logConfigurationState(getStateSpec(component).name, component.state, null)
|
||||
assertThat(printer.getInvokedEvent().data["project"]).isEqualTo(printer.getOptionByName("boolOption").data["project"])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `log changed to default setting`() {
|
||||
val component = TestComponent()
|
||||
component.loadState(MultiComponentState())
|
||||
val printer = TestFeatureUsageSettingsChangedPrinter(false)
|
||||
val state = getStateSpec(component)
|
||||
printer.logConfigurationStateChanged(state.name, component.state, projectRule.project)
|
||||
|
||||
assertThat(printer.result).hasSize(1)
|
||||
validateChangedComponent(state, printer.result.first())
|
||||
}
|
||||
|
||||
private fun validateChangedComponent(state: State, event: Pair<String, FeatureUsageData>) {
|
||||
val (eventId, usageData) = event
|
||||
assertThat(eventId).isEqualTo("component_changed")
|
||||
val data = usageData.build()
|
||||
assertThat(data["component"]).isEqualTo(state.name)
|
||||
assertThat(data).containsOnlyKeys("component", "plugin_type", "project")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `log changed to not default settings`() {
|
||||
val component = TestComponent()
|
||||
component.loadState(MultiComponentState(secondBool = false))
|
||||
val printer = TestFeatureUsageSettingsChangedPrinter(false)
|
||||
val state = getStateSpec(component)
|
||||
printer.logConfigurationStateChanged(state.name, component.state, projectRule.project)
|
||||
|
||||
assertThat(printer.result).hasSize(2)
|
||||
val (eventId, usageData) = printer.result[0]
|
||||
assertThat(eventId).isEqualTo("component_changed_option")
|
||||
val data = usageData.build()
|
||||
assertThat(data["component"]).isEqualTo(state.name)
|
||||
assertThat(data["type"]).isEqualTo("bool")
|
||||
assertThat(data["name"]).isEqualTo("secondBoolOption")
|
||||
assertThat(data).containsOnlyKeys("component", "plugin_type", "project", "type", "name", "value")
|
||||
validateChangedComponent(state, printer.result[1])
|
||||
}
|
||||
|
||||
private fun assertDefaultWithoutDefaultRecording(printer: TestFeatureUsageSettingsEventsPrinter,
|
||||
withProject: Boolean,
|
||||
defaultProject: Boolean) {
|
||||
@@ -499,9 +536,13 @@ class FeatureUsageSettingsEventsTest {
|
||||
var size = 1
|
||||
if (withProject) size++
|
||||
if (defaultProject) size++
|
||||
if (event.data.containsKey("plugin_type")) size++
|
||||
if (event.data.containsKey("plugin_version")) size++
|
||||
if (event.data.containsKey("plugin")) size++
|
||||
|
||||
assertThat(event.data).hasSize(size)
|
||||
assertThat(event.data["component"]).isEqualTo("MyTestComponent")
|
||||
assertThat(event.data["plugin_type"]).isNotNull
|
||||
if (withProject) {
|
||||
assertThat(event.data).containsKey("project")
|
||||
}
|
||||
@@ -513,8 +554,8 @@ class FeatureUsageSettingsEventsTest {
|
||||
private class TestFeatureUsageSettingsEventsPrinter(recordDefault: Boolean) : FeatureUsageSettingsEventPrinter(recordDefault) {
|
||||
val result: MutableList<LoggedComponentStateEvents> = ArrayList()
|
||||
|
||||
override fun logConfig(group: EventLogGroup, eventId: String, data: Map<String, Any>) {
|
||||
result.add(LoggedComponentStateEvents(group, eventId, data))
|
||||
override fun logConfig(group: EventLogGroup, eventId: String, data: FeatureUsageData) {
|
||||
result.add(LoggedComponentStateEvents(group, eventId, data.build()))
|
||||
}
|
||||
|
||||
fun getOptionByName(name: String): LoggedComponentStateEvents {
|
||||
@@ -536,6 +577,14 @@ class FeatureUsageSettingsEventsTest {
|
||||
}
|
||||
}
|
||||
|
||||
private class TestFeatureUsageSettingsChangedPrinter(recordDefault: Boolean) : FeatureUsageSettingsEventPrinter(recordDefault) {
|
||||
val result: MutableList<Pair<String, FeatureUsageData>> = ArrayList()
|
||||
|
||||
override fun logSettingsChanged(eventId: String, data: FeatureUsageData, id: Int) {
|
||||
result.add(Pair(eventId, data))
|
||||
}
|
||||
}
|
||||
|
||||
private class LoggedComponentStateEvents(val group: EventLogGroup, val id: String, val data: Map<String, Any>)
|
||||
|
||||
@State(name = "MyTestComponent", reportStatistic = true)
|
||||
@@ -608,6 +657,7 @@ class FeatureUsageSettingsEventsTest {
|
||||
val absDoubleOption: Double = absDoubleOpt
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
private class ComponentStateWithEnum(enumOpt: EnumOption = EnumOption.FOO,
|
||||
absEnumOpt: EnumOption = EnumOption.FOO) : ComponentState() {
|
||||
@Attribute("enum-option")
|
||||
@@ -622,6 +672,7 @@ class FeatureUsageSettingsEventsTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
private class ComponentStateWithString(stringOpt: String = "test",
|
||||
absStringOpt: String = "test",
|
||||
absStringOptWithoutPossibleValues: String = "test") : ComponentState() {
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ import com.intellij.internal.statistic.utils.StatisticsUploadAssistant
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
internal class FeatureUsageEventLoggerProvider : StatisticsEventLoggerProvider("FUS", 46, sendFrequencyMs = TimeUnit.MINUTES.toMillis(15)) {
|
||||
internal class FeatureUsageEventLoggerProvider : StatisticsEventLoggerProvider("FUS", 47, sendFrequencyMs = TimeUnit.MINUTES.toMillis(15)) {
|
||||
override fun isRecordEnabled(): Boolean {
|
||||
return !ApplicationManager.getApplication().isHeadlessEnvironment &&
|
||||
StatisticsUploadAssistant.isCollectAllowed()
|
||||
|
||||
+1
-1
@@ -66,7 +66,7 @@ public class FUCounterUsageLogger {
|
||||
private static final String[] GENERAL_GROUPS = new String[]{
|
||||
"event.log", "performance", "ui.dialogs", "ui.settings",
|
||||
"toolwindow", "intentions", "run.configuration.exec",
|
||||
"productivity", "completion.postfix", "notifications"
|
||||
"productivity", "completion.postfix", "notifications", "settings.changes"
|
||||
};
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(FUCounterUsageLogger.class);
|
||||
|
||||
Reference in New Issue
Block a user