Skip to content

Commit

Permalink
Refactor logging system and adjust FUSEvent handling, fix IDEA-347208 (
Browse files Browse the repository at this point in the history
…#102)

The logging system has been refactored to log events using a new PackageSearchFUSEvent sealed interface, to handle logging more uniformly across the code. Furthermore, the sharing behavior of selectedModulesFlow in PackageListViewModel has been adjusted for better performance and readability. These changes help improve the organization and readability of the code while maintaining its functionality.
  • Loading branch information
lamba92 authored Feb 27, 2024
1 parent 111db62 commit 298e703
Show file tree
Hide file tree
Showing 10 changed files with 234 additions and 78 deletions.
1 change: 1 addition & 0 deletions plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ tasks {
?.suffixIfNot("]]>")

}

val buildShadowPlugin by registering(Zip::class) {
group = "intellij"
from(shadowJar) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.jetbrains.packagesearch.plugin.core.utils

import java.nio.file.Path
import kotlin.io.path.absolutePathString
import kotlin.io.path.isDirectory
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
Expand All @@ -16,6 +17,10 @@ class DirectoryPath(path: Path) : Path by path {
require(path.isDirectory()) { "Path $path is not a directory" }
}

override fun toString() = absolutePathString()
override fun equals(other: Any?) = absolutePathString() == (other as? DirectoryPath)?.absolutePathString()
override fun hashCode() = absolutePathString().hashCode()

companion object : KSerializer<DirectoryPath> {
override val descriptor: SerialDescriptor
get() = NioPathSerializer.descriptor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,22 +152,67 @@ private val headerAttributesClick = GROUP.registerEvent(
)
private val headerVariantClick = GROUP.registerEvent(FUSGroupIds.HEADER_VARIANTS_CLICK)

internal fun logPackageInstalled(
internal fun PackageSearchFUSEvent.log() {
when (this) {
is PackageSearchFUSEvent.PackageInstalled -> logPackageInstalled(packageIdentifier, targetModule)
is PackageSearchFUSEvent.PackageRemoved -> logPackageRemoved(
packageIdentifier = packageIdentifier,
packageVersion = packageVersion,
targetModule = targetModule
)

is PackageSearchFUSEvent.PackageVersionChanged -> logPackageVersionChanged(
packageIdentifier = packageIdentifier,
packageFromVersion = packageFromVersion,
packageTargetVersion = packageTargetVersion,
targetModule = targetModule
)

is PackageSearchFUSEvent.PackageScopeChanged -> logPackageScopeChanged(
packageIdentifier = packageIdentifier,
scopeFrom = scopeFrom,
scopeTo = scopeTo,
targetModule = targetModule
)

is PackageSearchFUSEvent.PackageVariantChanged -> logPackageVariantChanged(
packageIdentifier = packageIdentifier,
targetModule = targetModule
)

is PackageSearchFUSEvent.RepositoryAdded -> logRepositoryAdded(model)
is PackageSearchFUSEvent.RepositoryRemoved -> logRepositoryRemoved(model)
is PackageSearchFUSEvent.PreferencesRestoreDefaults -> logPreferencesRestoreDefaults()
is PackageSearchFUSEvent.TargetModulesSelected -> logTargetModuleSelected(targetModules)
is PackageSearchFUSEvent.PackageSelected -> logPackageSelected(isInstalled)
is PackageSearchFUSEvent.DetailsLinkClick -> logDetailsLinkClick(type)
is PackageSearchFUSEvent.OnlyStableToggle -> logOnlyStableToggle(state)
is PackageSearchFUSEvent.SearchRequest -> logSearchRequest(query)
is PackageSearchFUSEvent.SearchQueryClear -> logSearchQueryClear()
is PackageSearchFUSEvent.UpgradeAll -> logUpgradeAll()
is PackageSearchFUSEvent.InfoPanelOpened -> logInfoPanelOpened()
is PackageSearchFUSEvent.GoToSource -> logGoToSource(module, packageId)
is PackageSearchFUSEvent.HeaderAttributesClick -> logHeaderAttributesClick(isSearchHeader)
is PackageSearchFUSEvent.HeaderVariantsClick -> logHeaderVariantsClick()
}
}

private fun logPackageInstalled(
packageIdentifier: String,
targetModule: PackageSearchModule,
) = runSafelyIfEnabled(packageInstalledEvent) {
log(packageIdentifier, targetModule::class.java)
}

internal fun logPackageRemoved(
private fun logPackageRemoved(
packageIdentifier: String,
packageVersion: String?,
targetModule: PackageSearchModule,
) = runSafelyIfEnabled(packageRemovedEvent) {
log(packageIdentifier, packageVersion, targetModule::class.java)
}

internal fun logPackageVersionChanged(
private fun logPackageVersionChanged(
packageIdentifier: String,
packageFromVersion: String?,
packageTargetVersion: String,
Expand All @@ -181,14 +226,14 @@ internal fun logPackageVersionChanged(
)
}

internal fun logPackageVariantChanged(
private fun logPackageVariantChanged(
packageIdentifier: String,
targetModule: PackageSearchModule,
) = runSafelyIfEnabled(packageVariantChangedEvent) {
log(packageIdentifier, targetModule::class.java)
}

internal fun logPackageScopeChanged(
private fun logPackageScopeChanged(
packageIdentifier: String,
scopeFrom: String?,
scopeTo: String?,
Expand All @@ -202,11 +247,11 @@ internal fun logPackageScopeChanged(
)
}

internal fun logRepositoryAdded(model: ApiRepository) = runSafelyIfEnabled(repositoryAddedEvent) {
private fun logRepositoryAdded(model: ApiRepository) = runSafelyIfEnabled(repositoryAddedEvent) {
log(FUSGroupIds.IndexedRepositories.forId(model.id), FUSGroupIds.IndexedRepositories.validateUrl(model.url))
}

internal fun logRepositoryRemoved(model: ApiRepository) = runSafelyIfEnabled(repositoryRemovedEvent) {
private fun logRepositoryRemoved(model: ApiRepository) = runSafelyIfEnabled(repositoryRemovedEvent) {
val repository = FUSGroupIds.IndexedRepositories.forId(model.id)
val validatedUrl = FUSGroupIds.IndexedRepositories.validateUrl(model.url)
val usesCustomUrl = repository != FUSGroupIds.IndexedRepositories.NONE &&
Expand All @@ -215,57 +260,57 @@ internal fun logRepositoryRemoved(model: ApiRepository) = runSafelyIfEnabled(rep
log(repository, validatedUrl, usesCustomUrl)
}

internal fun logPreferencesRestoreDefaults() = runSafelyIfEnabled(preferencesRestoreDefaultsEvent) {
private fun logPreferencesRestoreDefaults() = runSafelyIfEnabled(preferencesRestoreDefaultsEvent) {
log()
}

internal fun logTargetModuleSelected(targetModules: List<PackageSearchModule>) =
private fun logTargetModuleSelected(targetModules: List<PackageSearchModule>) =
runSafelyIfEnabled(targetModulesSelectedEvent) {
if (targetModules.isNotEmpty()) {
log(targetModules.size, targetModules.groupBy { it.identity.group }.keys.size != 1)
}
}

internal fun logPackageSelected(isInstalled: Boolean) = runSafelyIfEnabled(packageSelectedEvent) {
private fun logPackageSelected(isInstalled: Boolean) = runSafelyIfEnabled(packageSelectedEvent) {
log(isInstalled)
}

internal fun logDetailsLinkClick(type: FUSGroupIds.DetailsLinkTypes) = runSafelyIfEnabled(detailsLinkClickEvent) {
private fun logDetailsLinkClick(type: FUSGroupIds.DetailsLinkTypes) = runSafelyIfEnabled(detailsLinkClickEvent) {
log(type)
}

internal fun logOnlyStableToggle(state: Boolean) = runSafelyIfEnabled(onlyStableToggleEvent) {
private fun logOnlyStableToggle(state: Boolean) = runSafelyIfEnabled(onlyStableToggleEvent) {
log(state)
}

internal fun logSearchRequest(query: String) = runSafelyIfEnabled(searchRequestEvent) {
private fun logSearchRequest(query: String) = runSafelyIfEnabled(searchRequestEvent) {
log(query.length)
}

internal fun logSearchQueryClear() = runSafelyIfEnabled(searchQueryClearEvent) {
private fun logSearchQueryClear() = runSafelyIfEnabled(searchQueryClearEvent) {
log()
}

internal fun logUpgradeAll() = runSafelyIfEnabled(upgradeAllEvent) {
private fun logUpgradeAll() = runSafelyIfEnabled(upgradeAllEvent) {
log()
}

internal fun logInfoPanelOpened() = runSafelyIfEnabled(infoPanelOpenedEvent) {
private fun logInfoPanelOpened() = runSafelyIfEnabled(infoPanelOpenedEvent) {
log()
}

internal fun logGoToSource(
private fun logGoToSource(
module: PackageSearchModule,
packageId: String,
) = runSafelyIfEnabled(goToSourceEvent) {
log(module::class.java, packageId)
}

internal fun logHeaderAttributesClick(isSearchHeader: Boolean) = runSafelyIfEnabled(headerAttributesClick) {
private fun logHeaderAttributesClick(isSearchHeader: Boolean) = runSafelyIfEnabled(headerAttributesClick) {
log(isSearchHeader)
}

internal fun logHeaderVariantsClick() = runSafelyIfEnabled(headerVariantClick) {
private fun logHeaderVariantsClick() = runSafelyIfEnabled(headerVariantClick) {
log()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.jetbrains.packagesearch.plugin.fus

import com.jetbrains.packagesearch.plugin.core.data.PackageSearchModule
import org.jetbrains.packagesearch.api.v3.ApiRepository

sealed interface PackageSearchFUSEvent {
data class PackageInstalled(val packageIdentifier: String, val targetModule: PackageSearchModule) :
PackageSearchFUSEvent

data class PackageRemoved(
val packageIdentifier: String,
val packageVersion: String?,
val targetModule: PackageSearchModule,
) : PackageSearchFUSEvent

data class PackageVersionChanged(
val packageIdentifier: String,
val packageFromVersion: String?,
val packageTargetVersion: String,
val targetModule: PackageSearchModule,
) : PackageSearchFUSEvent

data class PackageVariantChanged(val packageIdentifier: String, val targetModule: PackageSearchModule) :
PackageSearchFUSEvent

data class PackageScopeChanged(
val packageIdentifier: String,
val scopeFrom: String?,
val scopeTo: String?,
val targetModule: PackageSearchModule,
) : PackageSearchFUSEvent

data class RepositoryAdded(val model: ApiRepository) : PackageSearchFUSEvent
data class RepositoryRemoved(val model: ApiRepository) : PackageSearchFUSEvent
data object PreferencesRestoreDefaults : PackageSearchFUSEvent
data class TargetModulesSelected(val targetModules: List<PackageSearchModule>) : PackageSearchFUSEvent
data class PackageSelected(val isInstalled: Boolean) : PackageSearchFUSEvent
data class DetailsLinkClick(val type: FUSGroupIds.DetailsLinkTypes) : PackageSearchFUSEvent
data class OnlyStableToggle(val state: Boolean) : PackageSearchFUSEvent
data class SearchRequest(val query: String) : PackageSearchFUSEvent
data object SearchQueryClear : PackageSearchFUSEvent
data object UpgradeAll : PackageSearchFUSEvent
data object InfoPanelOpened : PackageSearchFUSEvent
data class GoToSource(val module: PackageSearchModule, val packageId: String) : PackageSearchFUSEvent
data class HeaderAttributesClick(val isSearchHeader: Boolean) : PackageSearchFUSEvent
data object HeaderVariantsClick : PackageSearchFUSEvent
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.jetbrains.packagesearch.plugin.services

import com.intellij.openapi.components.Service
import com.intellij.openapi.components.Service.Level
import com.jetbrains.packagesearch.plugin.fus.PackageSearchFUSEvent
import com.jetbrains.packagesearch.plugin.fus.log
import com.jetbrains.packagesearch.plugin.utils.logWarn
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.consumeAsFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.retry

@Service(Level.APP)
class PackageSearchFUSService(coroutineScope: CoroutineScope) {
private val eventsChannel: Channel<PackageSearchFUSEvent> = Channel(capacity = Channel.UNLIMITED)

init {
eventsChannel.consumeAsFlow()
.onEach { it.log() }
.retry {
logWarn("${this::class.qualifiedName}#eventReportingJob", it) { "Failed to log FUS" }
true
}
.launchIn(coroutineScope)
}

fun logEvent(event: PackageSearchFUSEvent) {
eventsChannel.trySend(event)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ import com.jetbrains.packagesearch.plugin.core.utils.PackageSearchProjectCachesS
import com.jetbrains.packagesearch.plugin.core.utils.fileOpenedFlow
import com.jetbrains.packagesearch.plugin.core.utils.replayOn
import com.jetbrains.packagesearch.plugin.core.utils.toolWindowOpenedFlow
import com.jetbrains.packagesearch.plugin.fus.logOnlyStableToggle
import com.jetbrains.packagesearch.plugin.fus.PackageSearchFUSEvent
import com.jetbrains.packagesearch.plugin.utils.PackageSearchApplicationCachesService
import com.jetbrains.packagesearch.plugin.utils.PackageSearchFUSService
import com.jetbrains.packagesearch.plugin.utils.WindowedModuleBuilderContext
import com.jetbrains.packagesearch.plugin.utils.filterNotNullKeys
import com.jetbrains.packagesearch.plugin.utils.logDebug
import com.jetbrains.packagesearch.plugin.utils.logFUSEvent
import com.jetbrains.packagesearch.plugin.utils.logWarn
import com.jetbrains.packagesearch.plugin.utils.nativeModulesFlow
import com.jetbrains.packagesearch.plugin.utils.startWithNull
Expand Down Expand Up @@ -147,11 +149,7 @@ class PackageSearchProjectService(
init {

stableOnlyStateFlow
.onEach { logOnlyStableToggle(it) }
.retry {
logWarn("${this::class.simpleName}#stableOnlyStateFlow", throwable = it)
true
}
.onEach { logFUSEvent(PackageSearchFUSEvent.OnlyStableToggle(it)) }
.launchIn(coroutineScope)

combine(
Expand Down
Loading

0 comments on commit 298e703

Please sign in to comment.