Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix log formatting #313

Merged
merged 6 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
package com.jetbrains.rider.aspire.services

import com.intellij.execution.filters.TextConsoleBuilderFactory
import com.intellij.execution.process.ProcessHandler
import com.intellij.execution.process.ProcessOutputTypes
import com.intellij.execution.services.ServiceEventListener
import com.intellij.execution.ui.ConsoleView
import com.intellij.execution.ui.ConsoleViewContentType
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.EDT
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Disposer
import com.intellij.terminal.TerminalExecutionConsole
import com.jetbrains.rd.util.lifetime.Lifetime
import com.jetbrains.rider.aspire.generated.*
import com.jetbrains.rider.aspire.util.getServiceInstanceId
import com.jetbrains.rider.aspire.util.parseLogEntry
import com.jetbrains.rider.debugger.DebuggerWorkerProcessHandler
import com.jetbrains.rider.run.ConsoleKind
import com.jetbrains.rider.run.createConsole
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.datetime.Instant
Expand Down Expand Up @@ -97,11 +95,14 @@ class AspireResource(
var isUnderDebugger: Boolean? = null
private set

var consoleView: ConsoleView = TextConsoleBuilderFactory
.getInstance()
.createBuilder(project)
.apply { setViewer(true) }
.console
private val logProcessHandler = object : ProcessHandler() {
override fun destroyProcessImpl() {}
override fun detachProcessImpl() {}
override fun detachIsDefault() = false
override fun getProcessInput() = null
}
private val logConsole = TerminalExecutionConsole(project, logProcessHandler)
val logConsoleComponent = logConsole.component

init {
val model = modelWrapper.model.valueOrNull
Expand All @@ -128,7 +129,9 @@ class AspireResource(
modelWrapper.model.advise(lifetime, ::update)
modelWrapper.logReceived.advise(lifetime, ::logReceived)

Disposer.register(this, consoleView)
logProcessHandler.startNotify()

Disposer.register(this, logConsole)

project.messageBus.syncPublisher(ResourceListener.TOPIC).resourceCreated(this)

Expand Down Expand Up @@ -234,22 +237,7 @@ class AspireResource(
fun setHandler(processHandler: ProcessHandler) {
if (type != ResourceType.Project) return

val handler =
if (processHandler is DebuggerWorkerProcessHandler) {
isUnderDebugger = true
processHandler.debuggerWorkerRealHandler
}
else {
isUnderDebugger = false
processHandler
}
val console = createConsole(
ConsoleKind.Normal,
handler,
project
)
Disposer.register(this, console)
consoleView = console
isUnderDebugger = processHandler is DebuggerWorkerProcessHandler

sendServiceChildrenChangedEvent()
}
Expand All @@ -267,13 +255,9 @@ class AspireResource(
}

private fun logReceived(log: ResourceLog) {
if (type == ResourceType.Project) return

consoleView.print(
log.text + "\n",
if (!log.isError) ConsoleViewContentType.NORMAL_OUTPUT
else ConsoleViewContentType.ERROR_OUTPUT
)
val outputType = if (!log.isError) ProcessOutputTypes.STDOUT else ProcessOutputTypes.STDERR
val (_, logContent) = parseLogEntry(log.text) ?: return
logProcessHandler.notifyTextAvailable(logContent + "\r\n", outputType)
}

private fun sendServiceStructureChangedEvent() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ import com.jetbrains.rider.aspire.services.AspireResource
class ResourceConsolePanel(resourceService: AspireResource) : BorderLayoutPanel() {
init {
border = JBUI.Borders.empty()
add(resourceService.consoleView.component)
add(resourceService.logConsoleComponent)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ class SessionExecutableFactory(private val project: Project) {
null,
"",
!executablePath.endsWith(".dll", true),
DotNetCoreRuntimeType
DotNetCoreRuntimeType,
usePty = false
) to browserSettings
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import com.jetbrains.rd.util.lifetime.isNotAlive
import com.jetbrains.rider.aspire.generated.SessionModel
import com.jetbrains.rider.aspire.run.AspireHostConfig
import com.jetbrains.rider.aspire.run.AspireHostConfiguration
import com.jetbrains.rider.aspire.util.decodeAnsiCommandsToString
import com.jetbrains.rider.build.BuildParameters
import com.jetbrains.rider.build.tasks.BuildTaskThrottler
import com.jetbrains.rider.debugger.DebuggerWorkerProcessHandler
Expand Down Expand Up @@ -129,7 +128,10 @@ class SessionManager(private val project: Project, scope: CoroutineScope) {
}

override fun onTextAvailable(event: ProcessEvent, outputType: Key<*>) {
val text = decodeAnsiCommandsToString(event.text, outputType)
val text =
if (event.text.endsWith("\r\n")) event.text.substring(0, event.text.length - 2)
else if (event.text.endsWith("\n")) event.text.substring(0, event.text.length - 1)
else event.text
val isStdErr = outputType == ProcessOutputType.STDERR
sessionEvents.tryEmit(SessionLogReceived(sessionId, isStdErr, text))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.intellij.execution.configurations.GeneralCommandLine
import com.intellij.execution.process.ProcessListener
import com.intellij.execution.runners.ExecutionEnvironment
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.util.Key
import com.jetbrains.rd.util.lifetime.Lifetime
import com.jetbrains.rider.debugger.DebuggerHelperHost
import com.jetbrains.rider.debugger.DebuggerWorkerProcessHandler
Expand Down Expand Up @@ -51,7 +52,19 @@ open class ProjectSessionDebugProfileState(
protocolServerPort: Int,
projectLifetime: Lifetime
): DebuggerWorkerProcessHandler {
val processHandler = TerminalProcessHandler(project, workerCmd, createPresentableCommandLine(), false)
val presentableCommandLine = createPresentableCommandLine()
val processHandler = object : TerminalProcessHandler(
project,
workerCmd,
presentableCommandLine,
false
) {
override fun notifyTextAvailable(text: String, outputType: Key<*>) {
val modifiedText = text.lineSequence().joinToString("\r\n")
super.notifyTextAvailable(modifiedText, outputType)
}
}

val debuggerWorkerProcessHandler = DebuggerWorkerProcessHandler(
processHandler,
protocolModel,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import com.intellij.execution.process.ProcessListener
import com.intellij.execution.runners.ExecutionEnvironment
import com.intellij.execution.runners.ProgramRunner
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.util.Key
import com.jetbrains.rd.util.lifetime.Lifetime
import com.jetbrains.rider.run.ConsoleKind
import com.jetbrains.rider.run.TerminalProcessHandler
Expand Down Expand Up @@ -37,12 +38,17 @@ class ProjectSessionRunProfileState(
): ExecutionResult {
val commandLine = dotnetExecutable.createRunCommandLine(dotnetRuntime)
val originalExecutable = Path(commandLine.exePath)
val processHandler = TerminalProcessHandler(
val processHandler = object : TerminalProcessHandler(
environment.project,
commandLine,
commandLine.commandLineString,
originalExecutable = originalExecutable
)
) {
override fun notifyTextAvailable(text: String, outputType: Key<*>) {
val modifiedText = text.lineSequence().joinToString("\r\n")
super.notifyTextAvailable(modifiedText, outputType)
}
}

sessionProcessLifetime.onTermination {
if (!processHandler.isProcessTerminating && !processHandler.isProcessTerminated) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.jetbrains.rider.aspire.util

private const val YEAR = "(\\d{4})"
private const val MONTH = "(0[1-9]|1[0-2])"
private const val DAY = "(0[1-9]|[12][0-9]|3[01])"
private const val HOUR = "([01][0-9]|2[0-3])"
private const val MINUTES = "([0-5][0-9])"
private const val SECONDS = "([0-5][0-9])"
private const val PARTIAL_SECONDS = "(\\.\\d{1,9})?"
private const val TIME_ZONE = "(Z|([Z+-]([01][0-9]|2[0-3]):([0-5][0-9])))?"

private const val PATTERN = "^$YEAR-$MONTH-${DAY}T$HOUR:$MINUTES:$SECONDS$PARTIAL_SECONDS$TIME_ZONE"
private val regex = Regex(PATTERN)

fun parseLogEntry(logEntry: String): Pair<String, String>? {
val match = regex.find(logEntry)
if (match == null) return null

val timestamp = match.value
val logContent =
if (logEntry.length > match.range.last + 2 && logEntry[match.range.last + 1] == ' ')
logEntry.substring(match.range.last + 2)
else if (logEntry.length > match.range.last + 1)
logEntry.substring(match.range.last + 1)
else ""

return timestamp to logContent
}
Loading