--- todos: - id: "migrate-log-calls" content: "13 个文件:LoggerService::info/error/warning → support\\Log,统一 context 为 array" status: pending - id: "migrate-trace-timing" content: "InnerCurlService / OutputService / EventBus:改用 Context + TraceIdMiddleware::initContext" status: pending - id: "delete-logger-service" content: "删除 LoggerService.php,更新 README §8.1" status: pending - id: "fix-handler-syntax" content: "修复 app/exception/Handler.php 末尾多余花括号" status: pending - id: "verify" content: "grep 无残留引用 + 跑 report.sh + CLI/HTTP/MQ 冒烟" status: pending isProject: false --- # slot_agent 废弃 LoggerService 完整迁移 ## 结论 **可以不再使用 `LoggerService` 写日志**,但不能「只配好 `config/log.php` 就删类」——当前仍有 **13 个文件、约 56 处** `LoggerService::` 调用,且 3 处依赖其 trace/timing 工具方法。 你已有的新栈已覆盖旧能力: | 能力 | LoggerService(旧) | 新配置 | |------|---------------------|--------| | 落盘 | 直接 `SeasLog::*` | [`config/log.php`](slot_agent/config/log.php) → `SeasLogHandler` | | traceId | `$_SERVER['TRACE_ID']` 手动拼进 message | [`TraceIdMiddleware`](slot-foundation/src/Middleware/TraceIdMiddleware.php) → `Context::get('trace_id')` + `SeasLog::setRequestID` | | 调用位置 | `debug_backtrace` 手动 JSON | `IntrospectionProcessor`(已排除 `support\Log`) | | 请求耗时 | `$_SERVER['REQUEST_TIME_FLOAT']`(HTTP 几乎未初始化) | `Context::get('request_time')`(Middleware 已写入) | 当前项目处于 **双轨并存**,会导致同一次请求里日志格式、trace 来源不一致: - 已用 `support\Log`:[`AuthMiddleware`](slot_agent/app/middleware/AuthMiddleware.php)、[`RabbitMqService`](slot_agent/app/service/RabbitMqService.php)、[`Test`](slot_agent/app/command/Test.php) - 仍用 `LoggerService`:EventBus、各 Service/Logic、Exception Handler 等 ```mermaid flowchart LR subgraph old [旧路径] LS[LoggerService] --> SeasLogDirect[SeasLog 直连] LS --> ServerTrace["$_SERVER TRACE_ID"] end subgraph new [新路径] LogFacade["support\\Log"] --> Monolog[Monolog] Monolog --> Handler[SeasLogHandler] Handler --> SeasLogCtx[SeasLog + Context trace_id] TraceMW[TraceIdMiddleware] --> Context[Context] end ``` --- ## 迁移范围(按职责) ### 1. 写日志:统一改为 `support\Log` 涉及文件(全部在 `slot_agent/app/` 下): - [`command/EventBus.php`](slot_agent/app/command/EventBus.php)(15 处) - [`innerapi/logic/AgentLogic.php`](slot_agent/app/innerapi/logic/AgentLogic.php) - [`service/ReferralRewardConfigService.php`](slot_agent/app/service/ReferralRewardConfigService.php)(9 处) - [`service/InnerCurlService.php`](slot_agent/app/service/InnerCurlService.php)(8 处日志) - [`service/UserReferralGatewayService.php`](slot_agent/app/service/UserReferralGatewayService.php) - [`service/ReferralRewardService.php`](slot_agent/app/service/ReferralRewardService.php) - [`service/activity/UserAgentRegisterService.php`](slot_agent/app/service/activity/UserAgentRegisterService.php) - [`service/LuckyRewardInviteCallbackGatewayService.php`](slot_agent/app/service/LuckyRewardInviteCallbackGatewayService.php) - [`service/ShareConfigService.php`](slot_agent/app/service/ShareConfigService.php) - [`exception/Handler.php`](slot_agent/app/exception/Handler.php) - [`innerapi/exception/Handler.php`](slot_agent/app/innerapi/exception/Handler.php) **替换约定**(与现有 `AuthMiddleware` 对齐): ```php // 旧 LoggerService::info(__METHOD__, $payload); // 新 — context 必须是 array,标量包一层 Log::info(__METHOD__, is_array($payload) ? $payload : ['msg' => $payload]); ``` ```php // 旧 — Throwable LoggerService::error(__METHOD__, $exception); // 新 — 与 AuthMiddleware 一致 Log::error($exception); // 或需要业务前缀时: Log::error(__METHOD__, ['msg' => $exception->getMessage(), 'file' => $exception->getFile(), 'line' => $exception->getLine()]); ``` CLI/MQ 消费若需独立 trace,在 handler 入口调用一次: ```php use Slot\Foundation\Middleware\TraceIdMiddleware; TraceIdMiddleware::initContext(); // 替代 LoggerService::initGenerateTraceId() ``` [`EventBus::deal()`](slot_agent/app/command/EventBus.php) 第 59 行即此处。 ### 2. trace / timing:改用 Context,不再读 `$_SERVER` | 文件 | 旧 API | 新 API | |------|--------|--------| | [`InnerCurlService`](slot_agent/app/service/InnerCurlService.php) | `LoggerService::getTraceId()` | `Context::get('trace_id')`;空则 `TraceIdMiddleware::initContext()` 后再取 | | [`OutputService`](slot_agent/app/service/OutputService.php) | `LoggerService::getRequestTime()` | `Context::get('request_time', microtime(true))`,`timing = microtime(true) - $start` | | [`EventBus`](slot_agent/app/command/EventBus.php) | `initGenerateTraceId()` | `TraceIdMiddleware::initContext()` | `TRACE_CHILD_ID` / `setChildId` / `initRequestTime` 在 slot_agent **无任何调用**,删除 `LoggerService` 时一并移除即可。 ### 3. 删除与文档 - 删除 [`app/service/LoggerService.php`](slot_agent/app/service/LoggerService.php) - 更新 [`README.md`](slot_agent/README.md) §8.1:由「统一 `LoggerService`」改为「统一 `support\Log` + `Context trace_id`」 - **保留** [`AppBootStrap`](slot_agent/app/AppBootStrap.php):仍负责 SeasLog 按 worker 分目录(`cli` / `webman`),与 `SeasLogHandler` 互补 ### 4. 顺带修复(改 Handler 时) [`app/exception/Handler.php`](slot_agent/app/exception/Handler.php) 文件末尾有多余 `{\n\n}`,迁移时一并去掉,避免语法问题。 --- ## 不需要改动的部分 - [`config/log.php`](slot_agent/config/log.php) — 已就绪 - [`config/middleware.php`](slot_agent/config/middleware.php) — `TraceIdMiddleware` 已在最前 - [`config/process.php`](slot_agent/config/process.php) — 已注入 `Log::channel('default')` --- ## 验证 1. 跑 completion report:`SLOT_ROOT=/Users/ray/Documents/project/www/slot/slot_agent ~/.cursor/skills/slot-backend-completion-report/scripts/report.sh` 2. 手动冒烟: - HTTP:`AuthMiddleware` 已有 `Log::info`,确认 `runtime/logs/webman/` 含 trace + 调用栈 - CLI:`php webman test`([`Test.php`](slot_agent/app/command/Test.php) 已有 Log 示例) - MQ:`event:bus` 消费一条消息,确认 CLI 日志有独立 trace_id 3. 确认全仓库 `slot_agent` 内无 `LoggerService` 引用 --- ## 风险与注意 - **日志格式会变**:旧格式为 `trace_id|Class::method | json {"file":...}` 单行;新格式由 `SeasLogLineFormatter` + `IntrospectionProcessor` 决定。若 ELK/告警规则按旧格式解析,需同步调整。 - **跨服务 trace 传递**:`InnerCurlService` 请求头 `traceId` 应改为传 `Context::get('trace_id')`,与 [`TraceIdMiddleware`](slot-foundation/src/Middleware/TraceIdMiddleware.php) 一致(不再用 `trace_id:xxx` 前缀的 uniqid 格式)。 - **OutputService timing 行为会修正**:HTTP 请求将正确使用 Middleware 写入的 `request_time`,不再依赖几乎未初始化的 `REQUEST_TIME_FLOAT`。