1. 文档用途
这份文档是 DGJ2 日志治理的持续台账。以后每一次日志优化,都按同一套格式追加:
| 必填项 | 要记录的内容 |
|---|---|
| 日志点 | Kibana 中可直接搜索的固定文案 |
| 代码位置 | 文件、方法、行号范围 |
| 原来怎么记 | 原日志是否包含完整请求、完整对象、完整返回值、异常堆栈 |
| 原始量级 | 统计时间窗、条数、字符数、占比、最大单条 |
| 现在怎么记 | 保留哪些链路字段,删除哪些大字段,异常是否保留完整信息 |
| 优化后量级 | 发布前后同口径对比,不能只比较不同流量下的总条数 |
| 排查能力 | 出现问题时如何用 RequestId、msg_id、业务 ID 串起上下文 |
| 风险与验证 | 是否可能影响业务、如何灰度、如何回滚、验证结果 |
本台账遵守三个原则:
- Kafka 消费入口保留一份完整原始消息,作为链路的“原始证据”。
- 下游节点不重复打印完整对象,但必须保留
RequestId和能够判断节点是否执行、执行结果是什么的最小字段。 - 正常成功路径记录摘要;格式错误、业务异常、外部调用失败保留足够的失败原因,必要时只在异常分支输出完整上下文。
2. 当前统计口径
- 项目:DGJ2 AI 报价 /
RobotInquiry。 - 当前代码分支:
bugfix/20260827-log。 - 当前版本基线:
1b94e4cbef(日志优化后的现有代码基线)。 - 日志查询:内网 Kibana API,索引
logstash-2026.08.27。 - 最新量级窗口:
2026-08-27 16:00:00 ~ 16:15:00,东八区。 message的量级使用 Elasticsearchmessage.length()统计,单位是字符,不等同于磁盘字节;用于同一口径的相对比较。- 线上日志已经集中到 Kibana,本台账不依赖登录服务器直接读取线上文件。
3. 上线前后总体效果
本次发布以 2026-08-26 20:15 重启后的 20:16~20:17 作为优化后窗口,与上线前 19:59~20:00 对比。两段时间流量不完全相同,因此同时看总量和“每条 onMessage 的平均字符数”。
| 指标 | 优化前 19:59~20:00 | 优化后 20:16~20:17 | 结果 |
|---|---|---|---|
robot_inquiry 日志条数 | 9,222 | 6,355 | 受流量影响,不能单独作为效果结论 |
robot_inquiry message 字符数 | 88,594,622 | 1,807,870 | 下降约 97.96%,约 49 倍 |
| 平均每条日志字符数 | 9,606.9 | 284.5 | 单条平均下降约 97.04% |
onMessage 开始 平均单条 | 52,893 | 156 | 完整消息改为摘要 |
onMessage 结束 平均单条 | 393 | 107 | 保留结束节点,去除重复大字段 |
loadConversation:会话加载完成 平均单条 | 2,411 | 479 | preConversation 改为 ID/状态摘要 |
消息处理失败 平均单条 | 929 | 106 | “未绑定客户”不再重复打印 trace |
说明:选取的几个重点日志点合计从 45,705,732 字符下降到 341,008 字符;按 onMessage 开始 归一化后,每条消息相关日志从约 54,606 字符下降到约 590 字符。这个结果说明本次主要收益来自“去掉重复完整对象”,不是减少业务处理次数。
4. 已完成的优化台账
4.1 入口与链路日志
| 日志点 | 代码位置 | 原来怎么记 | 上线前量级 | 现在怎么记 | 上线后量级 | 排查能力与结论 |
|---|---|---|---|---|---|---|
onMessage 开始 | application/controllers/inner/moveMall/Robot.php,消费消息入口 | 开始处理时把完整 $message 再打印一遍;同一份 payload 后面还会被下游节点重复打印 | 837 条 / 44,271,029 字符;平均 52,893,最大 149,714 | 只保留 RequestId、memory_limit 等入口诊断字段,不再重复打印 payload | 578 条 / 90,168 字符;平均 156,最大 156 | 完整原始消息由 Kafka 收到消息 保留;入口仍能确认“已进入 onMessage”,并可按 RequestId 串联后续日志 |
onMessage 结束 | application/controllers/inner/moveMall/Robot.php | 结束时重复携带较多上下文,且与开始、下游处理日志内容重叠 | 824 条 / 323,912 字符;平均 393 | 保留结束节点和最小结束信息,不再携带完整业务对象 | 562 条 / 60,134 字符;平均 107 | 能确认是否正常走到结束;真正的失败原因由错误日志记录 |
parseNotify:解析微信消息 | application/Providers/WechatRobot/Module/NotifyModule.php | 原来把完整原始 $notifyData 写入日志,导致入口 payload 与解析节点重复 | 本窗口前的旧版本没有该固定摘要点,旧代码形态为完整原始 JSON | 保留 request_id、msg_id、event、from_wxid、robot_wxid;完整原始消息只由入口保存 | 27,293 条 / 6,529,372 字符;平均约 239 | 可确认解析节点执行、识别哪条消息、来自哪个机器人;需完整 payload 时回到入口按 request_id 查询 |
消息格式错误 | application/controllers/inner/moveMall/Robot.php | 格式错误时打印完整消息 | 本次正常样本为 0 条 | 保留完整错误消息,不做摘要化 | 正常窗口 0 条 | 这是入口异常证据,不能删除;出现时可直接拿原始 payload 复现 |
收到消息 | application/controllers/inner/moveMall/Robot.php | 消费入口保存完整 Kafka 消息 | 作为完整证据保留 | 每条消息只保留一份完整原始消息;下游不再复制 | 作为链路根节点保留 | 这是整条链路的“原始档案”,必须通过 RequestId/msg_id 与下游关联 |
4.2 联系人、会话与异常日志
| 日志点 | 代码位置 | 原来怎么记 | 上线前量级 | 现在怎么记 | 上线后量级 | 排查能力与结论 |
|---|---|---|---|---|---|---|
setContact:获取绑定微信ID | application/Services/MoveMall/RobotInquiryBaseSer.php:204 | 打印绑定微信 ID | 旧日志为高频小日志 | 继续保留 bindWxId | 当前属于高频小字段 | 能判断联系人查询使用了哪个微信 ID;字段短,保留收益大于成本 |
setContact:设置联系人 | application/Services/MoveMall/RobotInquiryBaseSer.php:221 | 打印完整 $this->contact,包含联系人、服务站、群聊等字段 | 当前 15 分钟 6,497 条 / 8,407,252 字符;最大 1,357 | 当前代码仍打印完整 contact,是目前需要优先处理的重复大对象之一 | 尚未压缩 | 联系人节点本身不能删除;建议改为 contact_id、sid、chat_group_id、wxid、name 和绑定校验结果。完整 contact 不应在多个节点重复出现 |
setContact:设置联系人 前后的空状态日志 | RobotInquirySer.php 调用链 | 开始、完成、初始化等多个节点同时携带完整 contact/conversation | 旧版本同一请求会重复出现多个完整对象 | 保留节点状态和 RequestId,完整对象只保留在一个入口/必要异常点 | 当前空状态节点单条很小 | 这些日志用于判断节点是否进入,不应全部删除;应删除的是重复对象,不是节点标志 |
loadConversation:开始加载会话 | application/Services/MoveMall/RobotInquiryBaseSer.php:240 | 开始加载时打印完整 contact | 旧样本与 contact 重复 | 当前只打印 cvKey;完整 contact 不再在此节点出现 | 当前 15 分钟 7,743 条 / 约 1.27M 字符,平均约 164 | cvKey 足够定位会话查询;结合 contact_id/sid/wxid 摘要即可排查会话键生成问题 |
loadConversation:会话加载完成 | application/Services/MoveMall/RobotInquiryBaseSer.php:251 | 同时打印完整 conversation 与完整 preConversation | 104 条 / 250,775 字符;平均 2,411,最大 19,149 | 按当前约定保留完整 conversation;preConversation 只保留 pre_conversation_id、pre_conversation_status | 当前 7,743 条 / 5,843,185 字符;平均约 755,最大 1,903 | 没有丢掉当前会话内容;可以判断主会话是否存在、前置会话是否存在及状态。后续若量仍高,只压缩 conversation 内部重复字段,不改变会话查询逻辑 |
消息处理失败 | application/controllers/inner/moveMall/Robot.php / RobotInquirySer.php | 所有异常都打印 error + trace;“未绑定客户”也打印完整 trace | 751 条 / 697,738 字符;平均 929,最大 59,942 | 对明确业务预期异常“未绑定客户”只保留 error、bindWxId/RequestId 等最小信息;代码异常仍保留 trace | 511 条 / 54,185 字符;平均 106,最大 635 | 未绑定客户是可解释业务分支,不需要堆栈;真正 PHP 异常仍有 trace。不能把所有异常都一律去掉 trace |
处理verifyBindContactCode | application/Services/MoveMall/WechatSer.php:946 附近 | 直接打印完整 notify,请求参数在入口及 Services 节点重复 | 旧口径曾将其误判为 Services/info 的 99.6%;该比例不能沿用 | 当前改为 request_id、msg_id、事件、来源/机器人及验证码判断所需的短字段 | 最新 15 分钟 Services/info:26,120 条 / 6,354,864 字符;平均 243,最大 249 | 当前占 Services/info 约 90.7% 的条数、约 96.6% 的字符,不是 99.6%。它仍是 Services/info 的最大来源,但已经是短日志;后续重点是确认是否还需要每次成功都打 info,而不是恢复完整 notify |
5. 最新未优化日志量级排序
以下是 2026-08-27 16:00~16:15 内网 robot_inquiry 日志的聚合结果。数字按 message.length() 统计,目的是决定优化优先级;“条数多”与“单条大”要分别看。
| 优先级 | 日志点 | 条数 | 总字符数 | 占窗口总字符 | 最大单条 | 当前判断 |
|---|---|---|---|---|---|---|
| P0 | setConversationRecord:生成会话记录 | 6,555 | 12.86M | 7.54% | 87KB | 完整 $data,包含 source_content、text、keyword,当前最大业务日志 |
| P0 | searchWxList:查询到商城商品数量 | 671 | 10.66M | 6.25% | 220KB | 已在当前分支改为最多 500 字符;待发布后复测实际下降量 |
| P0 | setContact:设置联系人 | 6,497 | 8.41M | 4.93% | 1.36KB | 高频打印完整 contact,多个节点还会重复带联系人 |
| P0 | 处理optionPrivateChat | 4,373 | 6.44M | 3.78% | 2.65KB | 高频打印完整 notify,入口已有完整消息 |
| P1 | loadConversation:会话加载完成 | 7,743 | 5.84M | 3.43% | 1.90KB | conversation 按约定保留;后续只考虑压缩其重复字段 |
| P1 | unlock:释放锁 | 28,126 | 5.10M | 2.99% | 191B | 单条很小,主要是高频;成功日志可降级/采样,失败必须保留 |
| P1 | filterSearchResult:商品库存debug | 6,237 | 4.75M | 2.79% | 1.67KB | 循环内逐商品打印 $it,容易随商品数线性放大 |
| P1 | formatMessage:开始处理商品数据 | 664 | 4.16M | 2.44% | 47.6KB | 打印完整 goods |
| P1 | formatMessage:物料信息 | 664 | 4.14M | 2.43% | 47.5KB | 与上一条重复打印完整 goods,优先合并 |
| P1 | searchWearingParts:排序信息 | 628 | 3.32M | 1.95% | 41.7KB | 打印完整排序数据 |
| P2 | formatMessage:缓存数据 | 664 | 1.53M | 0.90% | 15.8KB | 打印完整缓存结构,改为数量、key、序列号范围 |
| P2 | RobotSegmentationService: 开始处理@提醒文本 | 95 | 200KB | 0.12% | 57.5KB | 少量但单条很大,建议截断文本并只保留成员 ID/数量 |
补充判断:parseNotify 和 onMessage 开始 虽然总字符数靠前,但当前已经是固定短字段;它们应继续保留作为链路节点,不应仅按总量再次删除。真正优先的是仍然打印完整业务对象的 P0/P1 日志。
6. 下一批具体落地方案
6.1 P0:setConversationRecord:生成会话记录
当前代码位于 application/Services/MoveMall/RobotInquiryBaseSer.php:2183 附近,打印的是完整 $data。其中最容易变大的字段是:
source_content:可能是图片、音频地址或较长原始内容。text:用户原始文本。keyword:完整关键词解析结果 JSON。- 其它联系人、服务站、会话字段:与前面节点重复。
建议改成一条摘要日志,保留:
request_id, cv_id, contact_id, sid, wxid, role,
source_type, source_content_length, text_length,
keyword_count/keyword_type, text_flag, text_flag_order_type
不要在成功 info 中打印 source_content、完整 text、完整 keyword。如果 conversationRecordModel->add() 失败,错误日志保留上述 ID 和失败原因;需要复现原始输入时,通过同一 request_id 回查入口 收到消息,而不是依赖这条数据库记录日志。
6.2 P0:searchWxList:查询到商城商品数量
当前代码位于 application/Services/MoveMall/MoveMallGoodsSer.php:1202 附近,变量 $res 是完整商品查询返回,不是“数量”。
成功路径建议只记录:
request_id, vin, page, page_size, result_code,
rows_count, category_count, car_count,
first_product_ids/top_product_codes, elapsed_ms
异常路径记录接口错误码、接口耗时、查询条件摘要;完整 $res 只在异常或临时 debug 开关打开时打印,并且要有截断上限。这样仍能判断“是否查询到商品、数量是否异常、过滤条件是否命中”,但不会把数百 KB 的商品数组每次写入日志。
本次已在 bugfix/20260827-log 完成最小修改,并抽取为公共方法 BaseSer::formatLogContext():
searchWxList和searchWxList-self两条日志都统一处理,避免只改微仓路径而遗漏自提仓路径。- 公共方法先将数据序列化为 JSON,再按 UTF-8 字符数限制到 500 个字符;超过上限时保留前 497 个字符并追加
...,后续其它服务日志也可以复用。 - 日志只使用截断后的
result字符串,业务后续仍继续使用原始$res,不改变商品查询、过滤和返回逻辑。 - JSON 序列化失败时只记录短错误提示,不会因为日志处理影响业务流程。
当前状态:代码已发布到预发,并已通过真实消息链路验证;searchWxList 的结果上下文为 500 字符,超长时末尾为 ...。整体 15 分钟窗口的长期量级仍需在业务高峰期持续观察,单次验证结果见第 12 节。
6.3 P0:setContact:设置联系人
当前代码位于 application/Services/MoveMall/RobotInquiryBaseSer.php:221,完整 contact 是明确的大量来源,而且前后多个节点都有 contact。
建议保留:
request_id, contact_id, sid, chat_group_id,
wxid, wxname, contact_name, bind_match=true/false
不要在正常成功路径打印完整 $this->contact。联系人为空、服务站不匹配时,保留 bindWxId、回调服务站、绑定服务站、错误原因;这已经足够定位“找不到绑定客户”和“绑定站点不一致”。
6.4 P0:处理optionPrivateChat
当前代码位于 application/Services/MoveMall/RobotInquiryBaseSer.php:2098,每次直接打印完整 $this->notify,而入口已经保存完整消息。
建议保留:
request_id, msg_id, event, from_wxid, to_wxid, robot_wxid,
content_type, content_length, verify_code_flow=true
验证码校验失败保留 error;只在异常且确需复现时,通过 RequestId 回查入口原始消息。这样能判断是否进入验证码分支、处理的是哪条消息,也不会丢链路。
6.5 P1:库存、商品和排序循环日志
| 代码日志点 | 当前问题 | 建议保留 | 建议删除/限制 |
|---|---|---|---|
filterSearchResult:商品库存debug,RobotInquirySer.php:1840 | 循环内每个商品打印完整 $it | invId、product_code、categoryId、原库存、最终库存、过滤原因 | 删除完整 $it;只在库存异常时打印,或增加 debug 开关 |
formatMessage:开始处理商品数据,RobotInquirySer.php:3777 | 打印完整 goods | goods_count、分类数、产品码数、处理耗时 | 删除完整 goods |
formatMessage: 物料信息,RobotInquirySer.php:3692 | 与上一条再次打印完整 goods | 如果需要节点标志,只保留 goods_count、首尾 ID、分类统计 | 两条合并成一条摘要,不要两次打印同一 goods |
searchWearingParts:排序信息,RobotInquirySer.php:3415 | 打印完整排序数据 | 排序规则、输入数、输出数、前 3 个商品 ID/产品码、耗时 | 删除完整 data |
searchWearingPartsByKeyword:排序信息,RobotInquirySer.php:2917 | 同类排序结果再次打印完整数组 | 同上 | 删除完整数组,只保留摘要 |
searchWearingPartsByKeyword:合并无车关键词查询到的商品结果,RobotInquirySer.php:2705 | 打印完整 allGoods | 合并前后数量、关键词、去重数量 | 删除完整商品数组 |
6.6 P1/P2:高频小日志和长尾大日志
unlock:释放锁:释放失败必须保留;正常成功可以改为debug或按比例采样,仍保留获取锁失败、释放失败和耗时超阈值日志。formatMessage:缓存数据:保留缓存命中/未命中、key 类型、数据条数、序列号范围;不打印完整cacheData/showData。processVinConversation:车型解析成功:保留cars_count、首个车型 ID/名称、耗时;完整cars仅在解析异常时输出。RobotSegmentationService: 开始处理@提醒文本:保留文本长度、成员数量、前 N 个成员 ID;对文本设置长度上限,避免 57KB 单条日志。checkAndPlaceAgentOrder:根据报价记录获取最近会话信息:保留报价记录 ID、会话 ID、查询耗时;不要输出完整 SQL 和完整 conversation,SQL 异常另行记录 SQL 类型/模板标识。- Kafka 消费循环中的
当前IP:进程启动或 IP 变化时打印一次即可。 - Kafka
Local: Timed out:正常 poll 超时不是业务异常,不应每次以 error/info 打印;只统计计数,连续超时超过阈值或发生非 timeout 错误时告警。
7. “一条消息一份完整证据”的链路设计
一条消息的推荐查询顺序如下:
Kafka 收到消息(唯一完整 payload)
|
+--> onMessage 开始(确认进入处理,RequestId/内存信息)
|
+--> parseNotify(msg_id/event/from/robot 摘要)
|
+--> setContact(绑定微信、联系人和服务站摘要)
|
+--> loadConversation(cvKey、conversation、pre 会话 ID/状态)
|
+--> 商品查询/库存/排序(数量、ID、耗时摘要)
|
+--> 会话落库(记录 ID/会话 ID/内容长度/标志位)
|
+--> onMessage 结束 或 消息处理失败
排查时优先使用:
RequestId:串起一次消费处理链路。msg_id:确认是不是同一条微信消息;当内部服务重新生成 RequestId 时,用它补充关联。contact_id、cv_id、record_id、sid:定位联系人、会话、落库记录和服务站。source_type、数量、耗时和错误原因:判断是在入口、绑定、会话、商品查询还是落库阶段出问题。
因此,减少下游完整对象不会导致无法排查,前提是入口确实保留一份完整消息,并且所有下游节点都保留稳定关联字段。绝不能把入口完整日志、格式错误完整日志和异常证据同时删掉。
8. 当前代码风险与本次日志优化无关的独立问题
以下问题不应通过“多打印日志”掩盖,需要单独立 Bug:
Robot.php当前在处理消息前提交 Kafka offset;如果后续处理失败,可能已经无法重新消费。onMessage内部捕获异常后如果返回成功,外层消费者可能记录成功并提交 offset,导致“业务失败但消费成功”的状态不一致。消息处理失败的 trace 优化只适用于明确的业务预期异常,例如“未绑定客户”;未知 PHP 异常、外部接口异常仍必须保留 trace 或错误定位信息。- 任何完整日志改摘要,都必须保证不改变原有业务变量和返回值;日志表达式也不能调用有副作用的方法。
9. 每次发布后的验证清单
| 验证项 | 通过标准 |
|---|---|
| 语法检查 | 修改 PHP 文件执行 php -l,无语法错误 |
| 入口证据 | 指定测试消息能查到一条完整 收到消息 |
| 链路关联 | 入口的 RequestId/msg_id 能查到 parseNotify、联系人、会话和结束/失败节点 |
| 节点完整性 | 每个关键节点至少有一条短日志,能判断是否进入和结果是什么 |
| 业务异常 | “未绑定客户”无无意义 trace;未知异常仍有 trace/error |
| 日志大小 | 以相同 15 分钟窗口比较总字符、平均字符、最大单条;不能只比较条数 |
| 内容安全 | 不把密码、token、完整 SQL 参数、超长图片/音频内容写入正常 info |
| 回滚能力 | 变更尽量只注释/替换日志字段,不改业务分支;发现排查缺字段时可快速恢复 |
10. 变更记录
| 日期 | 变更 | 结果 |
|---|---|---|
| 2026-08-26 20:15 | 发布入口及部分下游日志精简:onMessage、parseNotify、联系人/会话节点、WechatSer、未绑定客户异常 | 重点窗口从 88.59M 字符降至 1.81M 字符;完整入口证据仍保留 |
| 2026-08-27 | 按最新 Kibana 15 分钟窗口重新排名;校正 verifyBindContactCode 的占比口径 | 当前 Services/info 中该日志约占 96.6% 字符,不是 99.6%;当前已是短日志,后续优先级转向完整商品/会话对象 |
| 2026-08-27 | 修改 MoveMallGoodsSer::getMoveMallGoods() 中 searchWxList、searchWxList-self 的完整 $res 日志 | 两条日志统一限制为最多 500 个字符,业务继续使用原始 $res;预发实测已命中并确认截断生效 |
| 2026-08-27 | 抽取 BaseSer::formatLogContext() 统一处理 JSON 日志截断 | 避免每个日志点重复编写序列化、长度判断和异常兜底逻辑;预发 PHP 语法和真实业务链路均验证通过 |
| 2026-08-27 | 建立本日志优化持续台账 | 后续每个优化点必须补充“原来/现在/量级/排查能力/验证结果” |
11. 后续追加模板
12. 2026-09-10 生产搜索日志发布验证
本次验证只统计 DGJ 自身日志,不能将 VinAudit 服务端 /product/search 混入 DGJ 最大日志排名。
12.1 DGJ OfferProvider 搜索响应
- 目标入口:DGJ 调 Sale
/offer/search/list的成功响应日志;phone/offer/search/list和其他 Provider 不在本次改动范围。 - 生产验证窗口:2026-09-10 21:10–21:25。
- 258 条请求对应 258 条响应,258 条为新摘要格式,旧的完整
data响应为 0;code=0,ProviderErrorException、RequestTimeoutException、PHP Fatal、Uncaught均为 0。 - 同口径上线前后字符量:
2,010,924 -> 488,296;平均单条:24,228 -> 7,077;最大单条:79,652 -> 19,813;总字符量下降约 75.7%。原始业务响应仍由代码返回给调用方,摘要只用于日志。
12.2 DGJ 自身剩余日志排序
在 2026-09-10 21:55–22:10 窗口、来源限定 /data/logs/dgj/ 的统计为:
| 日志来源 | 条数 | 总字符数 | 后续动作 |
|---|---|---|---|
DataService | 344 | 16.49M | 优先将 skuSaleNum 完整数组改为数量/汇总摘要 |
providers/default | 6,134 | 16.35M | 其中 AES 请求约 7.87M,优先移除成功请求中的完整密文/大配置 |
providers/VinAudit | 1,074 | 5.04M | 保留客户端链路字段,按接口继续拆分 |
inventoryCenter | 966 | 4.88M | 后续按返回数量和库存摘要评估 |
OfferProvider | 648 | 2.11M | 搜索摘要已生效,继续观察长尾 |
该窗口 DGJ 自身日志约 56.85M 字符。更早同口径对比显示 DGJ 总量约 2,668.96M -> 1,419.36M 字符、下降约 46.8%;providers/default 响应约下降 98.4%,AES 请求仅下降约 4.3%,因此下一优先级是 AES 请求而不是已完成的搜索响应摘要。
12.3 跨系统关联边界
DGJ、Sale、VinAudit 当前各自保留本地 RequestId;Sale 请求体可完整解析,但正常大响应日志在约 1,024 字符处截断,业务响应本身未截断。后续建议增加 Dgj-Request-Id 请求头并由下游继续透传,同时保留各系统本地 ID,先做单节点验证,不直接覆盖现有 request_id。
新增优化时直接复制下面的表格行,并补齐真实 Kibana 数据:
| 日期 | 优先级 | 日志点 | 代码位置 | 原来怎么记 | 原始条数/字符/最大单条 | 现在怎么记 | 优化后条数/字符/最大单条 | RequestId/业务 ID 是否保留 | 验证与风险 |
|---|---|---|---|---|---|---|---|---|---|
| YYYY-MM-DD | P0/P1/P2 | 日志文案 | 文件:行号 | 完整对象/重复字段/异常堆栈 | N / M / X | 摘要字段与异常策略 | N / M / X | 是/否,具体字段 | php -l、Kibana、业务消息验证 |
12. 2026-08-27 预发真实链路验证
12.1 验证方式
通过预发入口调用正常 Robot 消息接口:
POST http://dgj-staging.kzmall.cc/index.php/moveMall/RobotController/receiveMsg
调用从预发 Robot 主机发起,使用预发已绑定会话和测试 VIN;先发送 VIN 完成车型解析,再发送“VIN + 已配置品类词”,确保真正进入 searchWxList。本次未访问线上 Kibana,也未修改预发服务器配置。
12.2 代码与主机确认
| 检查项 | 结果 |
|---|---|
| 实际处理应用 | staging-dgj-1(10.90.21.11),不是 staging-dgj-admin(10.90.21.12) |
BaseSer.php | 已存在 formatLogContext(),默认上限 500 字符 |
MoveMallGoodsSer.php | searchWxList、searchWxList-self 均调用公共截断方法 |
NotifyModule.php | parseNotify 只保留链路字段,完整原始消息不在该节点重复打印 |
| PHP 语法 | 三个修改文件执行 /usr/local/php/bin/php -l,均无语法错误 |
| Kafka 消费进程 | inner/moveMall/Robot/consumeKafkaMessage 进程正常存在 |
12.3 业务调用与日志结果
| 日志/结果 | 原来量级或问题 | 本次预发实测 | 判断 |
|---|---|---|---|
| 接口返回 | 需要确认是否影响业务 | HTTP 200,返回 success,目标商品查询链路耗时约 3.23 秒 | 业务主流程成功 |
robot_inquiry | 单条可能包含完整业务对象 | 本次 RequestId 共 31 条,累计约 11.6KB;入口、解析、联系人、会话、检索、结束节点均存在 | 链路节点未丢失 |
searchWxList:查询到商城商品数量 | 旧数据中最大单条约 220KB | 本次日志总长约 708 字符,result 上下文严格 500 字符,并以 ... 结束 | 截断生效,未改变 $res 业务数据 |
处理verifyBindContactCode | 原来可能重复携带完整对象 | 本次单条约 289 字符,仅保留 event/final_from_wxid/msg_id/request_id/robot_wxid | 链路字段仍可关联 |
| 关联错误日志 | 需要确认是否出现异常 | 本次 RequestId 未发现 ERROR、Exception、失败或错误日志 | 未发现本次改动引起的运行异常 |
12.4 测试过程中的独立兼容性问题
第一次人工构造报文使用了 final_from_name,而当前历史协议/代码读取的是拼写为 fina_from_name 的字段,导致测试报文在会话记录落库时出现 wxname cannot be null。修正为真实报文字段后调用成功;这属于测试报文协议兼容问题,不是日志截断改动造成的业务错误。后续构造测试报文必须复用真实网关报文字段,不要自行改写字段名。
12.5 发布后继续观察
本次是单次真实链路验证,证明功能和截断逻辑正常,但不能代替高峰期统计。下一步按相同 15 分钟窗口对比:searchWxList 总字符数、平均单条、最大单条,以及 robot_inquiry 总量;重点确认高峰期是否还有其它完整 goods、conversation、排序数组日志成为新的 P0。