mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 06:50:54 +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),
|
sendFrequencyMs = TimeUnit.HOURS.toMillis(1),
|
||||||
maxFileSizeInBytes = 1 * 512, // enough to fill a log file with one entry of the state collector
|
maxFileSizeInBytes = 1 * 512, // enough to fill a log file with one entry of the state collector
|
||||||
sendLogsOnIdeClose = true,
|
sendLogsOnIdeClose = true,
|
||||||
isCharsEscapingRequired = false
|
isCharsEscapingRequired = false,
|
||||||
|
useDefaultRecorderId = true
|
||||||
) {
|
) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ class MLEventLoggerProvider : StatisticsEventLoggerProvider(
|
|||||||
sendFrequencyMs = TimeUnit.MINUTES.toMillis(10),
|
sendFrequencyMs = TimeUnit.MINUTES.toMillis(10),
|
||||||
maxFileSizeInBytes = 100 * 1024,
|
maxFileSizeInBytes = 100 * 1024,
|
||||||
sendLogsOnIdeClose = true,
|
sendLogsOnIdeClose = true,
|
||||||
isCharsEscapingRequired = false
|
isCharsEscapingRequired = false,
|
||||||
|
useDefaultRecorderId = true
|
||||||
) {
|
) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -11,6 +11,19 @@ import com.intellij.testFramework.fixtures.BasePlatformTestCase
|
|||||||
import kotlin.test.assertNotEquals
|
import kotlin.test.assertNotEquals
|
||||||
|
|
||||||
class EventLogConfigurationTest : BasePlatformTestCase() {
|
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() {
|
fun testMachineIdRegeneration() {
|
||||||
doTestRegenerate({ it.machineId }, hashMapOf(MACHINE_ID_SALT to "newSalt",
|
doTestRegenerate({ it.machineId }, hashMapOf(MACHINE_ID_SALT to "newSalt",
|
||||||
MACHINE_ID_SALT_REVISION to "2"))
|
MACHINE_ID_SALT_REVISION to "2"))
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ class EventLogConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val defaultSessionId: String by lazy { generateSessionId() }
|
val defaultSessionId: String by lazy { generateSessionId() }
|
||||||
|
|
||||||
internal fun generateSessionId(): String {
|
internal fun generateSessionId(): String {
|
||||||
val presentableHour = StatisticsUtil.getCurrentHourInUTC()
|
val presentableHour = StatisticsUtil.getCurrentHourInUTC()
|
||||||
return "$presentableHour-${UUID.randomUUID().toString().shortedUUID()}"
|
return "$presentableHour-${UUID.randomUUID().toString().shortedUUID()}"
|
||||||
@@ -119,11 +120,12 @@ class EventLogConfiguration {
|
|||||||
return if (str.endsWith(".")) str + "0" else str
|
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
|
if (isDefaultRecorderId(recorderId)) return defaultConfiguration
|
||||||
|
|
||||||
synchronized(this) {
|
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,
|
class EventLogRecorderConfiguration internal constructor(private val recorderId: String,
|
||||||
private val eventLogConfiguration: EventLogConfiguration,
|
private val eventLogConfiguration: EventLogConfiguration,
|
||||||
val sessionId: String = generateSessionId()) {
|
val sessionId: String = generateSessionId(),
|
||||||
|
val alternativeRecorderId: String? = null) {
|
||||||
|
|
||||||
val deviceId: String = getOrGenerateDeviceId()
|
val deviceId: String = getOrGenerateDeviceId()
|
||||||
val bucket: Int = deviceId.asBucket()
|
val bucket: Int = deviceId.asBucket()
|
||||||
@@ -167,11 +173,11 @@ class EventLogRecorderConfiguration internal constructor(private val recorderId:
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
machineIdReference = AtomicLazyValue {
|
machineIdReference = AtomicLazyValue {
|
||||||
val configOptions = EventLogConfigOptionsService.getInstance().getOptions(recorderId)
|
val configOptions = EventLogConfigOptionsService.getInstance().getOptions(alternativeRecorderId ?: recorderId)
|
||||||
generateMachineId(configOptions.machineIdSalt, configOptions.machineIdRevision)
|
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) {
|
override fun onMachineIdConfigurationChanged(salt: @Nullable String?, revision: Int) {
|
||||||
machineIdReference.updateAndGet { prevValue ->
|
machineIdReference.updateAndGet { prevValue ->
|
||||||
if (salt != null && revision != -1 && revision > prevValue.revision) {
|
if (salt != null && revision != -1 && revision > prevValue.revision) {
|
||||||
@@ -189,7 +195,7 @@ class EventLogRecorderConfiguration internal constructor(private val recorderId:
|
|||||||
return MachineId.DISABLED
|
return MachineId.DISABLED
|
||||||
}
|
}
|
||||||
val revision = if (value >= 0) value else DEFAULT_ID_REVISION
|
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)
|
return MachineId(machineId, revision)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,17 +225,17 @@ class EventLogRecorderConfiguration internal constructor(private val recorderId:
|
|||||||
private fun getOrGenerateDeviceId(): String {
|
private fun getOrGenerateDeviceId(): String {
|
||||||
val app = ApplicationManager.getApplication()
|
val app = ApplicationManager.getApplication()
|
||||||
if (app != null && app.isHeadlessEnvironment) {
|
if (app != null && app.isHeadlessEnvironment) {
|
||||||
val property = eventLogConfiguration.getHeadlessDeviceIdProperty(recorderId)
|
val property = eventLogConfiguration.getHeadlessDeviceIdProperty(alternativeRecorderId ?: recorderId)
|
||||||
System.getProperty(property)?.let {
|
System.getProperty(property)?.let {
|
||||||
return it
|
return it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return DeviceIdManager.getOrGenerateId(object : DeviceIdManager.DeviceIdToken {}, recorderId)
|
return DeviceIdManager.getOrGenerateId(object : DeviceIdManager.DeviceIdToken {}, alternativeRecorderId ?: recorderId)
|
||||||
}
|
}
|
||||||
catch (e: DeviceIdManager.InvalidDeviceIdTokenException) {
|
catch (_: DeviceIdManager.InvalidDeviceIdTokenException) {
|
||||||
EventLogConfiguration.LOG.warn("Failed retrieving device id for $recorderId")
|
EventLogConfiguration.LOG.warn("Failed retrieving device id for ${alternativeRecorderId ?: recorderId}")
|
||||||
return UNDEFINED_DEVICE_ID
|
return UNDEFINED_DEVICE_ID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,13 +243,13 @@ class EventLogRecorderConfiguration internal constructor(private val recorderId:
|
|||||||
private fun getOrGenerateSalt(): ByteArray {
|
private fun getOrGenerateSalt(): ByteArray {
|
||||||
val app = ApplicationManager.getApplication()
|
val app = ApplicationManager.getApplication()
|
||||||
if (app != null && app.isHeadlessEnvironment) {
|
if (app != null && app.isHeadlessEnvironment) {
|
||||||
val property = eventLogConfiguration.getHeadlessSaltProperty(recorderId)
|
val property = eventLogConfiguration.getHeadlessSaltProperty(alternativeRecorderId ?: recorderId)
|
||||||
System.getProperty(property)?.let {
|
System.getProperty(property)?.let {
|
||||||
return it.toByteArray(Charsets.UTF_8)
|
return it.toByteArray(Charsets.UTF_8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return EventLogConfiguration.getOrGenerateSaltFromPrefs(recorderId)
|
return EventLogConfiguration.getOrGenerateSaltFromPrefs(alternativeRecorderId ?: recorderId)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -29,12 +29,16 @@ interface StatisticsEventLogger {
|
|||||||
fun rollOver()
|
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,
|
abstract class StatisticsEventLoggerProvider(val recorderId: String,
|
||||||
val version: Int,
|
val version: Int,
|
||||||
val sendFrequencyMs: Long,
|
val sendFrequencyMs: Long,
|
||||||
private val maxFileSizeInBytes: Int,
|
private val maxFileSizeInBytes: Int,
|
||||||
val sendLogsOnIdeClose: Boolean = false,
|
val sendLogsOnIdeClose: Boolean = false,
|
||||||
val isCharsEscapingRequired: Boolean = true) {
|
val isCharsEscapingRequired: Boolean = true,
|
||||||
|
val useDefaultRecorderId: Boolean = false) {
|
||||||
|
|
||||||
@Deprecated(message = "Use primary constructor instead")
|
@Deprecated(message = "Use primary constructor instead")
|
||||||
constructor(recorderId: String,
|
constructor(recorderId: String,
|
||||||
@@ -128,7 +132,7 @@ abstract class StatisticsEventLoggerProvider(val recorderId: String,
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
val eventLogConfiguration = EventLogConfiguration.getInstance()
|
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 writer = StatisticsEventLogFileWriter(recorderId, this, maxFileSizeInBytes, isEap, eventLogConfiguration.build)
|
||||||
|
|
||||||
val configService = EventLogConfigOptionsService.getInstance()
|
val configService = EventLogConfigOptionsService.getInstance()
|
||||||
|
|||||||
Reference in New Issue
Block a user