uc logs:跨机器聚合查看与实时流式跟踪 Uncloud 服务日志
【免费下载链接】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 logs是 Uncloud CLI 提供的统一日志查看命令,它把集群中分布在多台 Docker 主机上的服务副本(replica/容器)日志聚合到终端,按时间戳排序输出,并支持实时 follow、时间范围过滤、按机器/容器精确筛选等能力。读完本文,你将掌握uc logs的完整参数用法、SERVICE/CONTAINER精确定位技巧,以及其背后基于低水位(low watermark)算法的跨机器日志合并原理。
命令概览
uc logs用于查看指定服务在所有机器上的全部副本的日志。与docker logs只能查看单机单容器不同,uc logs面向“集群中的服务”这一抽象:一次调用即可拉取该服务分布在多台机器上的所有容器的日志,并按时间戳统一排序输出。
uc logs [SERVICE[/CONTAINER]...] [flags]- 位置参数为服务名列表,可叠加容器限定(
SERVICE/CONTAINER形式,其中CONTAINER可以是容器名、完整 ID 或唯一 ID 前缀)。 - 不带任何服务参数时,
uc logs会从 Compose 文件(默认compose.yaml,或--file指定的文件)中读取服务列表,流式输出全部服务(含未激活 profile 的服务)的日志。 - 若 Compose 中定义的服务尚未在集群中部署,会跳过并打印警告,其余服务照常输出(见 service/logs.go 与 service/logs.go)。
常用示例
以下示例覆盖了从基础查看到精细化筛选的典型场景:
# 查看某个服务最近的日志。 uc logs web # 实时流式跟踪日志(follow 模式)。 uc logs -f web # 同时查看多个服务的日志。 uc logs web api db # 查看 compose.yaml 中定义的所有服务的日志。 uc logs # 每个副本只显示最近 20 行(默认 100 行)。 uc logs -n 20 web # 显示全部日志,不限制行数。 uc logs -n all web # 查看指定时间范围内的日志。 uc logs --since 3h --until 1h30m web # 只查看服务的某些副本(容器)。 uc logs web/61d57fd3428f api/2f60 # 只查看运行在指定机器上的副本的日志。 uc logs -m machine1,machine2 web api参数详解
--file strings:指定 Compose 文件
仅当不带服务参数调用uc logs时生效,用于从 Compose 文件加载服务名列表,默认值为compose.yaml,可多次指定或传逗号分隔的多个文件。当服务来自 Compose 文件时,命令还会自动使用 Compose 中声明的集群上下文(SetClusterContextIfUnset(compose.ClusterContext(project)),见 service/logs.go),确保日志连到正确的集群。
-f, --follow:实时流式输出
持续输出新产生的日志,等价于docker logs -f/tail -f的集群版。在 follow 模式下,服务端会以心跳维持流存活(详见下文“底层原理”)。
-n, --tail string:限制每个副本的行数
- 默认值
"100",即每个副本(容器)只显示最近 100 行。 - 传
"all"表示显示全部日志。参数解析时all会被转换为-1,服务端收到-1后返回该容器的全部日志(见 internal/cli/logs/logs.go)。 - 若传非法数值(非整数),会报错
invalid --tail value。
--since/--until:时间范围过滤
两个参数都接受三种格式的时间戳:
| 格式 | 示例 | 说明 |
|---|---|---|
| 相对时长 | --since 2m30s、--since 1h | 表示从“多久之前”开始 |
| RFC 3339 日期/时间 | --since 2025-11-24(本地时区零点)、--since 2024-05-14T22:50:00(本地时区)、--since 2024-01-31T10:30:00Z(UTC) | 精确到秒的起止时间 |
| Unix 时间戳 | --since 1763953966 | 自 1970-01-01 起的秒数 |
--since表示输出该时间点及之后生成的日志,--until表示输出该时间点之前生成的日志,两者可组合使用形成闭合区间,例如uc logs --since 3h --until 1h30m web查看最近 1.5~3 小时之间的日志。
--utc:时间戳时区
默认按本机本地时区打印时间戳;加上--utc后统一按 UTC 打印,便于跨时区对比多机器日志。
-m, --machine strings:按机器过滤
按机器名称或 ID 过滤日志,可多次指定或用逗号分隔多个值(如-m machine1,machine2)。底层会先解析机器过滤条件,仅保留运行在这些机器上的副本的日志流(见 pkg/client/logs.go)。
SERVICE/CONTAINER:精确定位副本
uc logs web/61d57fd3428f api/2f60中,CONTAINER支持容器名、完整 ID 或唯一 ID 前缀(如2f60)。若同一服务的多个参数混用(既有web又有web/abc),只要出现不带/的纯服务名参数,该服务所有副本都会输出(见 internal/cli/logs/logs.go 的ParseServiceArgs合并逻辑)。
输出格式
每条日志输出形如:
Jan 2 15:04:05.000 machine1 web/61d57 GET /api 200依次为:时间戳(time.StampMilli格式,可--utc切换)→ 机器名 →服务名/容器ID前5位→ 消息内容。机器名和服务名会按列动态对齐,单服务场景下机器名着色、多服务场景下服务名着色(调色板见 internal/cli/logs/formatter.go)。其中:
- 来自
stderr的日志会输出到终端的 stderr,便于在 shell 中分别重定向。 - 部署钩子容器(如 pre-deploy)的日志会额外标注
[pre-deploy]字样(Metadata.Hook字段,见 pkg/api/logs.go)。 - 流异常(如某机器日志流 10 秒无响应)会以黄色
WARNING提示,不影响其余日志输出。
底层原理:一条日志的跨机器之旅
uc logs的高层调用链如下(见 cmd/uc/service/logs.go):
- 解析位置参数(
ParseServiceArgs)或从 Compose 文件加载服务列表; - 对每个服务调用
c.ServiceLogs(ctx, service, opts)(见 pkg/client/logs.go):先InspectService拿到服务全部容器(含钩子容器),再按容器逐一建立日志流; - 每个容器流通过 gRPC 代理
ContainerLogs请求转发到对应机器上的 uncloudd(ProxySingleMachineContext,见 pkg/client/logs.go),服务端再对接本机 Docker daemon(见 internal/machine/docker/server.go); - 客户端为每个容器流附带服务元数据(服务名、机器名、容器 ID、钩子类型),再交给
LogMerger合并。
低水位算法与心跳
由于多台机器的物理时钟存在偏差,跨机器日志无法保证严格全局有序。LogMerger(见 pkg/client/logmerger.go)采用低水位(low watermark)算法:为每个输入流记录其最新时间戳lastSeen,watermark 取所有活跃流lastSeen的最小值,只有时间戳早于 watermark 的日志才会从最小堆中弹出输出,从而在“尽快输出”与“尽可能有序”之间取得平衡(见 logmerger.go)。
为让缓冲的日志能及时输出,服务端在无日志产生时每 200ms 发送一次心跳条目(logsHeartbeatInterval,见 internal/machine/docker/server.go),心跳推进 watermark 触发旧日志落盘输出;合并器自身会对多流心跳去抖(200ms 间隔),并统一将心跳时间戳调整为当前 watermark 以维持排序(见 logmerger.go)。
流控与停滞检测
合并器为每个输入流设置最多 100 条在途消息的信号量(logMergerMaxInFlightPerStream),避免单个高速流无限缓冲拖垮整体;同时默认每 1 秒检查一次,若某流超过 10 秒无任何数据则判定为停滞(stalled),将其从 watermark 计算中剔除并输出黄色WARNING: log stream ... stopped responding,防止一条故障流阻塞整条日志管线(见 logmerger.go 与 logmerger.go)。
继承自父命令的全局选项
uc logs同样继承uc的集群连接相关选项,在未使用配置文件时可用:
| 选项 | 环境变量 | 说明 |
|---|---|---|
--connect string | $UNCLOUD_CONNECT | 直连远程集群机器而不使用 Uncloud 配置文件,支持[ssh://]user@host[:port]、ssh+go://user@host[:port]、tcp://host:port、unix:///path/to/uncloud.sock四种格式 |
-c, --context string | $UNCLOUD_CONTEXT | 使用的集群上下文名称(默认当前上下文) |
--uncloud-config string | $UNCLOUD_CONFIG | Uncloud 配置文件路径,默认~/.config/uncloud/config.yaml |
相关命令
- uc:Uncloud 根命令,管理机器、服务、卷等资源。
uc service logs:服务子命令下的日志查看,与uc logs等价(logs是service logs的顶层快捷方式,命令定义于 cmd/uc/service/logs.go)。uc machine logs:查看机器上的系统服务(如 uncloudd、Docker、corrosion)日志;客户端侧由MachineLogs实现(见 pkg/client/logs.go)。
小结
uc logs将“查看服务日志”从单机docker logs提升到集群维度:一条命令即可聚合多机器、多副本、多服务(甚至含部署钩子容器)的日志,配合-f、-n、--since/--until、-m、SERVICE/CONTAINER等参数可灵活完成实时跟踪与问题排查;其底层的低水位合并、心跳推进与停滞检测机制,保证了跨机器日志输出的及时性与尽可能有序,是 Uncloud 集群日常运维中最高频的调试入口之一。
【免费下载链接】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),仅供参考