mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-13 15:52:01 +07:00
LLM-10123 Fix different device_id in FUS and ML v2 logs
Add a possibility for other recorders to have same `device_id` and `machine_id` as in `FUS` recorder. This will greatly simplify the process of data analysis. Applicable only for anonymized recorders. (cherry picked from commit 5cee599f48d69ff77a006233b8103879597e8261) GitOrigin-RevId: 18c9763ef8bebb874fa85e720c61c196ea8b9b92
This commit is contained in:
committed by
intellij-monorepo-bot
parent
578c631e2a
commit
7d57293565
@@ -20,7 +20,8 @@ class IJMapperEventLoggerProvider : StatisticsEventLoggerProvider(
|
||||
sendFrequencyMs = TimeUnit.HOURS.toMillis(1),
|
||||
maxFileSizeInBytes = 1 * 512, // enough to fill a log file with one entry of the state collector
|
||||
sendLogsOnIdeClose = true,
|
||||
isCharsEscapingRequired = false
|
||||
isCharsEscapingRequired = false,
|
||||
useDefaultRecorderId = true
|
||||
) {
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,7 +21,8 @@ class MLEventLoggerProvider : StatisticsEventLoggerProvider(
|
||||
sendFrequencyMs = TimeUnit.MINUTES.toMillis(10),
|
||||
maxFileSizeInBytes = 100 * 1024,
|
||||
sendLogsOnIdeClose = true,
|
||||
isCharsEscapingRequired = false
|
||||
isCharsEscapingRequired = false,
|
||||
useDefaultRecorderId = true
|
||||
) {
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,6 +11,19 @@ import com.intellij.testFramework.fixtures.BasePlatformTestCase
|
||||
import kotlin.test.assertNotEquals
|
||||
|
||||
class EventLogConfigurationTest : BasePlatformTestCase() {
|
||||
|
||||
// Test that two different recorders can have same machine/device id if the alternative recorder id is provided
|
||||
fun testMachineIdDeviceIdAlternativeRecorder() {
|
||||
val configuration = EventLogConfiguration.getInstance().getOrCreate("ABC", null)
|
||||
val alternativeConfiguration = EventLogConfiguration.getInstance().getOrCreate("DEF", "ABC")
|
||||
|
||||
assertNotNull(configuration.deviceId)
|
||||
assertNotNull(configuration.machineId)
|
||||
|
||||
assertEquals(configuration.deviceId, alternativeConfiguration.deviceId)
|
||||
assertEquals(configuration.machineId, alternativeConfiguration.machineId)
|
||||
}
|
||||
|
||||
fun testMachineIdRegeneration() {
|
||||
doTestRegenerate({ it.machineId }, hashMapOf(MACHINE_ID_SALT to "newSalt",
|
||||
MACHINE_ID_SALT_REVISION to "2"))
|
||||
|
||||
@@ -80,6 +80,7 @@ class EventLogConfiguration {
|
||||
}
|
||||
|
||||
val defaultSessionId: String by lazy { generateSessionId() }
|
||||
|
||||
internal fun generateSessionId(): String {
|
||||
val presentableHour = StatisticsUtil.getCurrentHourInUTC()
|
||||
return "$presentableHour-${UUID.randomUUID().toString().shortedUUID()}"
|
||||
@@ -119,11 +120,12 @@ class EventLogConfiguration {
|
||||
return if (str.endsWith(".")) str + "0" else str
|
||||
}
|
||||
|
||||
fun getOrCreate(recorderId: String): EventLogRecorderConfiguration {
|
||||
@JvmOverloads
|
||||
fun getOrCreate(recorderId: String, alternativeRecorderId: String? = null): EventLogRecorderConfiguration {
|
||||
if (isDefaultRecorderId(recorderId)) return defaultConfiguration
|
||||
|
||||
synchronized(this) {
|
||||
return configurations.getOrPut(recorderId) { EventLogRecorderConfiguration(recorderId, this) }
|
||||
return configurations.getOrPut(recorderId) { EventLogRecorderConfiguration(recorderId = recorderId, eventLogConfiguration = this, alternativeRecorderId = alternativeRecorderId) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,9 +151,13 @@ class EventLogConfiguration {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param alternativeRecorderId - when provided, machine id and device id will be generated based on it instead of the `recorderId`
|
||||
*/
|
||||
class EventLogRecorderConfiguration internal constructor(private val recorderId: String,
|
||||
private val eventLogConfiguration: EventLogConfiguration,
|
||||
val sessionId: String = generateSessionId()) {
|
||||
val sessionId: String = generateSessionId(),
|
||||
val alternativeRecorderId: String? = null) {
|
||||
|
||||
val deviceId: String = getOrGenerateDeviceId()
|
||||
val bucket: Int = deviceId.asBucket()
|
||||
@@ -167,11 +173,11 @@ class EventLogRecorderConfiguration internal constructor(private val recorderId:
|
||||
|
||||
init {
|
||||
machineIdReference = AtomicLazyValue {
|
||||
val configOptions = EventLogConfigOptionsService.getInstance().getOptions(recorderId)
|
||||
val configOptions = EventLogConfigOptionsService.getInstance().getOptions(alternativeRecorderId ?: recorderId)
|
||||
generateMachineId(configOptions.machineIdSalt, configOptions.machineIdRevision)
|
||||
}
|
||||
|
||||
EventLogConfigOptionsService.TOPIC.subscribe(null, object : EventLogRecorderConfigOptionsListener(recorderId) {
|
||||
EventLogConfigOptionsService.TOPIC.subscribe(null, object : EventLogRecorderConfigOptionsListener(alternativeRecorderId ?: recorderId) {
|
||||
override fun onMachineIdConfigurationChanged(salt: @Nullable String?, revision: Int) {
|
||||
machineIdReference.updateAndGet { prevValue ->
|
||||
if (salt != null && revision != -1 && revision > prevValue.revision) {
|
||||
@@ -189,7 +195,7 @@ class EventLogRecorderConfiguration internal constructor(private val recorderId:
|
||||
return MachineId.DISABLED
|
||||
}
|
||||
val revision = if (value >= 0) value else DEFAULT_ID_REVISION
|
||||
val machineId = MachineIdManager.getAnonymizedMachineId("JetBrains$recorderId", salt) ?: return MachineId.UNKNOWN
|
||||
val machineId = MachineIdManager.getAnonymizedMachineId("JetBrains${alternativeRecorderId ?: recorderId}", salt) ?: return MachineId.UNKNOWN
|
||||
return MachineId(machineId, revision)
|
||||
}
|
||||
|
||||
@@ -219,17 +225,17 @@ class EventLogRecorderConfiguration internal constructor(private val recorderId:
|
||||
private fun getOrGenerateDeviceId(): String {
|
||||
val app = ApplicationManager.getApplication()
|
||||
if (app != null && app.isHeadlessEnvironment) {
|
||||
val property = eventLogConfiguration.getHeadlessDeviceIdProperty(recorderId)
|
||||
val property = eventLogConfiguration.getHeadlessDeviceIdProperty(alternativeRecorderId ?: recorderId)
|
||||
System.getProperty(property)?.let {
|
||||
return it
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return DeviceIdManager.getOrGenerateId(object : DeviceIdManager.DeviceIdToken {}, recorderId)
|
||||
return DeviceIdManager.getOrGenerateId(object : DeviceIdManager.DeviceIdToken {}, alternativeRecorderId ?: recorderId)
|
||||
}
|
||||
catch (e: DeviceIdManager.InvalidDeviceIdTokenException) {
|
||||
EventLogConfiguration.LOG.warn("Failed retrieving device id for $recorderId")
|
||||
catch (_: DeviceIdManager.InvalidDeviceIdTokenException) {
|
||||
EventLogConfiguration.LOG.warn("Failed retrieving device id for ${alternativeRecorderId ?: recorderId}")
|
||||
return UNDEFINED_DEVICE_ID
|
||||
}
|
||||
}
|
||||
@@ -237,13 +243,13 @@ class EventLogRecorderConfiguration internal constructor(private val recorderId:
|
||||
private fun getOrGenerateSalt(): ByteArray {
|
||||
val app = ApplicationManager.getApplication()
|
||||
if (app != null && app.isHeadlessEnvironment) {
|
||||
val property = eventLogConfiguration.getHeadlessSaltProperty(recorderId)
|
||||
val property = eventLogConfiguration.getHeadlessSaltProperty(alternativeRecorderId ?: recorderId)
|
||||
System.getProperty(property)?.let {
|
||||
return it.toByteArray(Charsets.UTF_8)
|
||||
}
|
||||
}
|
||||
|
||||
return EventLogConfiguration.getOrGenerateSaltFromPrefs(recorderId)
|
||||
return EventLogConfiguration.getOrGenerateSaltFromPrefs(alternativeRecorderId ?: recorderId)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,12 +29,16 @@ interface StatisticsEventLogger {
|
||||
fun rollOver()
|
||||
}
|
||||
|
||||
/**
|
||||
* [useDefaultRecorderId] - When enabled, device and machine ids would match FUS(default) recorder. Must NOT be enabled for non-anonymized recorders.
|
||||
*/
|
||||
abstract class StatisticsEventLoggerProvider(val recorderId: String,
|
||||
val version: Int,
|
||||
val sendFrequencyMs: Long,
|
||||
private val maxFileSizeInBytes: Int,
|
||||
val sendLogsOnIdeClose: Boolean = false,
|
||||
val isCharsEscapingRequired: Boolean = true) {
|
||||
val isCharsEscapingRequired: Boolean = true,
|
||||
val useDefaultRecorderId: Boolean = false) {
|
||||
|
||||
@Deprecated(message = "Use primary constructor instead")
|
||||
constructor(recorderId: String,
|
||||
@@ -128,7 +132,7 @@ abstract class StatisticsEventLoggerProvider(val recorderId: String,
|
||||
null
|
||||
}
|
||||
val eventLogConfiguration = EventLogConfiguration.getInstance()
|
||||
val config = eventLogConfiguration.getOrCreate(recorderId)
|
||||
val config = eventLogConfiguration.getOrCreate(recorderId, if (useDefaultRecorderId) "FUS" else null)
|
||||
val writer = StatisticsEventLogFileWriter(recorderId, this, maxFileSizeInBytes, isEap, eventLogConfiguration.build)
|
||||
|
||||
val configService = EventLogConfigOptionsService.getInstance()
|
||||
|
||||
Reference in New Issue
Block a user