目的

解决以下常见误判:

  • 搜索30天或60天超时后,误认为“线上没有日志”。
  • Elasticsearch Frozen/search-throttled历史索引被默认跳过。
  • Kibana Discover页面仍显示旧结果,但重新查询已不可用。
  • 只用业务单号搜索,遗漏只记录内部ID、RequestId或eventId的环节。
  • 为查日志直接登录生产机,导致查询方式不可复用且风险扩大。

适用于SAAS、DGJ、GRS生产、支付中心、MQ以及接入同一Kibana logstash-YYYY-MM-DD索引体系的项目。

核心结论

  1. 超时、零命中和索引不可见是三种不同结果。
  2. 历史日志必须显式使用 ignore_throttled=false。
  3. 首次查询使用“单日索引 + 1至5分钟绝对时间窗”。
  4. 业务链路必须用业务单号、内部ID、RequestId、eventId和外部单号逐段连接。
  5. 未完成精确单日查询前,不得得出“没有日志”的结论。

标准查询流程

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与SQLsaas、request-YYYY-MM-DD.logpath、request_id、订单号数据库ID、DGJ销售单ID
SAAS Providerprovider/...request_id、URL外部支付单号、返回业务号
SAAS MQkz_mq-YYYY-MM-DD.logeventType、eventId、routingKey消息ID、订单ID
SAAS DGJ Consumerconsumer/orderSync/dgj_order_sync-YYYY-MM-DD.logDGJ订单ID/号SAAS订单ID、request_id
DGJ服务日志Services/syncData-YYYY-MM-DD.logRequestId、eventTypeeventId、出库/销退单号
DGJ访问日志/opt/app/tengine/logs/access.logpath、内部ID、sidRequestId或响应时刻
MQ Brokerkzmq producer/consumereventId、routingKeyconsumer项目和时间
GRS生产grsprod应用日志listener、订单号、eventType下游处理结果
支付中心支付项目应用日志sourceOrderNo、outBillNopayOrderNo、支付结果

日志源会随部署变化。查询到实际 source 后,应使用该值作为后续精确过滤条件。

常见陷阱

业务单号搜不到HTTP请求

前端表单可能只提交内部订单ID,访问日志可能把JSON引号编码成 \x22, 接口也可能没有记录响应体。处理顺序:

  1. 用业务单号找到MQ或下游日志。
  2. 提取内部订单ID和RequestId。
  3. 用内部ID搜索前一时间段。
  4. 必要时按 /opt/app/tengine/logs/access.log精确过滤并在本地筛选。
  5. 如果原始请求仍未留存,明确说明日志覆盖不足,使用副作用日志和数据库回读证明分支。

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

相关文档