mirror of
https://github.com/slhaf/Partner.git
synced 2026-05-12 08:43:02 +08:00
feat(partnerctl): add --log-level option for run command and wire runtime log level to Partner-Core
This commit is contained in:
37
.idea/misc.xml
generated
37
.idea/misc.xml
generated
@@ -1,27 +1,28 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="EntryPointsManager">
|
<component name="EntryPointsManager">
|
||||||
<list size="20">
|
<list size="21">
|
||||||
<item index="0" class="java.lang.String" itemvalue="lombok.Data" />
|
<item index="0" class="java.lang.String" itemvalue="lombok.Data" />
|
||||||
<item index="1" class="java.lang.String" itemvalue="net.bytebuddy.implementation.bind.annotation.RuntimeType" />
|
<item index="1" class="java.lang.String" itemvalue="net.bytebuddy.implementation.bind.annotation.RuntimeType" />
|
||||||
<item index="2" class="java.lang.String" itemvalue="picocli.CommandLine.Command" />
|
<item index="2" class="java.lang.String" itemvalue="picocli.CommandLine.Command" />
|
||||||
<item index="3" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.capability.annotation.Capability" />
|
<item index="3" class="java.lang.String" itemvalue="picocli.CommandLine.Mixin" />
|
||||||
<item index="4" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityCore" />
|
<item index="4" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.capability.annotation.Capability" />
|
||||||
<item index="5" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityMethod" />
|
<item index="5" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityCore" />
|
||||||
<item index="6" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.capability.annotation.CoordinateManager" />
|
<item index="6" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityMethod" />
|
||||||
<item index="7" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.capability.annotation.Coordinated" />
|
<item index="7" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.capability.annotation.CoordinateManager" />
|
||||||
<item index="8" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.component.annotation.Init" />
|
<item index="8" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.capability.annotation.Coordinated" />
|
||||||
<item index="9" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.module.annotation.AfterExecute" />
|
<item index="9" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.component.annotation.Init" />
|
||||||
<item index="10" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.module.annotation.AgentRunningModule" />
|
<item index="10" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.module.annotation.AfterExecute" />
|
||||||
<item index="11" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule" />
|
<item index="11" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.module.annotation.AgentRunningModule" />
|
||||||
<item index="12" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.module.annotation.BeforeExecute" />
|
<item index="12" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule" />
|
||||||
<item index="13" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.module.annotation.Init" />
|
<item index="13" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.module.annotation.BeforeExecute" />
|
||||||
<item index="14" class="java.lang.String" itemvalue="work.slhaf.partner.api.capability.annotation.CapabilityMethod" />
|
<item index="14" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.module.annotation.Init" />
|
||||||
<item index="15" class="java.lang.String" itemvalue="work.slhaf.partner.api.capability.annotation.CoordinateManager" />
|
<item index="15" class="java.lang.String" itemvalue="work.slhaf.partner.api.capability.annotation.CapabilityMethod" />
|
||||||
<item index="16" class="java.lang.String" itemvalue="work.slhaf.partner.api.register.capability.annotation.Capability" />
|
<item index="16" class="java.lang.String" itemvalue="work.slhaf.partner.api.capability.annotation.CoordinateManager" />
|
||||||
<item index="17" class="java.lang.String" itemvalue="work.slhaf.partner.framework.agent.factory.capability.annotation.CapabilityCore" />
|
<item index="17" class="java.lang.String" itemvalue="work.slhaf.partner.api.register.capability.annotation.Capability" />
|
||||||
<item index="18" class="java.lang.String" itemvalue="work.slhaf.partner.framework.agent.factory.capability.annotation.CapabilityMethod" />
|
<item index="18" class="java.lang.String" itemvalue="work.slhaf.partner.framework.agent.factory.capability.annotation.CapabilityCore" />
|
||||||
<item index="19" class="java.lang.String" itemvalue="work.slhaf.partner.framework.agent.factory.component.annotation.AgentComponent" />
|
<item index="19" class="java.lang.String" itemvalue="work.slhaf.partner.framework.agent.factory.capability.annotation.CapabilityMethod" />
|
||||||
|
<item index="20" class="java.lang.String" itemvalue="work.slhaf.partner.framework.agent.factory.component.annotation.AgentComponent" />
|
||||||
</list>
|
</list>
|
||||||
<writeAnnotations>
|
<writeAnnotations>
|
||||||
<writeAnnotation name="work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability" />
|
<writeAnnotation name="work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability" />
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<configuration>
|
<configuration>
|
||||||
<property name="PARTNER_HOME" value="${PARTNER_HOME:-${user.home}/.partner}"/>
|
<property name="PARTNER_HOME" value="${PARTNER_HOME:-${user.home}/.partner}"/>
|
||||||
<property name="PARTNER_LOG_DIR" value="${PARTNER_HOME}/state/trace/log"/>
|
<property name="PARTNER_LOG_DIR" value="${PARTNER_HOME}/state/trace/log"/>
|
||||||
|
<property name="LOG_LEVEL" value="${PARTNER_LOG_LEVEL}:-${partner.log.level:-INFO}"/>
|
||||||
|
|
||||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
<encoder>
|
<encoder>
|
||||||
@@ -24,7 +25,7 @@
|
|||||||
</encoder>
|
</encoder>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<root level="DEBUG">
|
<root level="${LOG_LEVEL}">
|
||||||
<appender-ref ref="CONSOLE"/>
|
<appender-ref ref="CONSOLE"/>
|
||||||
<appender-ref ref="PARTNER_FILE"/>
|
<appender-ref ref="PARTNER_FILE"/>
|
||||||
</root>
|
</root>
|
||||||
|
|||||||
@@ -4,11 +4,7 @@ import picocli.CommandLine
|
|||||||
import work.slhaf.partner.ctl.commands.control.*
|
import work.slhaf.partner.ctl.commands.control.*
|
||||||
import work.slhaf.partner.ctl.i18n.I18n.text
|
import work.slhaf.partner.ctl.i18n.I18n.text
|
||||||
import work.slhaf.partner.ctl.support.CommandInterrupted
|
import work.slhaf.partner.ctl.support.CommandInterrupted
|
||||||
import java.io.OutputStream
|
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
|
||||||
import java.nio.file.StandardOpenOption
|
|
||||||
import java.time.LocalDateTime
|
|
||||||
|
|
||||||
@CommandLine.Command(
|
@CommandLine.Command(
|
||||||
name = "run",
|
name = "run",
|
||||||
@@ -26,6 +22,14 @@ class RunCommand : Runnable {
|
|||||||
)
|
)
|
||||||
var background: Boolean = false
|
var background: Boolean = false
|
||||||
|
|
||||||
|
@CommandLine.Option(
|
||||||
|
names = ["-l", "--log-level"],
|
||||||
|
descriptionKey = "cli.log.option.level.description",
|
||||||
|
defaultValue = "INFO",
|
||||||
|
converter = [LogLevelConverter::class],
|
||||||
|
)
|
||||||
|
lateinit var logLevel: LogLevel
|
||||||
|
|
||||||
override fun run() {
|
override fun run() {
|
||||||
val home = resolvePartnerHome()
|
val home = resolvePartnerHome()
|
||||||
val partnerJar = resolvePartnerJar(home)
|
val partnerJar = resolvePartnerJar(home)
|
||||||
@@ -35,98 +39,10 @@ class RunCommand : Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (background) {
|
if (background) {
|
||||||
runInBackground(home, partnerJar)
|
runInBackground(home, partnerJar, logLevel)
|
||||||
} else {
|
} else {
|
||||||
runInForeground(home, partnerJar)
|
runInForeground(home, partnerJar, logLevel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun runInForeground(home: Path, partnerJar: Path) {
|
|
||||||
val logFile = resolveLogFile(home)
|
|
||||||
Files.createDirectories(logFile.parent)
|
|
||||||
|
|
||||||
val process = createPartnerProcessBuilder(home, partnerJar)
|
|
||||||
.inheritIO()
|
|
||||||
.start()
|
|
||||||
|
|
||||||
appendControlLog(logFile, text("control.run.log.foregroundStarting", process.pid(), partnerJar))
|
|
||||||
|
|
||||||
val shutdownHook = Thread {
|
|
||||||
if (process.isAlive) {
|
|
||||||
process.destroy()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Runtime.getRuntime().addShutdownHook(shutdownHook)
|
|
||||||
|
|
||||||
val exitCode = process.waitFor()
|
|
||||||
runCatching { Runtime.getRuntime().removeShutdownHook(shutdownHook) }
|
|
||||||
appendControlLog(logFile, text("control.run.log.exited", exitCode))
|
|
||||||
|
|
||||||
if (exitCode != 0) {
|
|
||||||
throw CommandInterrupted(text("control.run.error.exited", exitCode), exitCode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun runInBackground(home: Path, partnerJar: Path) {
|
|
||||||
val pidFile = resolvePidFile(home)
|
|
||||||
val logFile = resolveLogFile(home)
|
|
||||||
val existingProcess = findPartnerProcesses(home, partnerJar).firstOrNull()
|
|
||||||
|
|
||||||
if (existingProcess != null) {
|
|
||||||
throw CommandInterrupted(text("control.run.error.alreadyRunning", existingProcess.pid()))
|
|
||||||
}
|
|
||||||
|
|
||||||
Files.createDirectories(pidFile.parent)
|
|
||||||
Files.createDirectories(logFile.parent)
|
|
||||||
|
|
||||||
val process = createPartnerProcessBuilder(home, partnerJar)
|
|
||||||
.redirectOutput(ProcessBuilder.Redirect.DISCARD)
|
|
||||||
.redirectError(ProcessBuilder.Redirect.DISCARD)
|
|
||||||
.start()
|
|
||||||
|
|
||||||
appendControlLog(logFile, text("control.run.log.backgroundStarting", process.pid(), partnerJar))
|
|
||||||
|
|
||||||
Thread.sleep(BACKGROUND_START_CHECK_MILLIS)
|
|
||||||
if (!process.isAlive) {
|
|
||||||
val exitCode = process.exitValue()
|
|
||||||
appendControlLog(logFile, text("control.run.log.exited", exitCode))
|
|
||||||
Files.deleteIfExists(pidFile)
|
|
||||||
throw CommandInterrupted(text("control.run.error.exited", exitCode), exitCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
Files.writeString(
|
|
||||||
pidFile,
|
|
||||||
process.pid().toString(),
|
|
||||||
StandardOpenOption.CREATE,
|
|
||||||
StandardOpenOption.TRUNCATE_EXISTING,
|
|
||||||
)
|
|
||||||
|
|
||||||
println(text("control.run.success.backgroundStarted", process.pid()))
|
|
||||||
println(text("control.run.info.logFile", logFile))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createPartnerProcessBuilder(home: Path, partnerJar: Path): ProcessBuilder {
|
|
||||||
return ProcessBuilder("java", "-DPARTNER_HOME=$home", "-jar", partnerJar.toString())
|
|
||||||
.apply {
|
|
||||||
environment()["PARTNER_HOME"] = home.toString()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun appendControlLog(logFile: Path, message: String) {
|
|
||||||
Files.createDirectories(logFile.parent)
|
|
||||||
Files.newOutputStream(
|
|
||||||
logFile,
|
|
||||||
StandardOpenOption.CREATE,
|
|
||||||
StandardOpenOption.APPEND,
|
|
||||||
).use { output ->
|
|
||||||
writeControlLog(output, message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun writeControlLog(output: OutputStream, message: String) {
|
|
||||||
output.write("[partnerctl ${LocalDateTime.now()}] $message\n".toByteArray())
|
|
||||||
output.flush()
|
|
||||||
}
|
|
||||||
|
|
||||||
private const val BACKGROUND_START_CHECK_MILLIS = 500L
|
|
||||||
|
|||||||
@@ -1,8 +1,14 @@
|
|||||||
package work.slhaf.partner.ctl.commands.control
|
package work.slhaf.partner.ctl.commands.control
|
||||||
|
|
||||||
|
import picocli.CommandLine
|
||||||
|
import work.slhaf.partner.ctl.i18n.I18n.text
|
||||||
|
import work.slhaf.partner.ctl.support.CommandInterrupted
|
||||||
|
import java.io.OutputStream
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
|
import java.nio.file.StandardOpenOption
|
||||||
|
import java.time.LocalDateTime
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import java.util.concurrent.TimeoutException
|
import java.util.concurrent.TimeoutException
|
||||||
|
|
||||||
@@ -25,7 +31,8 @@ fun resolvePidFile(home: Path): Path {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun resolveLogFile(home: Path): Path {
|
fun resolveLogFile(home: Path): Path {
|
||||||
return home.resolve("state").resolve("trace").resolve("log").resolve("partner-core.log").toAbsolutePath().normalize()
|
return home.resolve("state").resolve("trace").resolve("log").resolve("partner-core.log").toAbsolutePath()
|
||||||
|
.normalize()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findPartnerProcesses(home: Path, partnerJar: Path): List<ProcessHandle> {
|
fun findPartnerProcesses(home: Path, partnerJar: Path): List<ProcessHandle> {
|
||||||
@@ -95,3 +102,115 @@ private fun isPartnerProcess(process: ProcessHandle, partnerJar: Path): Boolean
|
|||||||
|
|
||||||
return arguments.any { it == jarPath } || commandLine.contains(jarPath)
|
return arguments.any { it == jarPath } || commandLine.contains(jarPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun runInForeground(home: Path, partnerJar: Path, logLevel: LogLevel) {
|
||||||
|
val logFile = resolveLogFile(home)
|
||||||
|
Files.createDirectories(logFile.parent)
|
||||||
|
|
||||||
|
val process = createPartnerProcessBuilder(home, partnerJar, logLevel)
|
||||||
|
.inheritIO()
|
||||||
|
.start()
|
||||||
|
|
||||||
|
appendControlLog(logFile, text("control.run.log.foregroundStarting", process.pid(), partnerJar))
|
||||||
|
|
||||||
|
val shutdownHook = Thread {
|
||||||
|
if (process.isAlive) {
|
||||||
|
process.destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Runtime.getRuntime().addShutdownHook(shutdownHook)
|
||||||
|
|
||||||
|
val exitCode = process.waitFor()
|
||||||
|
runCatching { Runtime.getRuntime().removeShutdownHook(shutdownHook) }
|
||||||
|
appendControlLog(logFile, text("control.run.log.exited", exitCode))
|
||||||
|
|
||||||
|
if (exitCode != 0) {
|
||||||
|
throw CommandInterrupted(text("control.run.error.exited", exitCode), exitCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun runInBackground(home: Path, partnerJar: Path, logLevel: LogLevel) {
|
||||||
|
val pidFile = resolvePidFile(home)
|
||||||
|
val logFile = resolveLogFile(home)
|
||||||
|
val existingProcess = findPartnerProcesses(home, partnerJar).firstOrNull()
|
||||||
|
|
||||||
|
if (existingProcess != null) {
|
||||||
|
throw CommandInterrupted(text("control.run.error.alreadyRunning", existingProcess.pid()))
|
||||||
|
}
|
||||||
|
|
||||||
|
Files.createDirectories(pidFile.parent)
|
||||||
|
Files.createDirectories(logFile.parent)
|
||||||
|
|
||||||
|
val process = createPartnerProcessBuilder(home, partnerJar, logLevel)
|
||||||
|
.redirectOutput(ProcessBuilder.Redirect.DISCARD)
|
||||||
|
.redirectError(ProcessBuilder.Redirect.DISCARD)
|
||||||
|
.start()
|
||||||
|
|
||||||
|
appendControlLog(logFile, text("control.run.log.backgroundStarting", process.pid(), partnerJar))
|
||||||
|
|
||||||
|
Thread.sleep(BACKGROUND_START_CHECK_MILLIS)
|
||||||
|
if (!process.isAlive) {
|
||||||
|
val exitCode = process.exitValue()
|
||||||
|
appendControlLog(logFile, text("control.run.log.exited", exitCode))
|
||||||
|
Files.deleteIfExists(pidFile)
|
||||||
|
throw CommandInterrupted(text("control.run.error.exited", exitCode), exitCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
Files.writeString(
|
||||||
|
pidFile,
|
||||||
|
process.pid().toString(),
|
||||||
|
StandardOpenOption.CREATE,
|
||||||
|
StandardOpenOption.TRUNCATE_EXISTING,
|
||||||
|
)
|
||||||
|
|
||||||
|
println(text("control.run.success.backgroundStarted", process.pid()))
|
||||||
|
println(text("control.run.info.logFile", logFile))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createPartnerProcessBuilder(home: Path, partnerJar: Path, logLevel: LogLevel): ProcessBuilder {
|
||||||
|
return ProcessBuilder(
|
||||||
|
"java",
|
||||||
|
"-Dpartner.log.level=${logLevel.name.uppercase()}",
|
||||||
|
"-DPARTNER_HOME=$home",
|
||||||
|
"-jar",
|
||||||
|
partnerJar.toString()
|
||||||
|
)
|
||||||
|
.apply {
|
||||||
|
environment()["PARTNER_HOME"] = home.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun appendControlLog(logFile: Path, message: String) {
|
||||||
|
Files.createDirectories(logFile.parent)
|
||||||
|
Files.newOutputStream(
|
||||||
|
logFile,
|
||||||
|
StandardOpenOption.CREATE,
|
||||||
|
StandardOpenOption.APPEND,
|
||||||
|
).use { output ->
|
||||||
|
writeControlLog(output, message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun writeControlLog(output: OutputStream, message: String) {
|
||||||
|
output.write("[partnerctl ${LocalDateTime.now()}] $message\n".toByteArray())
|
||||||
|
output.flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
private const val BACKGROUND_START_CHECK_MILLIS = 500L
|
||||||
|
|
||||||
|
enum class LogLevel {
|
||||||
|
TRACE, DEBUG, INFO, WARN, ERROR
|
||||||
|
}
|
||||||
|
|
||||||
|
class LogLevelConverter : CommandLine.ITypeConverter<LogLevel> {
|
||||||
|
override fun convert(value: String): LogLevel {
|
||||||
|
return LogLevel.entries.firstOrNull {
|
||||||
|
it.name.equals(value, ignoreCase = true)
|
||||||
|
} ?: throw CommandLine.TypeConversionException(
|
||||||
|
"invalid log level '$value'. Valid values: ${
|
||||||
|
LogLevel.entries.joinToString(", ") { it.name.lowercase() }
|
||||||
|
}"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ cli.shutdown.option.force.description=Forcefully kill matching Partner process i
|
|||||||
cli.log.description=Show Partner logs.
|
cli.log.description=Show Partner logs.
|
||||||
cli.log.option.tail.description=Number of log lines to show before exiting or following.
|
cli.log.option.tail.description=Number of log lines to show before exiting or following.
|
||||||
cli.log.option.follow.description=Follow appended log output.
|
cli.log.option.follow.description=Follow appended log output.
|
||||||
|
cli.log.option.level.description=Set Partner runtime log level. Available values: TRACE, DEBUG, INFO, WARN, ERROR. Default: INFO.
|
||||||
cli.chat.description=Start an interactive chat client.
|
cli.chat.description=Start an interactive chat client.
|
||||||
cli.config.description=Manage Partner configuration.
|
cli.config.description=Manage Partner configuration.
|
||||||
cli.module.description=Manage Partner modules.
|
cli.module.description=Manage Partner modules.
|
||||||
|
|||||||
@@ -2,12 +2,13 @@ cli.partnerctl.description=Partner 命令行工具。
|
|||||||
cli.init.description=初始化 Partner agent。
|
cli.init.description=初始化 Partner agent。
|
||||||
cli.run.description=启动 Partner agent。
|
cli.run.description=启动 Partner agent。
|
||||||
cli.run.option.background.description=后台运行 Partner。
|
cli.run.option.background.description=后台运行 Partner。
|
||||||
cli.shutdown.description=停止 Partner agent。
|
|
||||||
cli.shutdown.option.timeout.description=优雅停止后等待的秒数,超时后失败或强制停止。
|
cli.shutdown.option.timeout.description=优雅停止后等待的秒数,超时后失败或强制停止。
|
||||||
cli.shutdown.option.force.description=如果匹配的 Partner 进程没有在超时前退出,则强制结束进程。
|
cli.shutdown.option.force.description=如果匹配的 Partner 进程没有在超时前退出,则强制结束进程。
|
||||||
cli.log.description=查看 Partner 日志。
|
cli.log.description=查看 Partner 日志。
|
||||||
cli.log.option.tail.description=退出或 follow 前显示的日志行数。
|
cli.log.option.tail.description=退出或 follow 前显示的日志行数。
|
||||||
cli.log.option.follow.description=持续跟随新增日志输出。
|
cli.log.option.follow.description=持续跟随新增日志输出。
|
||||||
|
cli.log.option.level.description=指定 Partner 运行时日志等级。可选值:TRACE、DEBUG、INFO、WARN、ERROR。默认值:INFO。
|
||||||
|
cli.shutdown.description=停止 Partner agent。
|
||||||
cli.chat.description=启动交互式聊天客户端。
|
cli.chat.description=启动交互式聊天客户端。
|
||||||
cli.config.description=管理 Partner 配置。
|
cli.config.description=管理 Partner 配置。
|
||||||
cli.module.description=管理 Partner 模块。
|
cli.module.description=管理 Partner 模块。
|
||||||
|
|||||||
Reference in New Issue
Block a user