目的
解决以下常见误判:
- 搜索30天或60天超时后,误认为“线上没有日志”。
- Elasticsearch Frozen/search-throttled历史索引被默认跳过。
- Kibana Discover页面仍显示旧结果,但重新查询已不可用。
- 只用业务单号搜索,遗漏只记录内部ID、RequestId或eventId的环节。
- 为查日志直接登录生产机,导致查询方式不可复用且风险扩大。
适用于SAAS、DGJ、GRS生产、支付中心、MQ以及接入同一Kibana logstash-YYYY-MM-DD索引体系的项目。
核心结论
- 超时、零命中和索引不可见是三种不同结果。
- 历史日志必须显式使用
ignore_throttled=false。 - 首次查询使用“单日索引 + 1至5分钟绝对时间窗”。
- 业务链路必须用业务单号、内部ID、RequestId、eventId和外部单号逐段连接。
- 未完成精确单日查询前,不得得出“没有日志”的结论。
标准查询流程
flowchart TD
A["收到日志排查请求"] --> B["确认时区和业务发生时间"]
B --> C["选择精确 logstash-YYYY-MM-DD"]
C --> D["设置1至5分钟绝对时间窗"]
D --> E["通过Kibana console proxy查询"]
E --> F["确认 ignore_throttled=false"]
F --> G{"有命中吗"}
G -- "有" --> H["提取RequestId、内部ID、eventId、外部单号"]
H --> I["按新锚点查询下一系统"]
I --> J["形成升序时间线并只读核对数据库"]
G -- "无" --> K{"_shards.total是否大于0"}
K -- "否" --> L["索引缺失、关闭或当前账号不可见"]
K -- "是" --> M["更换ID/RequestId/eventId/日志源"]
M --> G
1. 精确单日查询
python3 /Users/zhoujiangbin/.codex/skills/kibana-log-query-runner/scripts/query_kibana_logs.py \
--date YYYY-MM-DD \
--from 'YYYY-MM-DDTHH:MM:SS+08:00' \
--to 'YYYY-MM-DDTHH:MM:SS+08:00' \
--keyword '业务单号或RequestId' \
--size 1000 \
--messages
脚本通过Kibana Dev Tools console proxy查询,并自动把:
ignore_throttled=false
加入Elasticsearch搜索路径。
2. 日志量过大时按源过滤
python3 /Users/zhoujiangbin/.codex/skills/kibana-log-query-runner/scripts/query_kibana_logs.py \
--date YYYY-MM-DD \
--from 'YYYY-MM-DDTHH:MM:SS+08:00' \
--to 'YYYY-MM-DDTHH:MM:SS+08:00' \
--source '/data/logs/dgj/Services/syncData-YYYY-MM-DD.log' \
--keyword 'RequestId或订单ID' \
--messages
先缩小索引和时间,再考虑使用 --timeout 60。不能先扩大超时时间搜索60天。
零命中判定门禁
只有全部满足以下条件,才能报告“当前Kibana未查询到对应日志”:
- 使用精确单日索引。
- 搜索路径包含
ignore_throttled=false。 - 使用绝对时间和明确时区。
- 时间窗已缩小到分钟级并执行成功,没有超时。
- 已尝试业务单号、源订单ID、目标订单ID、RequestId、eventId/messageId、路由键和外部单号。
_shards.total大于0。- 已重新执行查询,而不是只看Discover缓存结果。
如果任意一项不满足,应报告具体限制,不得直接说“没有日志”。
跨系统日志证据矩阵
| 环节 | 常见project/source | 首选锚点 | 连接下一段的键 |
|---|---|---|---|
| SAAS HTTP与SQL | saas、request-YYYY-MM-DD.log | path、request_id、订单号 | 数据库ID、DGJ销售单ID |
| SAAS Provider | provider/... | request_id、URL | 外部支付单号、返回业务号 |
| SAAS MQ | kz_mq-YYYY-MM-DD.log | eventType、eventId、routingKey | 消息ID、订单ID |
| SAAS DGJ Consumer | consumer/orderSync/dgj_order_sync-YYYY-MM-DD.log | DGJ订单ID/号 | SAAS订单ID、request_id |
| DGJ服务日志 | Services/syncData-YYYY-MM-DD.log | RequestId、eventType | eventId、出库/销退单号 |
| DGJ访问日志 | /opt/app/tengine/logs/access.log | path、内部ID、sid | RequestId或响应时刻 |
| MQ Broker | kzmq producer/consumer | eventId、routingKey | consumer项目和时间 |
| GRS生产 | grsprod应用日志 | listener、订单号、eventType | 下游处理结果 |
| 支付中心 | 支付项目应用日志 | sourceOrderNo、outBillNo | payOrderNo、支付结果 |
日志源会随部署变化。查询到实际 source 后,应使用该值作为后续精确过滤条件。
常见陷阱
业务单号搜不到HTTP请求
前端表单可能只提交内部订单ID,访问日志可能把JSON引号编码成 \x22, 接口也可能没有记录响应体。处理顺序:
- 用业务单号找到MQ或下游日志。
- 提取内部订单ID和RequestId。
- 用内部ID搜索前一时间段。
- 必要时按
/opt/app/tengine/logs/access.log精确过滤并在本地筛选。 - 如果原始请求仍未留存,明确说明日志覆盖不足,使用副作用日志和数据库回读证明分支。
Discover有数据,脚本查询没有
Discover页面可能保留之前加载的结果。重新执行查询或按文档 _id 通过console proxy查询,才是当前Elasticsearch可用性的权威证据。
时间相差8小时
@timestamp常使用UTC,消息正文和数据库通常使用Asia/Shanghai。时间线必须同时保留:
- Elasticsearch
@timestamp - 消息正文业务时间
- 明确时区
不能把UTC和本地时间直接排序后得出链路先后。
输出模板
| 时间 | 系统 | host/source | 动作 | 输入锚点 | 输出锚点 | 结果 |
|---|
输出规则:
- 按业务发生时间升序。
- 区分日志事实、代码推断和数据库回读。
- 记录命中总数和查询范围。
- 不复制账号密码、Cookie、Token、客户隐私和超长原始消息。
- 跨系统问题至少使用两个独立锚点相互验证。
相关Skill与源码
- Skill:
/Users/zhoujiangbin/.codex/skills/kibana-log-query-runner/SKILL.md - 查询脚本:
/Users/zhoujiangbin/.codex/skills/kibana-log-query-runner/scripts/query_kibana_logs.py - 跨项目参考:
/Users/zhoujiangbin/.codex/skills/kibana-log-query-runner/references/cross-project-order-tracing.md