Uncloud 集群系统服务日志排查指南:uc machine logs 详解
【免费下载链接】uncloudA lightweight tool for deploying and managing containerised applications across a network of Docker hosts. Bridging the gap between Docker and Kubernetes ✨项目地址: https://gitcode.com/GitHub_Trending/unc/uncloud
导读
uc machine logs是 Uncloud CLI 提供的跨机器系统服务日志查看命令,用于在集群内一次性地、按时间顺序聚合查看多台机器上的系统级服务日志,覆盖 Corrosion 分布式状态存储、Docker 守护进程与 Uncloud 守护进程三类服务。读完本文,你将掌握该命令的全部参数语义、时间过滤语法、跟随(follow)模式用法,并理解其底层"多机日志合并"与心跳保序机制的实现原理,从而高效完成集群层面的故障排查与运行状态观测。
命令概述与定位
uc machine logs从集群中所有机器(或-m指定的部分机器)上读取指定系统服务的日志,并按时间戳统一排序输出。它与uc service logs(面向应用服务的容器日志)互补:uc service logs关注的是用户部署的服务容器,而uc machine logs关注的是支撑整个集群运转的系统组件。
命令别名log,用法格式:
uc machine logs [SERVICE...] [flags]对应命令定义位于 cmd/uc/machine/logs.go。从源码看,SERVICE...位置参数为可选项:当不指定任何服务时,命令内部会将服务列表默认设置为uncloud(见 runLogs 中的api.SystemServiceUncloud分支),即默认流式读取 Uncloud 守护进程的日志。
支持的三种系统服务
命令仅接受以下三种系统服务名,传入其他名称会直接报错(校验逻辑见 runLogs),服务常量定义在 pkg/api/logs.go:
| 服务名 | 全称与角色 | 日志来源(源码依据) |
|---|---|---|
corrosion | Corrosion 分布式状态存储,负责集群状态的复制与持久化 | 以守护进程管理的容器形式运行,日志取自容器 |
docker | Docker 守护进程 | systemd 单元docker,日志取自 journal |
uncloud | Uncloud 守护进程(集群 Agent) | systemd 单元uncloud,日志取自 journal |
从源码结构看:在服务端 internal/machine/machine.go#L1425-L1438 的
MachineLogs实现中,uncloud与docker走 systemd journal 读取路径,而corrosion因为由 daemon 托管为容器(容器名常量见corroservice.ContainerName),走的是与uc service logs相同的容器日志路径。
实战用法示例
以下示例均来自命令自带帮助文本(见 logs.go),可直接复制使用:
# 查看 uncloud 服务最近的日志(默认行为,等价于不带参数) uc machine logs uc machine logs uncloud # 实时跟随(follow 模式),持续输出新增日志 uc machine logs -f uncloud # 同时查看多个服务的日志 uc machine logs uncloud docker corrosion # 每台机器只显示最后 20 行(默认 100 行) uc machine logs -n 20 docker # 显示全部日志,不限制行数 uc machine logs -n all docker # 按时间范围过滤 uc machine logs --since 3h --until 1h30m docker # 只查看指定机器的日志 uc machine logs -m machine1,machine2 uncloud corrosion注意-n/--tail的行数是按副本(每台机器上的实例)分别限制的:在多机场景下,每个机器的日志流各取最后 N 行再合并,而非整体只取 N 行。
参数选项详解
核心选项
| 选项 | 简写 | 类型 | 默认值 | 说明 |
|---|---|---|---|---|
--follow | -f | bool | false | 持续流式输出新日志,直到用户中断 |
--machine | -m | strings | — | 按机器名称或 ID 过滤;可多次指定,也支持逗号分隔列表 |
--since | — | string | "" | 仅显示该时间点之后生成的日志,支持相对时长 / RFC 3339 / Unix 时间戳 |
--tail | -n | string | "100" | 限制每个副本显示的最新日志行数,all表示不限制 |
--until | — | string | "" | 仅显示该时间点之前生成的日志,语法同--since |
--utc | — | bool | false | 时间戳按 UTC 打印而非本地时区 |
选项的定义位置在 internal/cli/logs/logs.go#L22-L47,其中-m支持逗号分隔是通过cli.ExpandCommaSeparatedValues展开的(见 runLogs),--tail的取值解析函数Tail位于 internal/cli/logs/logs.go#L49-L59。
--since / --until 的时间语法
--since与--until共用同一套时间语法,支持三种格式:
1. 相对时长(Go duration 语法)
--since 2m30s # 2 分 30 秒前 --since 1h # 1 小时前 --since 3h # 3 小时前2. RFC 3339 日期/时间
--since 2025-11-24 # 仅日期,按本地时区零点 --since 2024-05-14T22:50:00 # 日期+时间,按本地时区 --since 2024-01-31T10:30:00Z # 日期+时间,UTC3. Unix 时间戳(自 1970-01-01 起的秒数)
--since 1763953966时间戳的解析发生在服务端日志读取层;对于 journal 路径,journalctl会按这些条件过滤条目。组合使用时,--since与--until划定了一个时间窗口,例如--since 3h --until 1h30m表示"1.5 小时前到 3 小时前之间"的日志。
从父命令继承的全局选项
| 选项 | 说明 |
|---|---|
--connect string | 直接连接远程集群机器而不用 Uncloud 配置文件,格式支持[ssh://]user@host[:port]、ssh+go://user@host[:port]、tcp://host:port、unix:///path/to/uncloud.sock;可用环境变量$UNCLOUD_CONNECT |
-c, --context string | 指定要使用的集群上下文名称(默认为当前上下文);可用环境变量$UNCLOUD_CONTEXT |
--uncloud-config string | 指定 Uncloud 配置文件路径,默认~/.config/uncloud/config.yaml;可用环境变量$UNCLOUD_CONFIG |
输出格式与多机合并
统一输出列
命令的输出由 internal/cli/logs/formatter.go 中的Formatter负责渲染,每条日志包含四段信息:
<时间戳> <机器名> <服务名> <日志内容>- 时间戳:默认按本地时区、
Jan _2 15:04:05.000(毫秒精度)格式显示;加--utc则转换为 UTC(见 formatTimestamp)。 - 机器名:粗体显示,单服务日志场景下不同机器使用不同颜色区分(10 色调色板循环分配,见 palette)。
- 服务名:多服务日志场景下不同服务用颜色区分;列宽根据实际涉及的机器名/服务名动态对齐,保证多行可读性。
- stderr 分流:stderr 流的日志写到标准错误输出,stdout 流写到标准输出(见 PrintEntry),方便管道重定向时分离错误信息。
跨机器的时间序合并
在客户端,MachineLogs(实现于 pkg/client/logs.go#L162-L195)会先按过滤条件列出机器,为每台机器分别建立一条日志流并附加机器元数据,然后通过NewLogMerger将多条流按时间戳升序合并为单一输出流。这里要注意:由于物理时钟存在偏差,跨机器的日志无法保证绝对严格的全局排序——合并算法使用低水位(low watermark)机制尽力保证正确顺序,服务端发送的心跳条目用于推进水位,促使客户端及时吐出已缓冲的日志。
当一次指定多个服务时,命令会为每个服务各建一条MachineLogs流,再用外层LogMerger合并(见 runLogs);由于内层每条流已自带 stall 检测,外层合并刻意跳过了重复的告警逻辑。
底层原理:从 CLI 到 journal/容器的完整链路
请求链路
uc machine logs → CLI 组装 api.ServiceLogsOptions → 客户端 c.MachineLogs(ctx, service, opts) → 对每台机器:ProxySingleMachineContext 注入机器路由 → gRPC 服务端流式接口 MachineLogs → 服务端 internal/machine/machine.go 的 MachineLogs → uncloud/docker:internal/journal.Logs(journalctl) → corrosion:dockerService.ContainerLogs(容器日志) → 客户端 LogMerger 按时间戳合并 → Formatter 渲染输出gRPC 接口定义见 api/pb/machine.proto(MachineLogs服务端流式 RPC),请求参数LogsRequest携带id(服务名)、follow、tail、since、until。
systemd journal 读取
对uncloud与docker两个服务,服务端调用 internal/journal 包的Logs函数读取 journal。日志条目采用journalctl的 short-unix 时间戳格式(SSSSSSSSSS.UUUUUU,秒.微秒),由 parseUnixTimestamp 解析为time.Time,消息正文会补回换行符(见 entry)。
心跳保序机制
在 follow 模式下,服务端每 200ms(常量logsHeartbeatInterval,见 internal/machine/machine.go#L1405-L1406)发送一条HEARTBEAT类型的空日志条目:只有当最近一次发送时间距现在超过一个心跳间隔时才发送,且时间戳取"一个心跳之前"的保守值(见 machine.go#L1483-L1501),避免客户端误以为已收到全部日志。这条心跳正是客户端低水位合并算法推进水位的信号源,是"follow 模式下跨机器日志能及时刷出"的关键设计。
流中断与错误提示
如果某个机器的日志流停滞或出错,客户端会收到一条ErrLogStreamStalled错误条目,Formatter 将其渲染为黄色 WARNING(如WARNING: log stream from system service 'uncloud' on machine 'm1' stopped responding),而普通错误则渲染为红色 ERROR(见 printError),便于在多机日志流中快速定位异常节点。
典型排障场景
- Uncloud 守护进程异常:
uc machine logs uncloud查看默认服务日志;若集群行为异常,可先uc machine logs -n 200 uncloud看更多上下文。 - Docker 引擎问题:容器无法调度或状态异常时,
uc machine logs -m node-a docker仅看目标机器的 Docker 日志,避免被其他机器刷屏。 - 集群状态存储故障:
uc machine logs corrosion观察 Corrosion 的复制与同步日志;结合-f实时观察状态变更。 - 多服务交叉排查:
uc machine logs -f uncloud docker corrosion -m machine1固定一台机器同时观察三类系统组件,利用颜色区分快速定位相互影响的日志。
相关命令
- uc machine:管理集群中的机器(
uc machine logs是其子命令之一)。 uc service logs:查看应用服务容器日志;系统服务与用户服务日志读取链路共享同一套LogMerger合并与 Formatter 渲染逻辑。- 全局连接与上下文选项说明见 7-cli-config-reference 中的
--connect/--context/--uncloud-config约定。
【免费下载链接】uncloudA lightweight tool for deploying and managing containerised applications across a network of Docker hosts. Bridging the gap between Docker and Kubernetes ✨项目地址: https://gitcode.com/GitHub_Trending/unc/uncloud
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考