tts-server-android 插件脚本 Console 日志输出指南:新版 console 与旧版 logger API 全解析

原创2026-10-01 10:06:421,450 阅读
文章标签:语音后端音频

tts-server-android 插件脚本 Console 日志输出指南:新版 console 与旧版 logger API 全解析

导读

tts-server-android 为插件脚本、语音规则脚本等 JS 运行时内置了一套完整的日志输出体系,即本文要讲解的 Console(控制台)运行时 API。它同时提供新版 console.log/debug/info/warn/error/trace 与旧版 logger.t/d/i/w/e 两套调用方式,并支持 %s 占位符格式化、日志级别着色、调用栈输出以及 UI 悬浮日志窗口实时展示。读完本文,你将掌握在插件与规则脚本中正确输出分级日志、格式化调试信息、查看调用栈以及理解日志从脚本到界面的完整链路。

本文基于官方帮助文档 console.md,并结合 lib-script 模块源码、应用层 UI 与测试用例展开深度解读。

一、Console API 概览:两套调用方式并存

官方帮助文档 console.md 给出的核心示例完整覆盖了两代 API:

// ---- 新版 console API ----
console.log("format: %s", "str")
console.debug("format: %s", 123)
console.info("123", "223", 323)
console.warn("warn", 123)
console.error("error", 200)
console.trace("trace")

// ---- 旧版 logger API ----
logger.t("t")
logger.d("d")
logger.i("i")
logger.w("w")
logger.e("e")

新版 console.*

方法 语义 对应日志级别
console.log(...) 常规日志 INFO
console.debug(...) 调试日志 DEBUG
console.info(...) 信息日志 INFO
console.warn(...) 警告日志 WARN
console.error(...) 错误日志 ERROR
console.trace(...) 跟踪日志(附带调用栈) TRACE

旧版 logger.*

旧版 API 以 logger 全局对象形式暴露,方法命名取自日志级别首字母:

方法 对应日志级别 说明
logger.t(msg) TRACE 与 console.trace 同级
logger.d(msg) DEBUG
logger.i(msg) INFO
logger.w(msg) WARN
logger.e(msg) ERROR
logger.log(msg) INFO 在源码中同样被注册为 INFO 级别

提示:新版 console 是当前推荐写法,旧版 logger 为兼容历史脚本保留,两者底层共用同一条日志通道,不会造成重复或冲突。

二、参数格式化:%s 占位符与多参数输出

从示例可见,Console API 支持 printf 风格格式化与多参数顺序输出两种模式:

console.log("format: %s", "str")      // 输出:format: str(%s 占位符被替换)
console.debug("format: %s", 123)      // 数字 123 同样可被 %s 格式化
console.info("123", "223", 323)       // 多个参数按顺序拼接到一条日志
console.warn("warn", 123)             // 字符串与数字混合
console.error("error", 200)

其格式化能力来自 Rhino 引擎的 NativeConsole.format(cx, scope, args):源码 ConsoleUtils.kt 中 writeFormat 先将全部实参交给 NativeConsole.format 完成占位符替换与类型转换,再写入日志通道。因此:

  • 第一个参数中的 %s 等占位符会被后续实参依次替换;
  • 没有占位符时,多个实参会被自然拼接输出;
  • 格式化结果统一为字符串后进入日志系统,保证中文与混合类型内容的输出稳定。

实际项目中的典型用法,例如在插件请求 TTS 前输出请求 URL:

console.debug("请求参数:url=%s, text=%s", url, text)
console.info("开始合成:%s 字", text.length)
console.warn("备用配置触发,重试第 %d 次", retryCount)
console.error("请求失败:%s", errorMessage)

三、日志级别体系:与 Android Log 级别一一映射

日志级别并非孤立定义,而是直接对齐 Android 系统日志级别。源码 LogLevel.kt 中:

脚本级别 底层常量 Android Log 对应值
TRACE LogLevel.TRACE Log.VERBOSE
DEBUG LogLevel.DEBUG Log.DEBUG
INFO LogLevel.INFO Log.INFO
WARN LogLevel.WARN Log.WARN
ERROR LogLevel.ERROR Log.ERROR

该映射关系由 ConsoleUtils.kt 的 toLogLevel 完成:Rhino 的 NativeConsole.Level.TRACE/DEBUG/INFO/WARN/ERROR 被逐一转换为上述内部常量,再进入 Console.write(level, str)。

在 UI 展示层面,同一文件 LogLevel.kt 的 toArgb 为不同级别分配了辨识色(如 DEBUG 蓝色、INFO 绿色、WARN 橙色、ERROR 红色,并区分深色/浅色主题),悬浮日志窗口据此对每条日志着色显示。

四、源码级链路:从 console.log 到日志界面

4.1 运行时初始化:console 与 logger 的注册

脚本运行时 RhinoScriptRuntime.kt 在 init() 中完成两件事:

  1. 调用 NativeConsole.init(globalScope, false, printer) 初始化标准 console 对象,并将打印回调转发给 console.writeFormat(...),其中 stack(调用栈信息)会随 TRACE 级别一并传入;
  2. 调用 initLogger()(L53-L63),通过 putLogger 在 logger 对象上注册 log/t/d/i/w/e 六个方法,并在全局作用域额外注册了 println(INFO 级别)。

也就是说,脚本里出现的 console 与 logger 均由运行时通过 defineProperty 以 READONLY 属性注入全局作用域,脚本侧无法覆盖或删除它们。

4.2 日志写入与广播:Console.write

所有级别最终汇入 Console.kt 的 write(level, str):

override fun write(@LogLevel level: Int, str: String) {
    logger.info { str }               // 同步写入 KotlinLogging 日志(logback)
    listeners.forEach {               // 广播给所有已注册监听器
        it.onNewLog(LogEntry(level, str))
    }
}
  • 每一条日志会被双写:既进入应用日志系统(logback,配置见 app/src/main/assets/logback.xml),又通过 LogListenerManager 广播给 UI 监听器;
  • 日志数据统一封装为 LogEntry(含 level、message、time、wrapLine 字段),并实现 Parcelable,可在进程/组件间传递。

4.3 TRACE 级别的调用栈

console.trace("trace") 的特殊之处在于:当级别为 TRACE 时,writeFormat 会将 Rhino 捕获的调用栈 stack 附加到消息末尾(str + "\n" + stack.contentToString())。因此 console.trace 不仅能打印文本,还能在定位脚本调用链问题时直接输出 JS 栈帧信息。

4.4 从脚本到悬浮窗:应用层的消费方

由此构成完整闭环:脚本 console.xxx() → NativeConsole.format 格式化 → Console.write → logback 落盘 + 监听器广播 → 悬浮日志窗口/调试界面实时展示。

五、测试验证:官方用例与自动化测试一致

lib-script 模块的仪器化测试资产中提供了与帮助文档逐行对应的脚本 console.js:

console.log("format: %s", "str")
console.debug("format: %s", 123)
console.info("123", "223", 323)
console.warn("warn", 123)
console.error("error", 200)
console.trace("trace")

logger.t("t")
logger.d("d")
logger.i("i")
logger.w("w")
logger.e("e")

该文件由 ScriptTest.kt 等测试驱动执行,用于验证运行时环境下日志 API 的正常调用与输出,可作为脚本编写者验证环境的参考。也就是说,文档中的每一行示例都在仓库测试资产中有对应实现,属于可运行、可验证的真实 API。

六、实际应用场景与最佳实践

在 tts-server-android 的插件脚本(如 plugin-azure.js)或语音规则脚本中,推荐这样组织日志:

// 1) 关键路径用 info,便于观察流程
console.info("开始执行插件:%s", pluginName)

// 2) 变量与中间结果用 debug,仅在需要排查时关注
console.debug("HTTP 响应状态码:%d, 耗时:%dms", status, cost)

// 3) 异常与失败用 error/warn,附加可读信息
console.warn("音频为空,启用备用发音人")
console.error("请求失败:%s", e.message)

// 4) 深挖调用链时用 trace
console.trace("进入回调函数")

实践建议:

  • 按需分级:常规流程用 info,调试细节用 debug,可恢复的异常用 warn,致命错误用 error,需要调用栈时用 trace,避免全部日志都用 log/info 造成噪音;
  • 善用格式化:用 %s/%d 占位符拼接变量,避免字符串拼接导致的类型问题与可读性下降;
  • 新旧 API 共存:维护旧脚本可直接沿用 logger.*,新脚本优先 console.*,二者输出通道一致;
  • 结合悬浮窗调试:调试插件时通过悬浮日志窗口实时观察分级着色输出,可快速定位脚本执行到哪一步、在哪一步出错。

七、小结

tts-server-android 的 Console 运行时是一套与引擎深度集成的日志基础设施:console.* 与 logger.* 双 API 覆盖全部日志级别,%s 占位符格式化开箱即用,TRACE 级调用栈、Android Log 级别映射、logback 双写与 UI 悬浮窗广播构成了从脚本到界面的完整日志链路。无论是开发插件还是调试语音规则,掌握这套日志 API 都能显著提升脚本的调试效率与可维护性。更多运行时能力可继续阅读官方帮助文档 运行时环境 README 中的 文件 File、HTTP 客户端 与 Websocket 客户端 等章节。

登录后查看全文
tts-server-android