Skip to content

Commit aafc2db

Browse files
committed
feat: add cpu profiler logs
1 parent 4e6c759 commit aafc2db

File tree

1 file changed

+34
-3
lines changed
  • plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp

1 file changed

+34
-3
lines changed

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLspService.kt

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import com.intellij.util.net.ssl.CertificateManager
3131
import kotlinx.coroutines.CoroutineScope
3232
import kotlinx.coroutines.Deferred
3333
import kotlinx.coroutines.Job
34+
import kotlinx.coroutines.CancellationException
3435
import kotlinx.coroutines.async
3536
import kotlinx.coroutines.channels.BufferOverflow
3637
import kotlinx.coroutines.delay
@@ -125,6 +126,17 @@ internal class LSPProcessListener : ProcessListener {
125126

126127
override fun processTerminated(event: ProcessEvent) {
127128
LOG.info { "LSP process terminated with exit code ${event.exitCode}" }
129+
130+
// Check for CPU profile file after process termination
131+
val processId = ProcessHandle.current().pid()
132+
val profileDir = System.getProperty("java.io.tmpdir").trimEnd('/')
133+
val profilePath = "$profileDir/node-profile-$processId.cpuprofile"
134+
if (Files.exists(Path.of(profilePath))) {
135+
LOG.info { "CPU profile file created: $profilePath" }
136+
} else {
137+
LOG.warn { "CPU profile file not found at: $profilePath" }
138+
}
139+
128140
try {
129141
this.outputStreamWriter.close()
130142
this.outputStream.close()
@@ -463,8 +475,17 @@ private class AmazonQServerInstance(private val project: Project, private val cs
463475
val nodePath = getNodeRuntimePath(artifact.resolve(node))
464476
val emptyFile = Files.createTempFile("empty", null).toAbsolutePath().toString()
465477

478+
val processId = ProcessHandle.current().pid()
479+
val profileDir = System.getProperty("java.io.tmpdir").trimEnd('/')
480+
val profilePath = "node-profile-$processId"
481+
LOG.info { "Node.js CPU profile will be saved to: $profileDir $profilePath" }
482+
466483
val cmd = NodeExePatcher.patch(nodePath)
467484
.withParameters(
485+
"--cpu-prof",
486+
"--cpu-prof-dir=$profileDir",
487+
"--cpu-prof-name=$profilePath",
488+
// "--cpu-prof-name=node-profile-$processId.cpuprofile",
468489
LspSettings.getInstance().getArtifactPath() ?: artifact.resolve("aws-lsp-codewhisperer.js").toString(),
469490
"--stdio",
470491
"--set-credentials-encryption-key",
@@ -721,18 +742,28 @@ private class AmazonQServerInstance(private val project: Project, private val cs
721742
// otherwise can deadlock waiting for frozen flare process
722743
cs.launch {
723744
languageServer.apply {
724-
withTimeout(2000) {
745+
withTimeout(5000) {
725746
shutdown().await()
726747
exit()
727748
}
728749
}
729750
}.asCompletableFuture()
730-
.get(3000, TimeUnit.MILLISECONDS)
751+
.get(6000, TimeUnit.MILLISECONDS)
752+
} catch (e: CancellationException) {
753+
// Expected during shutdown, proceed with cleanup
754+
launcherHandler.process.destroy()
755+
Thread.sleep(500)
731756
} catch (e: Exception) {
732757
LOG.warn(e) { "LSP shutdown failed" }
733-
launcherHandler.killProcess()
758+
launcherHandler.process.destroy()
759+
Thread.sleep(500)
760+
} finally {
761+
if (!launcherHandler.isProcessTerminated) {
762+
launcherHandler.killProcess()
763+
}
734764
}
735765
} else if (!launcherHandler.isProcessTerminated) {
766+
Thread.sleep(500)
736767
launcherHandler.killProcess()
737768
}
738769
}

0 commit comments

Comments
 (0)