用途
用于诊断已部署的 Databricks App 在运行中出现崩溃、挂起或错误的情况。每个模板在启动时都会安装一个零依赖的诊断引导程序(Python 为 app_diagnostics.py,Node 为 diagnostics.ts),它会把崩溃、未处理异常和关闭时的堆栈跟踪输出到 stderr,也就是应用的日志流。当应用崩溃或挂起时,读取这些日志即可定位原因。
适用触发条件包括:应用崩溃 / 状态为 UNAVAILABLE / 返回 502;应用挂起或无响应;以及其他需要排查运行时异常的场景。
主要能力
读取日志
在启用 SSO 的工作区(例如 dogfood staging)上,databricks apps logs CLI 会被阻断(websocket 302)。此时应改为在浏览器中打开应用自带的日志查看器:
https://<app-url>/logz
在已登录(SSO)状态下打开,即可看到 stdout/stderr 流,其中包含诊断记录。在非 SSO 工作区,CLI 可以正常使用:
databricks apps logs <app-name> --follow --profile <profile>
databricks apps get <app-name> --output json | jq '.app_status' # state + message
日志中需要关注的内容
app.diagnostics: diagnostics: installed (pid=…)—— 表示引导程序已运行。CRITICAL app.diagnostics: Unhandled exception加上Traceback (most recent call last)—— 表示 Python 崩溃 / 未处理异常,并附带堆栈和出错行。Unhandled exception in thread <name>—— 表示工作线程崩溃。received SIGTERM—— 会转储所有线程堆栈,随后是逐线程的 traceback;表示平台终止了应用(OOM、健康检查失败、缩容);该转储显示当时每个线程正在做什么,可用于定位被杀掉的挂起问题。- Node:
[app.diagnostics] uncaughtException (<origin>): …附带 JS 堆栈。未处理的 promise rejection 也会在此出现,origin 为unhandledRejection(Node 默认的--unhandled-rejections=throw会将其升级为uncaughtException)。
使用方式
诊断挂起(Python)
挂起的应用通常会被平台杀掉;上面的 SIGTERM 全线程转储会显示它当时卡在哪里,应优先查看。如果要在终止前捕获堆栈,可以启用周期性看门狗并重新部署(无需访问 pod):
# app.yaml
env:
- name: DATABRICKS_APP_DIAGNOSTICS_HANG_TIMEOUT
value: "120" # dump all thread stacks every 120s while wedged
如果能够向 pod 发送信号,执行 kill -USR1 <pid> 可触发按需的全线程转储。Node 是单线程的——被卡住的事件循环无法自行转储;挂起会表现为健康检查失败,此时 SIGTERM 日志就是你的线索。
环境开关
| 变量 | 默认值 | 作用 |
|---|---|---|
DATABRICKS_APP_DIAGNOSTICS |
on | 设为 0/false 可禁用全部诊断 |
DATABRICKS_APP_DIAGNOSTICS_LOG_LEVEL |
INFO | 诊断日志级别 |
DATABRICKS_APP_DIAGNOSTICS_HANG_TIMEOUT |
未设置 | 秒数;启用周期性全线程挂起转储(Python) |
适用场景与限制
引导程序在每个入口点的最前面安装(app.py / agent_server/start_server.py 顶部 / Node 入口),因此即使是导入期或启动期的崩溃也能被捕获。它不会向你的应用抛出异常,并且是幂等的。
为什么不用 pyspy / gdb / strace?因为应用 pod 受到严格限制(没有 ptrace / CAP_SYS_PTRACE,无法安装软件包),所以进程内的标准库日志是唯一可靠的方法。
可运行的崩溃 fixture 与端到端崩溃测试位于 .scripts/agent-integration-tests/crash-examples/。
关于收费、价格、平台支持范围等更多信息:暂未提供。