版本: v1.0 修改日期: 2026-05-29 本文指导运维人员与项目经理,对 viSCADA 采集数据出现延迟、丢失或不入库问题进行标准化排查与定位。排查按采集日志 → 设备配置 → Kafka 消息三个环节依次推进,逐层缩小问题范围。
1 文档信息
| 项 | 内容 |
|---|---|
| 版本 | v1.3 |
| 日期 | 2026-03-24 |
| 适用对象 | 运维人员、项目经理 |
| 典型现象 | 数据延迟 / 丢失 / 不入库 |
⚠️ 先决条件:开始排查前请先核对各节点时间。检查 K8s 集群各节点、MQTT Broker 各节点的系统时钟,确保时间一致;时钟漂移常导致误判为「数据丢失」。
图 1 采集数据异常排查的整体架构视角
2 排查流程总览
- 第 3 章 定位采集端输出问题;
- 第 4 章 定位设备指令下发或配置错误;
- 第 5 章 验证数据是否成功进入 Kafka 目标主题。
3 采集数据日志排查(connector 服务)
目的:确认采集服务运行状态,核查设备与任务日志,验证采集数据输出是否正常。
3.1 配置日志脚本
路径:「设备类」→「脚本」→「添加脚本」→ 输入脚本 → 点击「√」保存
图 2 在设备类中添加日志脚本
[[processors.starlark]]
namepass = ["${TEMPLATE_NAME}"]
alias = "${TEMPLATE_NAME}@starting"
order = ${order@54}
source = '''
load("logging.star", "log")
load("json.star", "json")
def apply(metric):
log.info("metricStart:"+json.encode(metric))
return metric
'''3.2 在 viSCADA 页面查看日志
ℹ️ 页面查看方式适用于 viSCADA v1.6.3 及以上版本(2025-10-30 起支持)。
操作步骤:
- 进入数据对接服务 → 「运行日志」 页面;
- 通过筛选查看运行日志与报错日志;
- 筛选「最新日志」,使用
Ctrl + F搜索关键字; - 若未搜索到内容,点击「刷新日志」后再次检索;
- 建议复制近期报错的日志片段及上下文,便于后续分析。
图 3 数据对接服务的运行日志页面
图 4 筛选最新日志并使用 Ctrl + F 搜索关键字
图 5 未搜索到内容时可点击「刷新日志」后重试
常用筛选关键字:
| 关键字 | 用途 |
|---|---|
E! | 快速定位报错日志 |
| 设备类标识 | 查询某设备的采集数据,如 9DQpiyceGi |
图 6 按 E! 筛选可快速定位报错
图 7 按设备类标识筛选对应采集数据
图 8 设备类标识筛选结果示例
3.3 在 K8s 中查询日志
常用命令:
# 列出 prod 命名空间中名称包含 connect 的 Pod
kubectl -n prod get pods | grep -i connect
# | | └── -i connect:忽略大小写,过滤含 connect 的行
# | └── get pods:列出 Pod 资源列表
# └── -n prod:指定目标命名空间
# 查看 Pod 状态、重启次数及所在节点
kubectl -n prod get pods -o wide | grep -i connect
# └── -o wide:额外显示节点名称、IP 等附加列信息
# 实时跟踪指定 Pod 的日志输出(替换为实际 Pod 名称)
kubectl -n prod logs -f <connect-pod-name>
# | └── -f / --follow:持续流式输出新日志,Ctrl+C 退出
# └── logs:查看容器标准输出日志
# 限制日志输出行数与时间范围,减少噪音
kubectl -n prod logs --tail=200 --since=1h <connect-pod-name>
# | | └── --since=1h:只输出最近 1 小时内的日志
# | └── --tail=200:从末尾截取最多 200 行
# └── logs:查看容器日志
# 无日志或日志异常时,查看 Pod 详情与事件
kubectl -n prod describe pod <connect-pod-name>
# | └── pod <name>:要查看的目标 Pod 名称
# └── describe:输出资源完整描述信息与关联事件列表
kubectl -n prod get events --sort-by=.lastTimestamp | grep <connect-pod-name>
# | └── --sort-by=.lastTimestamp:按最近触发时间升序排列
# └── get events:列出命名空间内所有 K8s 事件过滤示例:
# 示例 1:排除设备 10000,仅保留 JuIzTd8MQ0 相关数据
kubectl -n prod logs -f connector-24043-79b89ffc5f-mcz6p | grep -v '10000' | grep 'JuIzTd8MQ0'
# | └── 'JuIzTd8MQ0':保留包含该设备标识的行
# └── -v '10000':反向过滤,排除含 10000 的行
# 示例 2:仅查看报错日志
kubectl -n prod logs -f connector-24043-79b89ffc5f-mcz6p | grep 'E!'
# └── 'E!':Telegraf 错误日志行前缀
# 示例 3:查看某设备类标识的采集数据
kubectl -n dev logs -f connector-90-ffc45fcb5-qgl8s | grep '9DQpiyceGi'
# └── '9DQpiyceGi':设备类唯一标识
图 9 K8s 命令行查询采集数据示例
3.4 fields 批次判定规则
日志中每条 metric 的 fields 字段,代表同一批采集到的数据。判定两个点位是否属于同一批,直接决定能否做公式联算。
| 场景 | 判定 | 是否可直接做公式计算 |
|---|---|---|
两个点位在同一条日志的 fields 中 | 同一批数据 | 是 |
两个点位在不同日志的 fields 中 | 非同一批 | 否 |
同一批示例(4x0001 与 4x0007 在同一 fields 中,可直接联算):
{
"fields": {
"0x0001:BOOL": 0,
"4x0001:INT": 2,
"4x0005:REAL": 0.00000000000000000000000000000000000000009183689745645554,
"4x0007:INT": 1
},
"name": "9DQpiyceGi",
"tags": {
"device_id": "200709",
"name": "9DQpiyceGi",
"slave_id": "1"
},
"time": 1774329166000000000
}非同一批示例(4x0001 与 4x0007 分散在两条日志中,不建议直接联算):
{
"fields": {
"4x0005:REAL": 0.00000000000000000000000000000000000000009183689745645554,
"4x0007:INT": 1
},
"name": "9DQpiyceGi",
"tags": { "device_id": "200709", "name": "9DQpiyceGi", "slave_id": "1" },
"time": 1774329166000000000
}{
"fields": {
"0x0001:BOOL": 0,
"4x0001:INT": 2
},
"name": "9DQpiyceGi",
"tags": { "device_id": "200709", "name": "9DQpiyceGi", "slave_id": "1" },
"time": 1774329166000000000
}3.5 判定与下一步
| 日志现象 | 下一步动作 |
|---|---|
| 数据正常推送 | 转入 § 4.2 设备下发 / 配置错误 排查设备下发或配置问题 |
| 设备或指令异常 | 转入 § 4.2 设备下发 / 配置错误 继续定位 |
| 容器频繁重启(CrashLoopBackOff) | 优先排查资源瓶颈或配置错误,稳定后再继续 |
3.6 专用协议排查参考
- Modbus 协议:<viSCADA - ModBus 协议数据对接配置.md>
- S7 协议:<viSCADA - S7 协议数据对接配置.md>
💡 跟踪日志时需指定准确的 Pod 名称;建议先查看原始日志确认关键词,再使用
grep过滤,必要时加-i忽略大小写。
4 设备下发与配置日志排查(device 服务)
目的:定位因指令下发错误或配置异常导致的采集失败。
4.1 grep 常用参数
| 参数 | 作用 |
|---|---|
-A N | 显示匹配行及其后 N 行 |
-B N | 显示匹配行及其前 N 行 |
-C N | 显示匹配行前后各 N 行(等价于 -A N -B N) |
4.2 设备下发 / 配置错误
# 列出 prod 命名空间下名称以 device- 开头的 Pod
kubectl get pods -n prod | grep '^device-'
# └── '^device-':正则表达式,仅匹配以 device- 开头的行
# 实时跟踪目标 Pod 日志(替换为实际 Pod 名称)
kubectl -n prod logs -f <device-pod-name>
# | └── -f:持续流式输出新日志,Ctrl+C 退出
# └── logs:查看容器标准输出日志
# 按设备唯一标识或关键字过滤日志(示例:123456)
kubectl -n prod logs -f device-service-8f7885b79-2fr9v | grep '123456'
# └── '123456':替换为实际设备唯一标识
# 无明显输出或错误时,核查 Pod 事件与容器状态
kubectl -n prod describe pod <device-pod-name>
# | └── pod <name>:要查看的目标 Pod 名称
# └── describe:输出资源完整描述信息与关联事件列表
# 按上下文行数筛选日志(示例:匹配行前后各 5 行)
kubectl -n prod logs -f device-service-8f7885b79-2fr9v | grep -A 5 '123456'
# | └── '123456':过滤关键字
# └── -A 5:输出匹配行及其之后 5 行
kubectl -n prod logs -f device-service-8f7885b79-2fr9v | grep -B 5 '123456'
# └── -B 5:输出匹配行及其之前 5 行
kubectl -n prod logs -f device-service-8f7885b79-2fr9v | grep -C 5 '123456'
# └── -C 5:输出匹配行前后各 5 行(等价于 -A 5 -B 5)5 Kafka 主题数据推送排查
目的:验证采集数据是否成功写入目标 Kafka 主题 ods.{PROJECT_ID}.data,并可通过设备 ID 等关键字筛选消息。
5.1 操作步骤
# 查看 kafka 命名空间的 Pod,确认 broker 正常运行
kubectl get pods -n kafka
# 进入 Kafka broker Pod 的交互式终端(将 kafka-0 替换为实际 Pod 名称)
kubectl exec -n kafka -it kafka-0 -- bash
# | | | | └── bash:在容器内启动的 shell 程序
# | | | └── --:分隔 kubectl 参数与容器内命令
# | | └── kafka-0:目标 Pod 名称
# | └── -it:-i 保持标准输入开放,-t 分配伪终端(TTY)
# └── exec:在运行中的容器内执行命令
# 若镜像不带 bash,可改用 sh:
# kubectl exec -n kafka -it kafka-0 -- sh
# 进入 Kafka CLI 脚本目录(不同镜像路径可能不同)
cd /opt/bitnami/kafka/bin/ # Bitnami 镜像;通用镜像改用 /opt/kafka/bin/
# 实时消费主题最新消息,按设备 ID 过滤
sh kafka-console-consumer.sh --bootstrap-server 127.0.0.1:9092 \
--topic ods.1.data | grep '48985'
# | | └── grep '48985':过滤包含该设备 ID 的消息行
# | └── --topic ods.1.data:指定要消费的 Kafka 主题名称
# └── --bootstrap-server 127.0.0.1:9092:Broker 连接地址(Pod 内使用本地 127.0.0.1)
# 从头消费历史消息(数据量大时速度较慢)
sh kafka-console-consumer.sh --bootstrap-server 127.0.0.1:9092 \
--topic ods.1.data --from-beginning | grep '48985'
# └── --from-beginning:从分区最早 offset 开始消费(而非最新位置)
# 列出集群中所有主题,确认目标主题是否存在
sh kafka-topics.sh --bootstrap-server 127.0.0.1:9092 --list
# | └── --list:输出所有主题名称列表
# └── --bootstrap-server 127.0.0.1:9092:Broker 地址
# 查看目标主题的分区、副本与 leader 状态
sh kafka-topics.sh --bootstrap-server 127.0.0.1:9092 \
--describe --topic ods.1.data
# | └── --topic ods.1.data:指定要查看的主题名称
# └── --describe:输出主题详情(分区数、副本分配、ISR 列表、leader)💡 可选:临时指定新的 consumer group 避免影响现有消费进度:
sh kafka-console-consumer.sh --bootstrap-server 127.0.0.1:9092 \ --topic ods.1.data --from-beginning \ --group debug-$(date +%s) # └── --group debug-$(date +%s):以时间戳命名临时 group,不影响现有消费进度
5.2 镜像路径对照
| 镜像类型 | Kafka CLI 脚本路径 |
|---|---|
| Bitnami | /opt/bitnami/kafka/bin/ |
| 通用 Kafka 镜像 | /opt/kafka/bin/ |
5.3 判定与排查建议
- 无消息输出:回查 第 3 章) 的 connector 日志与 第 4 章) 的设备配置或下发日志;同时核查 broker 状态、监听地址、权限,以及分区或 leader 是否异常(参考
--describe输出)。 - 有消息输出:表明采集链路至 Kafka 段正常,应继续排查下游入库(数据仓库写入、stream 处理等)环节。
5.4 注意事项
⚠️
127.0.0.1仅适用于在 Kafka Pod 内执行的场景;如在集群内其他位置执行,请优先使用 Kafka 的 Service 地址。
- 主题名称需严格匹配大小写;
- 无输出时重点排查 broker 状态、网络连通性与权限配置。