Sonar scanner unchanged file detection

Sonar Server : v2025.2
Sonar gradle plugin : 6.1.0.5360
scanner-java-library: 3.3.1.450

Hi folks,

While going through the debug logs for a PR analysis, I see that the following lines

2025-05-20T14:47:41.127+0530 [INFO] [org.sonarsource.scanner.lib.internal.facade.forked.ScannerEngineLauncher] SCM collecting changed files in the branch (done) | time=454ms
2025-05-20T14:47:41.127+0530 [DEBUG] [org.sonarsource.scanner.lib.internal.facade.forked.ScannerEngineLauncher] SCM reported 4 files changed in the branch

Since this is a PR analysis, I also have sonar.java.skipUnchanged and sonar.kotlin.skipUnchanged enabled. However newer log lines indicate
the following

[DEBUG] [org.sonarsource.scanner.lib.internal.facade.forked.ScannerEngineLauncher] The Kotlin analyzer is running in a context where it can skip unchanged files.
[INFO] [org.sonarsource.scanner.lib.internal.facade.forked.ScannerEngineLauncher] Only analyzing 227 changed Kotlin files out of 227.
[INFO] [org.sonarsource.scanner.lib.internal.facade.forked.ScannerEngineLauncher] 227 source files to be analyzed

This repeats multiple times for various modules.

Since SCM has detected only 4 files as changed, why would the scanner analyze other files here?

My assumption is that this is because a file being “unchanged” is determined on the basis of the analysis cache being present for the branch.
Since the definition of new code is scm driven and the report would not report any issues on these files, is it necessary to do the analysis for all the other files?

The docs also state that the analysis cache for a PR is discarded.

Is there any way for us to avoid doing the extra analysis here?

Thanks.

Hi again,

So I triggered a branch analysis on the base branch and retriggerred the PR analysis. However this does not reduce the number of files being analyzed.

I also see these log lines for java analysis

Server-side caching is enabled. The Java analyzer was able to leverage cached data from previous analyses for 1 out of 1 files. These files will not be parsed.

I however cannot see any such logs for kotlin files. Would this mean that server-side caching is not enabled for kotlin?

Thanks

Hi again,
Adding to the question above. What would be the best way to debug analysis cache misses?
I have the debug logs with me , however I’m unable to understand why there were cache misses.

Edit:
Looks like the cache misses are logged at the TRACE level.

What would be the best way to log trace metrics from the sonar scanner?

Hi again,

There are changes in 4 files

sonarqub‎e.gradle 
libs.‎versions.toml‎
.gitlab-ci.yml‎
build.gr‎adle.kts‎

Some sensor metrics for the same MR.

Analysis of: rerun-5/gradle.log
==================================================

Sensor Execution Times (in milliseconds):
--------------------------------------------------
Kotlin Sensor: 1192763 ms
Import of Android Lint issues: 135907 ms
JavaSensor: 51446 ms
KotlinSurefireSensor: 17811 ms
JavaSecuritySensor: 12433 ms
JaCoCo XML Report Importer: 11764 ms
EnterpriseTextAndSecretsSensor: 4832 ms
IaC Docker Sensor: 932 ms
SurefireSensor: 853 ms
Gradle Sensor: 682 ms
Java Config Sensor: 346 ms
IaC AzureResourceManager Sensor: 141 ms
IaC CloudFormation Sensor: 98 ms
JavaArchitectureSensor: 74 ms
CSS Rules: 51 ms
HTML: 50 ms
Serverless configuration file sensor: 41 ms
XML Sensor: 24 ms
AWS SAM template file sensor: 24 ms
AWS SAM Inline template file sensor: 19 ms
javabugs: 5 ms
CSharpSecuritySensor: 3 ms
PhpSecuritySensor: 2 ms
PythonSecuritySensor: 2 ms
JsSecuritySensor: 2 ms
ThymeLeaf template sensor: 1 ms
KotlinSecuritySensor: 1 ms
pythonbugs: 0 ms
KotlinProjectSensor: 0 ms

==================================================
Total time across all sensors: 1430307 ms
Total time: 1430.31 seconds
Total time: 23.84 minutes

Hi,

The skipUnchanged parameters govern whether or not analysis can attempt to use cache files from the server. Each sensor (i.e. language analyzer) decides for itself whether it’s appropriate in context to use the cache files. Sometimes it is and some time can be saved during analysis. Sometimes it’s not.

My understanding is fuzzy, but I believe it’s not just whether or not the cache is present but that it’s still relevant given the changes in the PR. If you change a foundational or widely used class in your PR, it may blow the usefulness of the entire cache out of the water.

 
HTH,
Ann

Hi Ann,

Thank you for the reply. Can you let me know how the cache key is calculated for a kotlin file? I’m trying to understand what could cause a cache miss here.

Hello @sonardroid,

Could you please provide the full analysis log, so I can investigate what’s happening in your case?

There could be many things that went wrong resulting in such an outcome.

Could you also clarify if your complaint is about performance degradation on the PR due to cache misses or something else.

Best,
Margarita

Hi Margarita,

Since the logs would contain some sensitive info, I would prefer sharing this over a non public channel if that’s possible please let me know. We are Sonar enterprise customers and I believe have a ticket open for this too.

Yes that is correct, my complaint is about the performance degradation on PR analysis.
On going through the debug logs, I see that all kotlin files were analyzed despite there not being any changes to these files. Which leads me to the conclusion that the analysis cache could not be leveraged for any of these files.

Hi Again,

Some more details from the most recent run

==================================================
Analysis of: rerun-6/gradle.log
==================================================

Sensor Execution Times (in milliseconds):
--------------------------------------------------
Kotlin Sensor: 1174941 ms
Import of Android Lint issues: 137731 ms
JavaSensor: 47992 ms
JavaSecuritySensor: 12221 ms
EnterpriseTextAndSecretsSensor: 4291 ms
IaC Docker Sensor: 927 ms
Gradle Sensor: 704 ms
Java Config Sensor: 349 ms
IaC AzureResourceManager Sensor: 145 ms
IaC CloudFormation Sensor: 100 ms
JavaArchitectureSensor: 74 ms
HTML: 48 ms
CSS Rules: 41 ms
JaCoCo XML Report Importer: 39 ms
Serverless configuration file sensor: 38 ms
AWS SAM template file sensor: 26 ms
XML Sensor: 18 ms
AWS SAM Inline template file sensor: 17 ms
KotlinSurefireSensor: 13 ms
ThymeLeaf template sensor: 6 ms
javabugs: 5 ms
SurefireSensor: 4 ms
CSharpSecuritySensor: 3 ms
PhpSecuritySensor: 3 ms
PythonSecuritySensor: 3 ms
JsSecuritySensor: 3 ms
KotlinSecuritySensor: 2 ms
pythonbugs: 0 ms
KotlinProjectSensor: 0 ms

==================================================
Total time across all sensors: 1379744 ms
Total time: 1379.74 seconds
Total time: 23.00 minutes

The different between this branch and the sonar.pullrequest.base branch here is a new line character on the root build.gradle.kts

I also see the following log lines

2025-05-23T16:01:25.979+0530 [INFO] [org.sonarsource.scanner.lib.internal.facade.forked.ScannerEngineLauncher] Server-side caching is enabled. The Java analyzer was able to leverage cached data from previous analyses for 1 out of 1 files. These files will not be parsed.
2025-05-23T16:01:25.981+0530 [INFO] [org.sonarsource.scanner.lib.internal.facade.forked.ScannerEngineLauncher] Only analyzing 19 changed Kotlin files out of 19.
2025-05-23T16:01:25.983+0530 [DEBUG] [org.sonarsource.scanner.lib.internal.facade.forked.ScannerEngineLauncher] Using Kotlin 1.9 to parse source code
2025-05-23T16:01:25.983+0530 [INFO] [org.sonarsource.scanner.lib.internal.facade.forked.ScannerEngineLauncher] 19 source files to be analyzed

It seems that while I’m getting cache hits for java files, I do not get those for kotlin files.

Lastly I noticed these logs too

2025-05-23T16:00:28.675+0530 [INFO] [org.sonarsource.scanner.lib.internal.facade.forked.ScannerEngineLauncher] Quality profile for java: Acme Android App way
2025-05-23T16:00:28.675+0530 [INFO] [org.sonarsource.scanner.lib.internal.facade.forked.ScannerEngineLauncher] Quality profile for json: Sonar way
2025-05-23T16:00:28.675+0530 [INFO] [org.sonarsource.scanner.lib.internal.facade.forked.ScannerEngineLauncher] Quality profile for kotlin: Sonar way
2025-05-23T16:00:28.675+0530 [INFO] [org.sonarsource.scanner.lib.internal.facade.forked.ScannerEngineLauncher] Quality profile for xml: Sonar way

Can the quality gate used impact cache hits?
Prior to this upgrade(10.8), we were using the Acme Android App way for this project(configured via the sonar GUI). However after the upgrade(2025.1 LTA) the logs indicate that different quality gates are used for each language. I wanted to understand if this is a new feature or it has perhaps always been there and I’ve missed it.