Skip to content

Commit 5d663d8

Browse files
authored
Enforce LazyLog rule on Logger type instead of variable name (#3022)
1 parent 2625a4c commit 5d663d8

File tree

11 files changed

+60
-33
lines changed

11 files changed

+60
-33
lines changed

core/src/software/aws/toolkits/core/utils/LogUtils.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4+
@file:Suppress("LazyLog")
45
package software.aws.toolkits.core.utils
56

67
import org.slf4j.Logger

core/tst/software/aws/toolkits/core/utils/LogUtilsTest.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4+
@file:Suppress("LazyLog")
45
package software.aws.toolkits.core.utils
56

67
import org.assertj.core.api.Assertions.assertThat

core/tst/software/aws/toolkits/core/utils/RemoteResourceResolverTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ class RemoteResourceResolverTest {
145145
// It's possible for it to be done writing but path.exists to not work yet which
146146
// makes the canDownloadAFileOnce test fail (on CodeBuild).
147147
while (!path.exists()) {
148-
LOG.debug("writeDataToFile path does not exist yet: $path")
148+
LOG.debug { "writeDataToFile path does not exist yet: $path" }
149149
Thread.sleep(10)
150150
}
151151
}

detekt-rules/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ dependencies {
1111
testImplementation(libs.detekt.test)
1212
testImplementation(libs.junit4)
1313
testImplementation(libs.assertj)
14+
testRuntimeOnly(libs.slf4j.api)
1415
}

detekt-rules/src/software/aws/toolkits/gradle/detekt/rules/LazyLogRule.kt

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,18 @@ import io.gitlab.arturbosch.detekt.api.Entity
99
import io.gitlab.arturbosch.detekt.api.Issue
1010
import io.gitlab.arturbosch.detekt.api.Rule
1111
import io.gitlab.arturbosch.detekt.api.Severity
12-
import org.jetbrains.kotlin.name.Name
12+
import io.gitlab.arturbosch.detekt.api.internal.RequiresTypeResolution
13+
import io.gitlab.arturbosch.detekt.rules.fqNameOrNull
1314
import org.jetbrains.kotlin.psi.KtCallExpression
1415
import org.jetbrains.kotlin.psi.psiUtil.getCallNameExpression
15-
import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression
16-
import org.jetbrains.kotlin.psi.psiUtil.referenceExpression
16+
import org.jetbrains.kotlin.resolve.BindingContext
17+
import org.jetbrains.kotlin.resolve.calls.callUtil.getReceiverExpression
18+
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
1719

20+
@RequiresTypeResolution
1821
class LazyLogRule : Rule() {
1922
override val issue = Issue("LazyLog", Severity.Style, "Use lazy logging synatax (e.g. warning {\"abc\"} ) instead of warning(\"abc\")", Debt.FIVE_MINS)
2023

21-
private val logMethods = setOf("error", "warn", "info", "debug", "trace")
22-
private val logNames = setOf("log", "logger")
23-
2424
// UI tests have issues with this TODO see if we want multiple detekt.yml files or disable for certain modules in this rule
2525
private val optOut = setOf("software.aws.toolkits.jetbrains.uitests")
2626

@@ -31,25 +31,34 @@ class LazyLogRule : Rule() {
3131
return
3232
}
3333

34-
if (optOut.any { name -> element.containingKtFile.packageFqName.startsWith(Name.identifier(name)) }) {
34+
if (optOut.any { name -> element.containingKtFile.packageFqName.asString().startsWith(name) }) {
3535
return
3636
}
3737

38-
val referenceExpression = it.getReceiverExpression()?.referenceExpression() ?: return
38+
if (bindingContext == BindingContext.EMPTY) return
39+
val resolvedCall = it.getResolvedCall(bindingContext)
40+
val type = resolvedCall?.extensionReceiver?.type?.fqNameOrNull()?.asString()
41+
?: resolvedCall?.dispatchReceiver?.type?.fqNameOrNull()?.asString()
3942

40-
if (!logNames.contains(referenceExpression.text.toLowerCase())) {
43+
if (type !in loggers) {
4144
return
4245
}
4346

4447
if (element.lambdaArguments.size != 1) {
48+
val receiverName = resolvedCall?.getReceiverExpression()?.text ?: type
4549
report(
4650
CodeSmell(
4751
issue,
4852
Entity.from(element),
49-
message = "Use the Lambda version of ${referenceExpression.text}.${it.text} instead"
53+
message = "Use the lambda version of $receiverName.${it.text} instead"
5054
)
5155
)
5256
}
5357
}
5458
}
59+
60+
companion object {
61+
private val logMethods = setOf("error", "warn", "info", "debug", "trace")
62+
val loggers = setOf("org.slf4j.Logger")
63+
}
5564
}

detekt-rules/tst/software/aws/toolkits/gradle/detekt/rules/LazyLogRuleTest.kt

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,31 @@
33

44
package software.aws.toolkits.gradle.detekt.rules
55

6-
import io.gitlab.arturbosch.detekt.test.lint
6+
import io.github.detekt.test.utils.createEnvironment
7+
import io.gitlab.arturbosch.detekt.test.compileAndLintWithContext
78
import org.assertj.core.api.Assertions.assertThat
89
import org.junit.Test
10+
import java.io.File
911

1012
class LazyLogRuleTest {
1113
private val rule = LazyLogRule()
14+
private val environment = createEnvironment(
15+
additionalRootPaths = LazyLogRule.loggers.map {
16+
File(Class.forName(it).protectionDomain.codeSource.location.path)
17+
}
18+
).env
1219

1320
@Test
1421
fun lambdaIsUsedToLog() {
1522
assertThat(
16-
rule.lint(
23+
rule.compileAndLintWithContext(
24+
environment,
1725
"""
1826
import org.slf4j.LoggerFactory
1927
20-
val LOG = LoggerFactory.getLogger(T::class.java)
28+
val LOG = LoggerFactory.getLogger(LoggerFactory::class.java)
2129
fun foo() {
22-
LOG.debug {"Hi" }
30+
LOG.debug { "Hi" }
2331
}
2432
""".trimIndent()
2533
)
@@ -29,30 +37,32 @@ fun foo() {
2937
@Test
3038
fun methodCallIsUsedToLog() {
3139
assertThat(
32-
rule.lint(
40+
rule.compileAndLintWithContext(
41+
environment,
3342
"""
3443
import org.slf4j.LoggerFactory
3544
36-
val LOG = LoggerFactory.getLogger(T::class.java)
45+
val LOG = LoggerFactory.getLogger(LoggerFactory::class.java)
3746
fun foo() {
3847
LOG.debug("Hi")
3948
}
4049
""".trimIndent()
4150
)
4251
).singleElement()
4352
.matches {
44-
it.id == "LazyLog" && it.message == "Use the Lambda version of LOG.debug instead"
53+
it.id == "LazyLog" && it.message == "Use the lambda version of LOG.debug instead"
4554
}
4655
}
4756

4857
@Test
4958
fun lambdaIsUsedToLogButWithException() {
5059
assertThat(
51-
rule.lint(
60+
rule.compileAndLintWithContext(
61+
environment,
5262
"""
5363
import org.slf4j.LoggerFactory
5464
55-
val LOG = LoggerFactory.getLogger(T::class.java)
65+
val LOG = LoggerFactory.getLogger(LoggerFactory::class.java)
5666
fun foo() {
5767
val e = RuntimeException()
5868
LOG.debug(e) {"Hi" }
@@ -65,13 +75,14 @@ fun foo() {
6575
@Test
6676
fun methodCallIsUsedToLogInUiTests() {
6777
assertThat(
68-
rule.lint(
78+
rule.compileAndLintWithContext(
79+
environment,
6980
"""
7081
package software.aws.toolkits.jetbrains.uitests.really.cool.test
7182
7283
import org.slf4j.LoggerFactory
7384
74-
val LOG = LoggerFactory.getLogger(T::class.java)
85+
val LOG = LoggerFactory.getLogger(LoggerFactory::class.java)
7586
fun foo() {
7687
LOG.debug("Hi")
7788
}

gradle/libs.versions.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ mockito = "4.0.0"
1717
telemetryGenerator = "1.0.25"
1818
testLogger = "3.1.0"
1919
testRetry = "1.2.1"
20+
slf4j = "1.7.36"
2021
wiremock = "2.27.2"
2122
zjsonpatch = "0.4.11"
2223

@@ -78,6 +79,7 @@ kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref =
7879
mockito-core = { module = "org.mockito:mockito-core", version.ref = "mockito" }
7980
mockito-kotlin = { module = "org.mockito.kotlin:mockito-kotlin", version.ref = "mockito" }
8081
telemetryGenerator = { module = "software.aws.toolkits:telemetry-generator", version.ref = "telemetryGenerator" }
82+
slf4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" }
8183
wiremock = { module = "com.github.tomakehurst:wiremock", version.ref = "wiremock" }
8284
zjsonpatch = { module = "com.flipkart.zjsonpatch:zjsonpatch", version.ref = "zjsonpatch" }
8385

jetbrains-core/src/software/aws/toolkits/jetbrains/core/credentials/AwsConnectionManager.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ abstract class AwsConnectionManager(private val project: Project) : SimpleModifi
159159
if (modificationStamp == this.modificationCount) {
160160
connectionState = it
161161
} else {
162-
LOGGER.warn("validateCredentials returned but the account manager state has been manipulated before results were back, ignoring")
162+
LOGGER.warn { "validateCredentials returned but the account manager state has been manipulated before results were back, ignoring" }
163163
}
164164
}
165165
}

jetbrains-core/src/software/aws/toolkits/jetbrains/core/docker/ToolkitDockerAdapter.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ abstract class AbstractToolkitDockerAdapter(protected val project: Project, prot
8181
// unfortunately no callbacks available to grab the Deployment instance
8282
val deploymentPromise = AsyncPromise<Deployment>()
8383
serverConnection.deploy(task) { deploymentName ->
84-
EcrUtils.LOG.debug("Retrieving Deployment associated with '$deploymentName'")
84+
LOG.debug { "Retrieving Deployment associated with '$deploymentName'" }
8585
RemoteServersView.getInstance(project).showDeployment(serverConnection, deploymentName)
8686
runInEdt {
8787
deploymentPromise.setResult(serverConnection.deployments.first { it.name == deploymentName })
@@ -110,7 +110,7 @@ abstract class AbstractToolkitDockerAdapter(protected val project: Project, prot
110110
}
111111

112112
if (!wasBuildOnly) {
113-
EcrUtils.LOG.debug("Configuration specified additional 'run' parameters in Dockerfile that will be ignored")
113+
LOG.debug { "Configuration specified additional 'run' parameters in Dockerfile that will be ignored" }
114114
logHandler.print("Skipping 'Run' portion of Dockerfile build configuration\n")
115115
}
116116

jetbrains-core/src/software/aws/toolkits/jetbrains/services/cloudwatch/logs/CloudWatchActor.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import software.amazon.awssdk.services.cloudwatchlogs.model.QueryStatus
2424
import software.amazon.awssdk.services.cloudwatchlogs.model.ResourceNotFoundException
2525
import software.aws.toolkits.core.utils.error
2626
import software.aws.toolkits.core.utils.getLogger
27+
import software.aws.toolkits.core.utils.info
2728
import software.aws.toolkits.core.utils.warn
2829
import software.aws.toolkits.jetbrains.core.coroutines.disposableCoroutineScope
2930
import software.aws.toolkits.jetbrains.core.coroutines.getCoroutineBgContext
@@ -507,15 +508,15 @@ class InsightsQueryResultsActor(
507508
}.chunked(1000)
508509

509510
dedupedResults.forEach { chunk ->
510-
LOG.info("loading block of ${chunk.size}")
511+
LOG.info { "loading block of ${chunk.size}" }
511512
table.listTableModel.addRows(chunk)
512513
}
513514
} while (isQueryRunning(response.status()))
514515

515-
LOG.info("done, ${loadedQueryResults.size} entries in set")
516+
LOG.info { "done, ${loadedQueryResults.size} entries in set" }
516517
tableDoneLoading()
517518
table.emptyText.text = emptyText
518-
LOG.info("total items in table: ${table.listTableModel.items.size}")
519+
LOG.info { "total items in table: ${table.listTableModel.items.size}" }
519520
channel.close()
520521
}.also {
521522
loadJob = it
@@ -540,7 +541,7 @@ class InsightsQueryResultsActor(
540541
}
541542
} catch (e: Exception) {
542543
// best effort; this will fail if the query raced to completion or user does not have permission
543-
LOG.warn("Failed to stop query", e)
544+
LOG.warn(e) { "Failed to stop query" }
544545
}
545546
}
546547
}

0 commit comments

Comments
 (0)