mirror of
https://github.com/enso-org/enso.git
synced 2024-12-22 23:01:29 +03:00
Always create events log when profiling (#8337)
Changelog: - update: always create an event log next to the profiling file when the engine is started with the `--profiling-path` flag - remove: `--profiling-events-log-path` flag
This commit is contained in:
parent
705d6f192c
commit
53d1f727da
@ -15,7 +15,7 @@ Start `project-manager` with following options to record first 20s of the Enso
|
|||||||
engine startup sequence:
|
engine startup sequence:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ project-manager --profiling-events-log-path=start.log --profiling-path=start.npss --profiling-time=20
|
$ project-manager --profiling-path=start.npss --profiling-time=20
|
||||||
```
|
```
|
||||||
|
|
||||||
Let the IDE connect to just launched `project-manager` - e.g. start the IDE with
|
Let the IDE connect to just launched `project-manager` - e.g. start the IDE with
|
||||||
|
@ -171,7 +171,7 @@ class MainModule(serverConfig: LanguageServerConfig, logLevel: Level) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
val runtimeEventsMonitor =
|
val runtimeEventsMonitor =
|
||||||
languageServerConfig.profiling.runtimeEventsLogPath match {
|
languageServerConfig.profiling.profilingEventsLogPath match {
|
||||||
case Some(path) =>
|
case Some(path) =>
|
||||||
val out = new PrintStream(path.toFile, StandardCharsets.UTF_8)
|
val out = new PrintStream(path.toFile, StandardCharsets.UTF_8)
|
||||||
new RuntimeEventsMonitor(out)
|
new RuntimeEventsMonitor(out)
|
||||||
|
@ -1,18 +1,41 @@
|
|||||||
package org.enso.languageserver.boot
|
package org.enso.languageserver.boot
|
||||||
|
|
||||||
|
import org.apache.commons.io.FilenameUtils
|
||||||
|
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
|
||||||
import scala.concurrent.duration.FiniteDuration
|
import scala.concurrent.duration.FiniteDuration
|
||||||
|
|
||||||
/** Application profiling configuration.
|
/** Application profiling configuration.
|
||||||
*
|
*
|
||||||
* @param runtimeEventsLogPath the path to the runtime events log file
|
|
||||||
* @param profilingPath the path to the profiling output file
|
* @param profilingPath the path to the profiling output file
|
||||||
* @param profilingTime limit the profiling duration, as an infinite profiling
|
* @param profilingTime limit the profiling duration, as an infinite profiling
|
||||||
* duration may cause out-of-memory errors.
|
* duration may cause out-of-memory errors.
|
||||||
*/
|
*/
|
||||||
case class ProfilingConfig(
|
case class ProfilingConfig(
|
||||||
runtimeEventsLogPath: Option[Path] = None,
|
|
||||||
profilingPath: Option[Path] = None,
|
profilingPath: Option[Path] = None,
|
||||||
profilingTime: Option[FiniteDuration] = None
|
profilingTime: Option[FiniteDuration] = None
|
||||||
)
|
) {
|
||||||
|
|
||||||
|
/** Creates the path to the runtime events log with the same name as
|
||||||
|
* `profilingPath` but with the `.log` extension.
|
||||||
|
*
|
||||||
|
* @return the path to the runtime events log file
|
||||||
|
*/
|
||||||
|
def profilingEventsLogPath: Option[Path] =
|
||||||
|
profilingPath.map { path =>
|
||||||
|
val profilingDirectory = path.getParent
|
||||||
|
val profilingFileName = path.getFileName.toString
|
||||||
|
val profilingFileExtension = FilenameUtils.getExtension(profilingFileName)
|
||||||
|
val eventsLogFileName =
|
||||||
|
profilingFileName.stripSuffix(
|
||||||
|
profilingFileExtension
|
||||||
|
) + ProfilingConfig.EventsLogExtension
|
||||||
|
|
||||||
|
profilingDirectory.resolve(eventsLogFileName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
object ProfilingConfig {
|
||||||
|
|
||||||
|
private val EventsLogExtension = "log"
|
||||||
|
}
|
||||||
|
@ -54,8 +54,6 @@ object Main {
|
|||||||
private val PROFILING_PATH = "profiling-path"
|
private val PROFILING_PATH = "profiling-path"
|
||||||
private val PROFILING_TIME = "profiling-time"
|
private val PROFILING_TIME = "profiling-time"
|
||||||
private val LANGUAGE_SERVER_OPTION = "server"
|
private val LANGUAGE_SERVER_OPTION = "server"
|
||||||
private val LANGUAGE_SERVER_PROFILING_EVENTS_LOG_PATH =
|
|
||||||
"server-profiling-events-log-path"
|
|
||||||
private val DAEMONIZE_OPTION = "daemon"
|
private val DAEMONIZE_OPTION = "daemon"
|
||||||
private val INTERFACE_OPTION = "interface"
|
private val INTERFACE_OPTION = "interface"
|
||||||
private val RPC_PORT_OPTION = "rpc-port"
|
private val RPC_PORT_OPTION = "rpc-port"
|
||||||
@ -201,16 +199,9 @@ object Main {
|
|||||||
.longOpt(PROFILING_TIME)
|
.longOpt(PROFILING_TIME)
|
||||||
.desc("The duration in seconds limiting the profiling time.")
|
.desc("The duration in seconds limiting the profiling time.")
|
||||||
.build()
|
.build()
|
||||||
val lsProfilingEventsLogPathOption = CliOption.builder
|
|
||||||
.hasArg(true)
|
|
||||||
.numberOfArgs(1)
|
|
||||||
.argName("file")
|
|
||||||
.longOpt(LANGUAGE_SERVER_PROFILING_EVENTS_LOG_PATH)
|
|
||||||
.desc("The path to the runtime events log file.")
|
|
||||||
.build()
|
|
||||||
val deamonizeOption = CliOption.builder
|
val deamonizeOption = CliOption.builder
|
||||||
.longOpt(DAEMONIZE_OPTION)
|
.longOpt(DAEMONIZE_OPTION)
|
||||||
.desc("Deamonize Language Server")
|
.desc("Daemonize Language Server")
|
||||||
.build()
|
.build()
|
||||||
val interfaceOption = CliOption.builder
|
val interfaceOption = CliOption.builder
|
||||||
.longOpt(INTERFACE_OPTION)
|
.longOpt(INTERFACE_OPTION)
|
||||||
@ -427,7 +418,6 @@ object Main {
|
|||||||
.addOption(lsOption)
|
.addOption(lsOption)
|
||||||
.addOption(lsProfilingPathOption)
|
.addOption(lsProfilingPathOption)
|
||||||
.addOption(lsProfilingTimeOption)
|
.addOption(lsProfilingTimeOption)
|
||||||
.addOption(lsProfilingEventsLogPathOption)
|
|
||||||
.addOption(deamonizeOption)
|
.addOption(deamonizeOption)
|
||||||
.addOption(interfaceOption)
|
.addOption(interfaceOption)
|
||||||
.addOption(rpcPortOption)
|
.addOption(rpcPortOption)
|
||||||
@ -1026,16 +1016,7 @@ object Main {
|
|||||||
profilingTime <- Either
|
profilingTime <- Either
|
||||||
.catchNonFatal(profilingTimeStr.map(_.toInt.seconds))
|
.catchNonFatal(profilingTimeStr.map(_.toInt.seconds))
|
||||||
.leftMap(_ => "Profiling time should be an integer")
|
.leftMap(_ => "Profiling time should be an integer")
|
||||||
profilingEventsLogPathStr =
|
} yield ProfilingConfig(profilingPath, profilingTime)
|
||||||
Option(line.getOptionValue(LANGUAGE_SERVER_PROFILING_EVENTS_LOG_PATH))
|
|
||||||
profilingEventsLogPath <- Either
|
|
||||||
.catchNonFatal(profilingEventsLogPathStr.map(Paths.get(_)))
|
|
||||||
.leftMap(_ => "Profiling events log path is invalid")
|
|
||||||
} yield ProfilingConfig(
|
|
||||||
profilingEventsLogPath,
|
|
||||||
profilingPath,
|
|
||||||
profilingTime
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Prints the version of the Enso executable.
|
/** Prints the version of the Enso executable.
|
||||||
|
@ -7,14 +7,13 @@ import scala.util.Try
|
|||||||
|
|
||||||
object Cli {
|
object Cli {
|
||||||
|
|
||||||
val JSON_OPTION = "json"
|
val JSON_OPTION = "json"
|
||||||
val HELP_OPTION = "help"
|
val HELP_OPTION = "help"
|
||||||
val NO_LOG_MASKING = "no-log-masking"
|
val NO_LOG_MASKING = "no-log-masking"
|
||||||
val VERBOSE_OPTION = "verbose"
|
val VERBOSE_OPTION = "verbose"
|
||||||
val VERSION_OPTION = "version"
|
val VERSION_OPTION = "version"
|
||||||
val PROFILING_PATH = "profiling-path"
|
val PROFILING_PATH = "profiling-path"
|
||||||
val PROFILING_TIME = "profiling-time"
|
val PROFILING_TIME = "profiling-time"
|
||||||
val PROFILING_EVENTS_LOG_PATH = "profiling-events-log-path"
|
|
||||||
|
|
||||||
object option {
|
object option {
|
||||||
|
|
||||||
@ -64,16 +63,6 @@ object Cli {
|
|||||||
.longOpt(PROFILING_TIME)
|
.longOpt(PROFILING_TIME)
|
||||||
.desc("The duration in seconds limiting the application profiling time.")
|
.desc("The duration in seconds limiting the application profiling time.")
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
val profilingEventsLogPath: cli.Option = cli.Option.builder
|
|
||||||
.hasArg(true)
|
|
||||||
.numberOfArgs(1)
|
|
||||||
.argName("file")
|
|
||||||
.longOpt(PROFILING_EVENTS_LOG_PATH)
|
|
||||||
.desc(
|
|
||||||
"The path to the runtime events log file. Enables the runtime events logging."
|
|
||||||
)
|
|
||||||
.build()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val options: cli.Options =
|
val options: cli.Options =
|
||||||
@ -85,7 +74,6 @@ object Cli {
|
|||||||
.addOption(option.noLogMasking)
|
.addOption(option.noLogMasking)
|
||||||
.addOption(option.profilingPath)
|
.addOption(option.profilingPath)
|
||||||
.addOption(option.profilingTime)
|
.addOption(option.profilingTime)
|
||||||
.addOption(option.profilingEventsLogPath)
|
|
||||||
|
|
||||||
/** Parse the command line options. */
|
/** Parse the command line options. */
|
||||||
def parse(args: Array[String]): Either[String, cli.CommandLine] = {
|
def parse(args: Array[String]): Either[String, cli.CommandLine] = {
|
||||||
|
@ -189,37 +189,10 @@ object ProjectManager extends ZIOAppDefault with LazyLogging {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val parseProfilingEventsLogPath = ZIO
|
|
||||||
.attempt {
|
|
||||||
Option(options.getOptionValue(Cli.PROFILING_EVENTS_LOG_PATH))
|
|
||||||
.map(Paths.get(_).toAbsolutePath)
|
|
||||||
}
|
|
||||||
.flatMap {
|
|
||||||
case pathOpt @ Some(path) =>
|
|
||||||
ZIO.ifZIO(ZIO.attempt(Files.isDirectory(path)))(
|
|
||||||
onTrue = printLineError(
|
|
||||||
s"Error: ${Cli.PROFILING_EVENTS_LOG_PATH} is a directory: $path"
|
|
||||||
) *>
|
|
||||||
ZIO.fail(new FileAlreadyExistsException(path.toString)),
|
|
||||||
onFalse = ZIO.succeed(pathOpt)
|
|
||||||
)
|
|
||||||
case None =>
|
|
||||||
ZIO.succeed(None)
|
|
||||||
}
|
|
||||||
.catchAll { err =>
|
|
||||||
printLineError(s"Invalid ${Cli.PROFILING_EVENTS_LOG_PATH} argument.") *>
|
|
||||||
ZIO.fail(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
profilingEventsLogPath <- parseProfilingEventsLogPath
|
profilingPath <- parseProfilingPath
|
||||||
profilingPath <- parseProfilingPath
|
profilingTime <- parseProfilingTime
|
||||||
profilingTime <- parseProfilingTime
|
} yield ProjectManagerOptions(profilingPath, profilingTime)
|
||||||
} yield ProjectManagerOptions(
|
|
||||||
profilingEventsLogPath,
|
|
||||||
profilingPath,
|
|
||||||
profilingTime
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The main function of the application, which will be passed the command-line
|
/** The main function of the application, which will be passed the command-line
|
||||||
@ -240,7 +213,6 @@ object ProjectManager extends ZIOAppDefault with LazyLogging {
|
|||||||
logLevel <- setupLogging(verbosity, logMasking)
|
logLevel <- setupLogging(verbosity, logMasking)
|
||||||
procConf = MainProcessConfig(
|
procConf = MainProcessConfig(
|
||||||
logLevel,
|
logLevel,
|
||||||
opts.profilingRuntimeEventsLog,
|
|
||||||
opts.profilingPath,
|
opts.profilingPath,
|
||||||
opts.profilingTime
|
opts.profilingTime
|
||||||
)
|
)
|
||||||
@ -271,7 +243,7 @@ object ProjectManager extends ZIOAppDefault with LazyLogging {
|
|||||||
()
|
()
|
||||||
}
|
}
|
||||||
.catchAll { exception =>
|
.catchAll { exception =>
|
||||||
printLineError(s"Failed to setup logger: ${exception.getMessage()}")
|
printLineError(s"Failed to setup logger: ${exception.getMessage}")
|
||||||
}
|
}
|
||||||
.as(level)
|
.as(level)
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,10 @@ import scala.concurrent.duration.FiniteDuration
|
|||||||
|
|
||||||
/** The runtime options.
|
/** The runtime options.
|
||||||
*
|
*
|
||||||
* @param profilingRuntimeEventsLog the path to the runtime events log file
|
|
||||||
* @param profilingPath the path to the profiling output file
|
* @param profilingPath the path to the profiling output file
|
||||||
* @param profilingTime the time limiting the profiling duration
|
* @param profilingTime the time limiting the profiling duration
|
||||||
*/
|
*/
|
||||||
case class ProjectManagerOptions(
|
case class ProjectManagerOptions(
|
||||||
profilingRuntimeEventsLog: Option[Path],
|
|
||||||
profilingPath: Option[Path],
|
profilingPath: Option[Path],
|
||||||
profilingTime: Option[FiniteDuration]
|
profilingTime: Option[FiniteDuration]
|
||||||
)
|
)
|
||||||
|
@ -12,13 +12,11 @@ object configuration {
|
|||||||
* main project manager process.
|
* main project manager process.
|
||||||
*
|
*
|
||||||
* @param logLevel the logging level
|
* @param logLevel the logging level
|
||||||
* @param profilingEventsLogPath the path to the runtime events log file
|
|
||||||
* @param profilingPath the path to the profiling out file
|
* @param profilingPath the path to the profiling out file
|
||||||
* @param profilingTime the time limiting the profiling duration
|
* @param profilingTime the time limiting the profiling duration
|
||||||
*/
|
*/
|
||||||
case class MainProcessConfig(
|
case class MainProcessConfig(
|
||||||
logLevel: Level,
|
logLevel: Level,
|
||||||
profilingEventsLogPath: Option[Path],
|
|
||||||
profilingPath: Option[Path],
|
profilingPath: Option[Path],
|
||||||
profilingTime: Option[FiniteDuration]
|
profilingTime: Option[FiniteDuration]
|
||||||
)
|
)
|
||||||
|
@ -107,18 +107,12 @@ object ExecutorWithUnlimitedPool extends LanguageServerExecutor {
|
|||||||
val profilingTimeArguments =
|
val profilingTimeArguments =
|
||||||
descriptor.profilingTime.toSeq
|
descriptor.profilingTime.toSeq
|
||||||
.flatMap(time => Seq("--profiling-time", time.toSeconds.toString))
|
.flatMap(time => Seq("--profiling-time", time.toSeconds.toString))
|
||||||
val profilingEventsLogPathArguments =
|
|
||||||
descriptor.profilingEventsLogPath.toSeq
|
|
||||||
.flatMap(path =>
|
|
||||||
Seq("--server-profiling-events-log-path", path.toString)
|
|
||||||
)
|
|
||||||
val startupArgs =
|
val startupArgs =
|
||||||
if (descriptor.skipGraalVMUpdater) Seq("--skip-graalvm-updater")
|
if (descriptor.skipGraalVMUpdater) Seq("--skip-graalvm-updater")
|
||||||
else Seq()
|
else Seq()
|
||||||
val additionalArguments =
|
val additionalArguments =
|
||||||
profilingPathArguments ++
|
profilingPathArguments ++
|
||||||
profilingTimeArguments ++
|
profilingTimeArguments ++
|
||||||
profilingEventsLogPathArguments ++
|
|
||||||
startupArgs
|
startupArgs
|
||||||
val runSettings = runner
|
val runSettings = runner
|
||||||
.startLanguageServer(
|
.startLanguageServer(
|
||||||
|
@ -86,7 +86,6 @@ class LanguageServerController(
|
|||||||
engineVersion = engineVersion,
|
engineVersion = engineVersion,
|
||||||
jvmSettings = distributionConfiguration.defaultJVMSettings,
|
jvmSettings = distributionConfiguration.defaultJVMSettings,
|
||||||
discardOutput = distributionConfiguration.shouldDiscardChildOutput,
|
discardOutput = distributionConfiguration.shouldDiscardChildOutput,
|
||||||
profilingEventsLogPath = processConfig.profilingEventsLogPath,
|
|
||||||
profilingPath = processConfig.profilingPath,
|
profilingPath = processConfig.profilingPath,
|
||||||
profilingTime = processConfig.profilingTime,
|
profilingTime = processConfig.profilingTime,
|
||||||
deferredLoggingServiceEndpoint = loggingServiceDescriptor.getEndpoint,
|
deferredLoggingServiceEndpoint = loggingServiceDescriptor.getEndpoint,
|
||||||
|
@ -24,7 +24,6 @@ import scala.concurrent.duration.FiniteDuration
|
|||||||
* @param jvmSettings settings to use for the JVM that will host the engine
|
* @param jvmSettings settings to use for the JVM that will host the engine
|
||||||
* @param discardOutput specifies if the process output should be discarded or
|
* @param discardOutput specifies if the process output should be discarded or
|
||||||
* printed to parent's streams
|
* printed to parent's streams
|
||||||
* @param profilingEventsLogPath the path to the runtime events log file
|
|
||||||
* @param profilingPath the language server profiling file path
|
* @param profilingPath the language server profiling file path
|
||||||
* @param profilingTime the time limiting the profiling duration
|
* @param profilingTime the time limiting the profiling duration
|
||||||
* @param deferredLoggingServiceEndpoint a future that is completed once the
|
* @param deferredLoggingServiceEndpoint a future that is completed once the
|
||||||
@ -44,7 +43,6 @@ case class LanguageServerDescriptor(
|
|||||||
engineVersion: SemVer,
|
engineVersion: SemVer,
|
||||||
jvmSettings: JVMSettings,
|
jvmSettings: JVMSettings,
|
||||||
discardOutput: Boolean,
|
discardOutput: Boolean,
|
||||||
profilingEventsLogPath: Option[Path],
|
|
||||||
profilingPath: Option[Path],
|
profilingPath: Option[Path],
|
||||||
profilingTime: Option[FiniteDuration],
|
profilingTime: Option[FiniteDuration],
|
||||||
deferredLoggingServiceEndpoint: Future[Option[URI]],
|
deferredLoggingServiceEndpoint: Future[Option[URI]],
|
||||||
|
@ -87,10 +87,9 @@ class BaseServerSpec extends JsonRpcServerTestKit with BeforeAndAfterAll {
|
|||||||
|
|
||||||
val processConfig: MainProcessConfig =
|
val processConfig: MainProcessConfig =
|
||||||
MainProcessConfig(
|
MainProcessConfig(
|
||||||
logLevel = if (debugLogs) Level.TRACE else Level.ERROR,
|
logLevel = if (debugLogs) Level.TRACE else Level.ERROR,
|
||||||
profilingPath = profilingPath,
|
profilingPath = profilingPath,
|
||||||
profilingTime = None,
|
profilingTime = None
|
||||||
profilingEventsLogPath = None
|
|
||||||
)
|
)
|
||||||
|
|
||||||
val testClock =
|
val testClock =
|
||||||
|
Loading…
Reference in New Issue
Block a user