可观测#
Luma 提供节点与容器采样、当前任务队列、资源历史、运行事件、持久化告警,以及可恢复读取的应用日志。这些观测不等同于终端用户可用性检测。部署和重启时的公共路由检查是独立能力。
控制台导航#
可观测分为告警事件、应用监控、资源指标、日志、告警规则和通知渠道,各页使用简洁的独立标题。引擎摘要位于告警事件页;通知渠道关注配置与发送历史。内置告警页每 15 秒刷新,资源历史每 30 秒刷新。操作流程及路由关系与连通性探测的区别,见控制台指南。
应用告警(luma-observe)#
Control 控制台提供节点与容器采样,实时 allocation 日志仍通过 Control 按需代理。应用 HTTP 5xx、延迟(p90/p95/p99)、Nomad 失败 allocation、重启风暴、链路追踪,以及可搜索的 stdout/stderr,由可选的 observe/ Compose 应用提供。可用 Luma 部署它;不部署也不影响 Control 运行。运维人员通过 控制台 → 可观测 → 应用查看,它在 Control 域名的 /grafana 嵌入 Grafana。部署 observe 后,HTTP、Nomad 和 trace 序列立即按 Luma 应用/stack 名标记,无需应用单独加入。失败指标只统计 Nomad 仍希望运行的 allocation,不是累计失败次数。该组件使用主机网络和回环监听器:Prometheus 为 127.0.0.1:8082,OTLP 为 127.0.0.1:4318,Tempo 为 127.0.0.1:3200。应用任务携带 Control 签发的 bearer token,向 Manager Tailscale mesh 的 4319 端口发送 trace。Control 使用主机网络,observe 存在时查询 http://127.0.0.1:8428。127.0.0.1:3100 上的 Grafana 仅用于本地调试。告警在 vmalert/Alertmanager 中评估,不经过 Control SQLite。Trace 和日志保留 7 天,指标保留期单独配置。
在 observe/ 中执行 luma build local . --platform linux/amd64 部署。首次部署不需要 secret;飞书通知可以之后再用 scoped secret 补上。当前 CLI 支持回环 metrics/OTLP 标志后,刷新 Traefik,让 RED 规则有可抓取目标。通过 控制台 → 可观测 → 应用查看。图表按 Luma 应用展示 Traefik HTTP 请求率、5xx、p90/p95/p99 延迟和 Nomad 健康状态,不是读取每个容器的 /metrics。Traefik 直方图桶为 0.05,0.1,0.25,0.5,1,2.5,5,10 秒,以区分这些分位数。启用 observe 后,后续 Luma 部署会自动注入官方 OpenTelemetry 环境变量:OTEL_SERVICE_NAME、luma.stack / luma.task / luma.region,以及指向 mesh 监听器的 OTLP HTTP 配置。已包含 OpenTelemetry 发行版的应用无需 Luma SDK 即可发送 span。首次启用 observe 后应重新部署已有应用。Trace 导出失败不会阻塞业务;采集器保留 HTTP 5xx、OTel 错误、超过 1 秒的 trace,并对其他请求进行 10% 基线采样。接近内存上限时丢弃新 trace,而不是触发 OOM。不要通过 Manager 公网接口向外发送原始访问日志或 trace。
应用接入#
部署 observe/ 即表示在集群级启用。此后新部署的 Luma job 自动获得 OTel 配置。只重启旧 job 的进程不够,必须重新渲染 Nomad job。这里没有 Luma 遥测 SDK,也不会注入语言 agent。
无需修改应用即可获得:
- 按 Luma 应用名标记的 Traefik HTTP RED(请求率、5xx、p90/p95/p99)。
- 按 Luma 应用名标记的 Nomad 运行数、当前失败数和重启数。
- 存入 Tempo 的公共 HTTP(
cn-edge/external-edge)入口 span。
重新部署后,只有镜像已经支持 OpenTelemetry 时,才会获得:
- 导出到 Tempo、带
luma.stack/luma.task/luma.region的进程 span。 - 在 控制台 → 可观测 → 应用 → Traces 或 Grafana
/grafana/d/luma-traces查看。
仍不会自动获得 nginx、静态 Go 程序或无 OTel SDK 镜像的进程追踪,也不覆盖未经过 Traefik 的流量、请求正文、SQL 文本或每次成功的快速请求。5xx 和超过 1 秒的 trace 会保留,其余按 10% 采样。导出失败不会阻塞业务。
手动添加 span#
不要自行设置 OTEL_EXPORTER_OTLP_ENDPOINT 或 bearer 请求头,Control 已经注入。使用官方 OpenTelemetry API,并保持导出器失败时不阻塞业务。
在镜像中安装官方发行版和 OTLP exporter,例如 Python:
opentelemetry-distro
opentelemetry-exporter-otlp
然后通过 opentelemetry-instrument(或 Node/Java 对应方式)启动,让 SDK 读取注入的环境变量。可在业务步骤外围增加 span:
from opentelemetry import trace
tracer = trace.get_tracer("orders")
def charge(order_id: str) -> None:
with tracer.start_as_current_span("charge_card") as span:
span.set_attribute("order.id", order_id)
provider.charge(order_id)
Node 示例:
const { trace } = require("@opentelemetry/api");
const tracer = trace.getTracer("orders");
async function charge(orderId) {
return tracer.startActiveSpan("charge_card", async (span) => {
span.setAttribute("order.id", orderId);
try {
return await provider.charge(orderId);
} finally {
span.end();
}
});
}
不要把密钥、令牌或完整请求正文写进 span 属性。自定义 span 名会归属同一进程的 luma.stack。镜像没有 OpenTelemetry SDK 时,这些调用不会产生效果,除非添加相应发行版。
控制台与日志#
控制台 → 可观测默认打开告警事件。指标有独立页面;日志通过 Grafana Explore 查询 VictoriaLogs(保留 7 天)。规则与通知渠道分别有列表和编辑地址。存储治理位于 基础设施 → 存储 → 数据治理。
指标页显示实际采样时间范围和保留期,区分缺失、过期和查询失败,并在采样缺口处断开曲线。可选择服务查看资源历史,或打开按 stack 筛选的可观测日志。
可观测日志来自 Nomad allocation 的 stdout/stderr,由 luma-observe 发送到 VictoriaLogs。按 app(Nomad job / Luma stack)筛选。Traefik JSON 访问日志是 traefik job 的 stdout,可用 LogsQL 的 unpack_json 解析。Nomad 帧没有事件时间戳,因此日志行时间是观测时间。luma service logs 和应用详情的实时日志仍通过 Control 跟随 Nomad 文件,只提供有限片段,并非 VictoriaLogs 的持久化日志存储。
资源数据按 30 秒桶保留,与上报某个服务的节点数量无关。LUMA_METRICS_HISTORY_POINTS 默认 720(约 6 小时),范围为 60 到 10000。资源历史独立保存在 Control 状态目录下有界的 metrics-history.json 中;长期排查和独立故障检测仍适合外部采集。备份范围见控制面存储与恢复。服务汇总只覆盖已上报节点,缺失贡献在 180 秒后过期,不能证明所有副本均已上报。
内置告警规则与通知#
控制台告警页管理规则、通知渠道和事件。规则、事件状态变化及通知发件箱持久化在 Control SQLite 中。评估器使用已上报给 Control 的采样和任务状态;创建资源规则不会启动公共 HTTP 探测。
可用预设包括节点心跳时长、持续 CPU/内存/磁盘/inode 使用率、排队任务时长、每个应用最近一次失败构建;部署 luma-observe 后还支持应用 p95 延迟、HTTP 5xx 比例和 Nomad 失败 allocation。Observe 采样通过 VictoriaMetrics 即时 PromQL 查询获得;observe 不可用时,相关规则保持上次状态(noData: keep),不会因此触发。阈值和持续时长可配置,条件持续达到要求后,事件才由 pending 变为 firing;健康观测会解除事件。每条规则与目标仅维护一个活动事件,可设置持续故障的重复通知间隔。
缺失数据有明确策略:keep 保持已有触发状态,不把缺失当作恢复;alert 把缺失视为待评估条件。CPU 规则使用新鲜的 Linux 主机 CPU 采样,不把 macOS 负载均值解释为 CPU 百分比。
确认事件会记录确认操作并停止重复通知,但不会把底层条件标记为健康。全局和规则级定时静默只抑制通知,评估及事件历史仍保留。待发送和重试通知等待静默期结束;静默无法撤回已经发出的 HTTPS 请求。修改规则条件会以规则变更事件把旧事件标记为 closed,不是健康恢复的 resolved。在某个浏览器里临时隐藏总览卡片属于另一种界面偏好,不会静默告警。
内置飞书渠道使用应用机器人。在渠道表单填写 App ID、App Secret 和目标群聊 ID。启用应用机器人能力,授予并发布 im:message:send_as_bot 权限,将机器人加入该群。保存渠道后关联规则,再显式发送测试通知。渠道测试会向配置的群发送真实消息,并绕过静默。
Luma 自动申请 tenant access token,仅缓存于进程内存,并在过期前刷新,运维人员无需配置该 token。读取渠道仅返回 App ID、群聊 ID 和 appSecretConfigured,不会返回 App Secret。App Secret 保存在私有 Control SQLite 中,属于受保护的备份范围。编辑时省略 App Secret 会保留原值;替换该值即可轮换凭据并获取新的缓存 token。
评估独立运行,约每 15 秒一次。单独的发送循环约每秒检查持久化发件箱,慢提供方请求不会暂停评估。待发送、已发送、重试中和失败均可查看。网络及限流失败会退避重试,最多 8 次;无效凭据、缺少权限和群不可访问会给出可操作的错误分类。每个 HTTPS 请求超时为 8 秒,总发送预算为 16 秒。
成功响应表示飞书已接受消息,不代表有人阅读。发件箱重试使用稳定的消息 UUID 供提供方去重;这仍是至少一次投递,而非无限期的严格恰好一次保证。不要为了再次触发而先修改规则,应先检查发送历史。已恢复/关闭事件和最终发送记录在摘要保留期(默认 90 天)后纳入经审查的存储保留计划;活动事件和未完成发送受保护。见控制面存储。
/v1/alerting/ 下的管理 API 需要管理令牌,纯指标令牌不能管理告警。不会自动创建通知渠道。Control 必须保持可用,才能评估并发送自己的告警;应保留独立 Prometheus 抓取或外部探针检测 Manager/Control 故障。内置资源告警不探测公网 URL。应用 p95、5xx 比例和失败 allocation 预设读取 luma-observe,不能替代外部 Control 宕机探测。
主机磁盘采样#
更新后的节点 agent 采样 /opt/luma 所在文件系统;该目录不存在时采样 /。可在节点 agent 服务环境设置 LUMA_METRICS_DISK_PATH,指定其他绝对路径。控制台显示采样路径;它不代表所有挂载点、远端 NFS 服务器容量或 macOS Docker VM 容量。文件系统缺失或 inode 计数不受支持时显示不可用,而非零使用率。
磁盘使用率从可用容量中排除保留块,与常见 df 语义一致;可用字节数也排除保留块。旧 agent 仍可工作,但更新后才会上报这些新增采样。
Prometheus 端点#
GET /v1/metrics 输出 Prometheus 文本格式。它读取持久化心跳快照,不联系 Nomad 或 agent,也不修改控制状态。支持管理令牌;远程采集器应使用独立只读指标令牌。
内置 luma-observe 采集器与 Manager 共享主机网络,无令牌抓取 http://127.0.0.1:8080/v1/metrics,与 Traefik :8082 使用相同的回环信任边界。请求带有 Authorization 请求头时仍会验证。远程 Prometheus 抓取仍需独立令牌。
在 Manager 的 /opt/luma/control/metrics-token 中配置至少 32 个 ASCII 字符的随机令牌。文件必须是 Control 进程可读的私有普通文件(通常权限为 0600),不能是符号链接。现有 /opt/luma 挂载使容器可见此默认路径。每个请求都会重新读取,支持原子轮换而不重启 Control。系统不会自动创建令牌。
显式配置 LUMA_METRICS_TOKEN_FILE 会覆盖默认路径。自定义安装应在进程/容器内暴露该绝对路径,并在对应环境设置变量;Manager shell 中的任意环境变量不会自动传给 Nomad job。
安全地把令牌复制到 Prometheus 采集器凭据文件。此令牌只被 /v1/metrics 接受,不能查询控制台、读取应用日志、部署、重启或访问 LAE 租户 API。它应与其他所有 Luma 令牌区分。端点输出包含基础设施名称与区域标签;远程抓取需要认证,同机 luma-observe 抓取仅限回环。
示例 Prometheus 抓取配置和告警规则是可选模板。替换主机名与凭据路径,使用当前 Prometheus 版本检查,并配置 Alertmanager 目标后才会有通知。外部模板独立于上述 Luma 内置规则和飞书渠道。应用 Prometheus/Alertmanager 配置是单独的基础设施变更,不会创建 Luma 通知渠道。
主要指标:
| 指标 | 含义 |
|---|---|
Prometheus up{job="luma-control"} |
抓取成功,包括连通性与认证,不代表应用健康。 |
luma_node_agent_up |
120 秒内收到心跳,不代表符合 Nomad 调度条件。 |
luma_node_heartbeat_timestamp_seconds |
Control 最近收到的心跳时间。 |
luma_node_metrics_timestamp_seconds |
Control 最近收到的主机采样时间。 |
luma_node_cpu_used_ratio |
Linux 主机 CPU 比例,特意排除 Darwin 负载估计。 |
luma_node_load1 |
主机一分钟负载均值。 |
luma_node_memory_* |
主机内存容量、可用量和使用比例。 |
luma_node_filesystem_* |
带路径标签的采样文件系统容量、可用量、使用量和 inode 比例。 |
luma_service_cpu_cores |
按服务和节点汇总的容器 CPU,单位为核。 |
luma_service_memory_bytes |
按服务和节点汇总的容器内存。 |
luma_service_observed_containers |
Agent 快照中存在的容器数,不是期望副本数。 |
luma_node_unresolved_containers |
缺少持久化 job 身份、未计入服务指标的容器。 |
luma_tasks |
按任务类型统计的当前排队/运行记录,不是累计计数。 |
luma_task_queue_oldest_age_seconds |
有时间记录的最老排队任务;不同类型可能指向同一流程,不能直接累加。 |
主机和容器资源序列在 120 秒无新采样后过期,会从输出中省略,而不是保留旧值或报告为零。更新 Control 后可获得独立采样时间戳;旧存储记录在被新记录替换前回退到心跳时间。此端点不能推导历史计数、延迟分位数、期望副本数或 HTTP 错误率。
服务资源标签保留上报的任务身份。已注册 Compose job 将 job + task 映射为控制台的 job_task 名称;其他 job 保留 job 名和独立 task 标签。只知道 allocation ID 的容器计为未解析,不猜测服务名,也不会在抓取时查询 Nomad。判断覆盖程度时请检查未解析数量。
请求率、状态码和延迟需要启用 Traefik metrics,并将 router/service 标签关联到 Luma 应用身份。私网工作节点和绕过 Traefik 的路由需要单独埋点。检测 Control 故障时,采集器或独立探针应运行在 Control 进程及其故障域之外。