logo
0
0
WeChat Login

Webman Trace 插件

Webman Plugin PHP Version License

一个功能强大的 Webman 框架请求链路追踪插件,提供完整的调试和监控解决方案。

✨ 核心特性

🎯 自动追踪

  • 唯一 Trace ID - 每个请求自动生成唯一标识
  • 全链路记录 - 请求、响应、SQL、异常一网打尽
  • 零配置启动 - 安装即用,无需手动配置
  • 中间件自动注册 - 全局拦截,无遗漏

🎨 美化输出

  • 🌈 控制台彩色显示 - 类似 thinkorm-log 的美观样式
  • 📊 Web查询界面 - 高级过滤、实时查看、详情展示
  • 🔧 详细/简洁模式 - 可切换的显示级别
  • 📝 JSON格式日志 - 便于 ELK/Loki 等系统接入

🛡️ 安全可控

  • 🔐 Web界面认证 - 可选密码保护
  • ⚙️ 灵活配置 - 开发/生产环境不同策略
  • 🚫 忽略路径 - 过滤不需要追踪的请求
  • 🎛️ 404追踪控制 - 可选的404页面追踪

🚀 开发友好

  • 📋 便捷API - jsont_success(), jsont_error() 等方法
  • 🔍 调试增强 - trace_info(), trace_error() 等日志函数
  • 🎨 美观展示 - 边框、图标、颜色一应俱全
  • 高性能 - 最小化性能影响

📦 快速安装

一键安装

composer require openb8/webman-trace

安装完成即可使用! 插件会自动:

  • ✅ 生成配置文件到 config/plugin/openb8/webman-trace/
  • ✅ 注册全局中间件
  • ✅ 配置Web查询路由
  • ✅ 启动所有追踪功能

启动服务

php start.php restart

立即享受完整的追踪功能!

🎯 立即可用功能

控制台美化输出

启动服务后,控制台会显示类似这样的美观输出:

🚀 新请求 [trace-abc123] ┃ 时间: 2024-01-30 10:00:00 ┃ 方法: POST ┃ 路径: /api/user/login ┃ 来源IP: 127.0.0.1 ┃ 请求参数: ┃ { ┃ "username": "admin", ┃ "password": "******" ┃ } ┌─────────────────────────────────────────────────────────────┐ │ 时间: 2024-01-30 10:00:00 │ Trace ID: trace-abc123 │ 状态码: ✅ 200 │ 请求方式: POST │ 接口: /api/user/login │ 耗时: 25.67ms │ 响应数据: │ { │ "code": 0, │ "msg": "登录成功", │ "data": {...} │ } └─────────────────────────────────────────────────────────────┘

Web查询界面

访问 http://127.0.0.1:8787/trace 即可使用:

  • 🔍 高级过滤: 按 Trace ID、类型、级别、时间范围搜索
  • 📊 实时查看: 最新的 trace 日志
  • 📋 详情展示: 点击查看完整 trace 链路
  • 🗑️ 日志管理: 一键清理旧日志
  • 🔐 认证保护: 可选的密码保护

⚙️ 配置说明

配置文件:config/plugin/openb8/webman-trace/app.php

开发环境推荐配置

return [ 'enable' => true, // 控制台美化输出 'console_output' => [ 'enable' => true, 'verbose' => true, // 显示详细信息 'beautiful' => true, // 美化显示 'levels' => ['request', 'response', 'exception', 'slow_query'], ], // Web查询界面 'web_interface' => [ 'enable' => true, 'path_prefix' => '/trace', 'auth_required' => false, // 开发环境无需认证 ], // 请求体和响应体记录 'log_body' => [ 'request' => true, // 记录请求参数 'response' => true, // 记录响应数据 'max_length' => 1024, // 最大长度限制 ], // 404追踪 'handle_404' => [ 'enable' => true, // 启用404追踪 'custom_response' => false, // 仅记录,不覆盖原有404页面 ], ];

生产环境推荐配置

return [ 'enable' => true, // 关闭控制台输出(减少性能影响) 'console_output' => [ 'enable' => false, ], // Web界面需要认证 'web_interface' => [ 'enable' => true, 'auth_required' => true, 'access_password' => 'your-secure-password', ], // 减少日志体积 'log_body' => [ 'request' => false, 'response' => false, ], // 仅记录关键信息 'log_levels' => [ 'request' => 'info', 'response' => 'info', 'sql' => 'warning', // 只记录慢查询 'exception' => 'error', ], ];

完整配置选项

return [ // 基础开关 'enable' => true, 'log_sql' => true, 'log_exception' => true, 'log_request' => true, 'debug_only' => false, // 控制台输出 'console_output' => [ 'enable' => true, 'levels' => ['request', 'response', 'exception', 'slow_query'], 'verbose' => true, // 详细模式开关 'beautiful' => true, // 美化输出开关 ], // Web查询界面 'web_interface' => [ 'enable' => true, 'path_prefix' => '/trace', 'auth_required' => false, 'access_password' => 'trace123', 'per_page' => 20, ], // 404处理 'handle_404' => [ 'enable' => true, // 启用404追踪 'custom_response' => false, // 是否自定义404响应 'response_body' => '404 Not Found', // 自定义404页面内容 ], // 日志配置 'log_file' => 'runtime/logs/trace.log', 'trace_id_key' => 'X-Trace-Id', 'trace_id_generator' => \OpenB8\WebmanTrace\Generator\UuidGenerator::class, // 过滤配置 'ignore_paths' => [ '/favicon.ico', '/robots.txt', '/health', ], // 性能配置 'slow_query_threshold' => 1000, // 慢查询阈值(毫秒) 'log_body' => [ 'request' => true, 'response' => true, 'max_length' => 1024, ], // 日志级别 'log_levels' => [ 'request' => 'info', 'response' => 'info', 'sql' => 'debug', 'exception' => 'error', 'slow_query' => 'warning', ], ];

🛠️ 使用方法

获取 Trace ID

// 在任何地方获取当前请求的 Trace ID $traceId = trace_id(); echo "当前 Trace ID: " . $traceId;

记录业务日志

// 使用便捷的日志函数(自动包含 trace_id) trace_info('用户登录成功', ['user_id' => 123]); trace_error('数据库连接失败', ['error' => $exception->getMessage()]); trace_debug('调试信息', ['data' => $debugData]); trace_warning('磁盘空间不足', ['usage' => '90%']);

JSON 响应方法

插件提供了四个便捷的 JSON 响应方法,自动包含 Trace ID:

1. jsont() - 基础响应

// 自动为任何数据添加 trace_id return jsont(['name' => '张三', 'age' => 25]); // 输出: {"name": "张三", "age": 25, "trace_id": "abc123"} return jsont($user, 200, ['Custom-Header' => 'value']);

2. jsont_success() - 成功响应

return jsont_success($user, '获取用户信息成功'); // 输出: { // "code": 0, // "message": "获取用户信息成功", // "data": {...}, // "trace_id": "abc123" // }

3. jsont_error() - 错误响应

return jsont_error('用户不存在', 1001, null, 404); // 输出: { // "code": 1001, // "message": "用户不存在", // "trace_id": "abc123" // } // HTTP状态码: 404 // 带错误详情 return jsont_error('验证失败', 1002, ['field' => 'email']);

4. jsont_paginate() - 分页响应

return jsont_paginate($users, 100, 2, 10, '获取用户列表成功'); // 输出: { // "code": 0, // "message": "获取用户列表成功", // "data": { // "items": [...], // "pagination": { // "total": 100, // "page": 2, // "page_size": 10, // "total_pages": 10, // "has_next": true, // "has_prev": true // } // }, // "trace_id": "abc123" // }

控制器示例

<?php class UserController { public function login($request) { // 记录开始处理 trace_info('开始处理用户登录', [ 'ip' => $request->getRealIp(), 'user_agent' => $request->header('user-agent') ]); try { // 业务逻辑 $user = $this->authenticate($request); // 记录成功 trace_info('用户登录成功', ['user_id' => $user->id]); // 返回成功响应(自动包含 trace_id) return jsont_success([ 'user' => $user, 'token' => $this->generateToken($user) ], '登录成功'); } catch (\Exception $e) { // 记录异常(异常会被自动追踪) trace_error('用户登录失败', [ 'error' => $e->getMessage(), 'code' => $e->getCode() ]); // 返回错误响应 return jsont_error('登录失败: ' . $e->getMessage(), 1001, null, 401); } } public function getUserList($request) { $page = max(1, (int)$request->get('page', 1)); $pageSize = min(100, max(1, (int)$request->get('page_size', 15))); try { $users = $this->userService->getUsers($page, $pageSize); $total = $this->userService->getUserCount(); // 分页响应 return jsont_paginate($users, $total, $page, $pageSize); } catch (\Exception $e) { return jsont_error('获取用户列表失败', 2001); } } }

📊 日志格式

插件生成标准的 JSON 格式日志,便于各种日志系统解析:

请求日志

{ "trace_id": "trace-abc123456789", "level": "INFO", "type": "request", "method": "POST", "path": "/api/user/login", "query": "remember=1", "user_agent": "Mozilla/5.0...", "ip": "127.0.0.1", "body": "{\"username\":\"admin\",\"password\":\"******\"}", "timestamp": "2024-01-30T10:00:00.123+08:00" }

响应日志

{ "trace_id": "trace-abc123456789", "level": "INFO", "type": "response", "method": "POST", "path": "/api/user/login", "status": 200, "duration": "25.67ms", "body": "{\"code\":0,\"message\":\"登录成功\",\"data\":{...}}", "timestamp": "2024-01-30T10:00:00.148+08:00" }

SQL日志

{ "trace_id": "trace-abc123456789", "level": "DEBUG", "type": "sql", "sql": "SELECT * FROM users WHERE email = ? AND status = ?", "bindings": ["admin@example.com", 1], "time": "12.34ms", "timestamp": "2024-01-30T10:00:00.135+08:00" }

异常日志

{ "trace_id": "trace-abc123456789", "level": "ERROR", "type": "exception", "class": "InvalidArgumentException", "message": "用户名不能为空", "file": "/var/www/app/controller/UserController.php", "line": 45, "trace": "Exception trace...", "method": "POST", "path": "/api/user/login", "timestamp": "2024-01-30T10:00:00.140+08:00" }

🎨 控制台输出效果

详细模式 (verbose = true)

显示完整的请求参数和响应数据:

🚀 新请求 [trace-abc123] ┃ 时间: 2024-01-30 10:00:00 ┃ 方法: POST ┃ 路径: /api/user/login ┃ 来源IP: 127.0.0.1 ┃ 查询参数: remember=1 ┃ 请求参数: ┃ { ┃ "username": "admin", ┃ "password": "123456" ┃ } ┌─────────────────────────────────────────────────────────────┐ │ 时间: 2024-01-30 10:00:00 │ Trace ID: trace-abc123 │ 状态码: ✅ 200 │ 请求方式: POST │ 接口: /api/user/login │ 耗时: 25.67ms │ 响应数据: │ { │ "code": 0, │ "message": "登录成功", │ "data": { │ "user": {...}, │ "token": "..." │ } │ } └─────────────────────────────────────────────────────────────┘ 💥 异常发生 [trace-abc123] ┃ 时间: 2024-01-30 10:00:05 ┃ 类型: InvalidArgumentException ┃ 消息: 用户名不能为空 ┃ 位置: UserController.php:45 🔍 SQL查询 [trace-abc123] ┃ 时间: 2024-01-30 10:00:01 ┃ 耗时: 12.34ms ┃ SQL: SELECT * FROM users WHERE email = ? AND status = ? ┃ 参数: ["admin@example.com", 1]

简洁模式 (verbose = false)

只显示关键信息:

🚀 新请求 [trace-abc123] ┃ 时间: 2024-01-30 10:00:00 ┃ 方法: POST ┃ 路径: /api/user/login ┃ 来源IP: 127.0.0.1 ┌─────────────────────────────────────────────────────────────┐ │ 时间: 2024-01-30 10:00:00 │ Trace ID: trace-abc123 │ 状态码: ✅ 200 │ 请求方式: POST │ 接口: /api/user/login │ 耗时: 25.67ms └─────────────────────────────────────────────────────────────┘ 🔍 SQL查询 [trace-abc123] ┃ 时间: 2024-01-30 10:00:01 ┃ 耗时: 12.34ms ┃ SQL: SELECT * FROM users WHERE email = ? AND...

颜色说明

  • 🟢 绿色: 请求日志(🚀 图标)
  • 🔵 蓝色: 响应日志(边框样式)
  • 🟣 紫色: SQL 日志(🔍 图标)
  • 🔴 红色: 异常日志(💥 图标)
  • 🟡 黄色: 慢查询(🐌 图标)

🌐 Web查询界面

启用Web界面

'web_interface' => [ 'enable' => true, 'path_prefix' => '/trace', 'auth_required' => true, // 启用认证保护 'access_password' => 'trace123', 'per_page' => 20, ],

访问地址

http://127.0.0.1:8787/trace

界面功能

🔐 认证保护

  • 支持密码保护,防止未授权访问
  • 开发环境可关闭认证(auth_required: false
  • 生产环境建议启用认证

🔍 高级过滤

  • Trace ID: 精确或模糊搜索特定请求
  • 类型: request、response、sql、exception、slow_query
  • 级别: INFO、ERROR、WARNING、DEBUG
  • 时间范围: 自定义开始和结束时间
  • 组合过滤: 多条件组合查询

📊 数据展示

  • 列表视图: 分页显示,支持排序
  • 详情视图: 点击展开完整JSON数据
  • 实时刷新: 查看最新日志
  • 响应速度: 快速加载,流畅体验

🗑️ 日志管理

  • 一键清理: 删除指定天数前的日志
  • 存储统计: 显示日志文件大小和条数
  • 批量操作: 支持批量删除

🚀 高级功能

自定义 Trace ID 生成器

use OpenB8\WebmanTrace\Generator\GeneratorInterface; class CustomTraceGenerator implements GeneratorInterface { public function generate(): string { // 自定义生成逻辑 return 'custom_' . uniqid() . '_' . time(); } } // 在配置中指定 'trace_id_generator' => \App\Trace\CustomTraceGenerator::class,

外部 Trace ID 集成

插件支持从请求头中读取外部系统的 Trace ID:

# 传入外部 Trace ID curl -H "X-Trace-Id: external-system-trace-123" \ http://127.0.0.1:8787/api/users

忽略特定路径

'ignore_paths' => [ '/favicon.ico', '/robots.txt', '/health', '/metrics', '*.css', '*.js', '/static/*', ],

自定义日志处理

use OpenB8\WebmanTrace\TraceService; $config = config('plugin.openb8.webman-trace.app'); $traceService = new TraceService($config); // 手动记录 SQL $traceService->logSql( 'SELECT * FROM users WHERE id = ?', [123], 25.6 // 执行时间(毫秒) ); // 手动记录异常 try { // 业务代码 } catch (\Exception $e) { $traceService->logException($e, $request); }

性能优化建议

开发环境

'console_output' => [ 'enable' => true, 'verbose' => true, // 显示详细信息,便于调试 'beautiful' => true, // 美化输出 ], 'log_body' => [ 'request' => true, // 记录请求参数 'response' => true, // 记录响应数据 ],

生产环境

'console_output' => [ 'enable' => false, // 关闭控制台输出,减少性能影响 ], 'log_body' => [ 'request' => false, // 关闭请求体记录,减少日志体积 'response' => false, // 关闭响应体记录 ], 'slow_query_threshold' => 100, // 降低慢查询阈值

📋 示例代码

API 控制器完整示例

<?php namespace app\controller; use support\Request; use support\Response; class ApiController { /** * 用户注册 */ public function register(Request $request): Response { trace_info('开始用户注册', [ 'ip' => $request->getRealIp(), 'user_agent' => $request->header('user-agent') ]); try { // 验证参数 $username = $request->post('username'); $email = $request->post('email'); $password = $request->post('password'); if (empty($username) || empty($email) || empty($password)) { return jsont_error('参数不完整', 1001, [ 'required_fields' => ['username', 'email', 'password'] ], 400); } // 检查用户是否存在 if ($this->userExists($email)) { trace_warning('用户注册失败:邮箱已存在', ['email' => $email]); return jsont_error('邮箱已被注册', 1002, null, 409); } // 创建用户 $user = $this->createUser($username, $email, $password); trace_info('用户注册成功', ['user_id' => $user->id]); return jsont_success([ 'user' => [ 'id' => $user->id, 'username' => $user->username, 'email' => $user->email, 'created_at' => $user->created_at ] ], '注册成功'); } catch (\Exception $e) { trace_error('用户注册异常', [ 'error' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine() ]); return jsont_error('注册失败,请稍后重试', 5000, null, 500); } } /** * 获取用户列表(分页) */ public function userList(Request $request): Response { $page = max(1, (int)$request->get('page', 1)); $pageSize = min(100, max(1, (int)$request->get('page_size', 15))); $keyword = $request->get('keyword', ''); trace_info('获取用户列表', [ 'page' => $page, 'page_size' => $pageSize, 'keyword' => $keyword ]); try { $users = $this->searchUsers($keyword, $page, $pageSize); $total = $this->getUserCount($keyword); return jsont_paginate($users, $total, $page, $pageSize, '获取成功'); } catch (\Exception $e) { return jsont_error('获取用户列表失败', 3001); } } /** * 批量操作示例 */ public function batchUpdate(Request $request): Response { $userIds = $request->post('user_ids', []); $status = $request->post('status'); if (empty($userIds) || !is_array($userIds)) { return jsont_error('用户ID列表不能为空', 4001); } trace_info('批量更新用户状态', [ 'user_ids' => $userIds, 'status' => $status, 'count' => count($userIds) ]); try { $updated = 0; $failed = []; foreach ($userIds as $userId) { try { $this->updateUserStatus($userId, $status); $updated++; } catch (\Exception $e) { $failed[] = $userId; trace_warning('更新用户状态失败', [ 'user_id' => $userId, 'error' => $e->getMessage() ]); } } $result = [ 'updated' => $updated, 'failed' => $failed, 'total' => count($userIds) ]; if ($updated > 0) { trace_info('批量更新完成', $result); return jsont_success($result, "成功更新 {$updated} 个用户"); } else { return jsont_error('批量更新失败', 4002, $result); } } catch (\Exception $e) { return jsont_error('批量更新异常', 5001); } } // 私有方法示例... private function userExists(string $email): bool { // 模拟数据库查询 // return User::where('email', $email)->exists(); return false; } private function createUser(string $username, string $email, string $password): object { // 模拟用户创建 return (object)[ 'id' => rand(1000, 9999), 'username' => $username, 'email' => $email, 'created_at' => date('Y-m-d H:i:s') ]; } }

🔧 故障排除

1. 安装后没有效果

检查项:

  • 确认配置文件是否生成:config/plugin/openb8/webman-trace/app.php
  • 重启 webman 服务:php start.php restart
  • 检查配置中的 enable 是否为 true

2. 控制台没有彩色输出

解决方法:

// 检查配置文件 'console_output' => [ 'enable' => true, // 确保启用 'beautiful' => true, // 确保开启美化 'levels' => ['request', 'response', 'exception', 'slow_query'], ],

3. Web界面无法访问

检查项:

  • 访问地址是否正确:http://127.0.0.1:8787/trace
  • Web界面是否启用:'web_interface' => ['enable' => true]
  • 如果开启认证,确认密码:默认 trace123

4. 404页面没有追踪

解决方法:

'handle_404' => [ 'enable' => true, // 启用404追踪 'custom_response' => false, // 只记录,不覆盖原有404 ],

5. SQL日志没有记录

原因: 需要数据库ORM支持 解决方法:

# 安装支持的ORM composer require topthink/think-orm # 或 composer require illuminate/database

6. 日志文件过大

解决方法:

  • 使用Web界面的清理功能
  • 或手动删除:rm runtime/logs/trace.log
  • 配置日志轮转(推荐)

7. 性能影响

优化建议:

// 生产环境配置 'console_output' => ['enable' => false], // 关闭控制台输出 'log_body' => ['request' => false, 'response' => false], // 关闭body记录 'debug_only' => true, // 仅在调试模式记录

🔗 相关链接

🤝 贡献指南

欢迎提交 PR 和 Issue!

  1. Fork 项目
  2. 创建功能分支:git checkout -b feature/new-feature
  3. 提交更改:git commit -m 'Add new feature'
  4. 推送分支:git push origin feature/new-feature
  5. 提交 Pull Request

📄 开源协议

MIT License - 详见 LICENSE 文件

👥 关于作者

OpenB8 - 每个字节,都是起点

OpenB8 是一个专注于高质量开源项目的组织,致力于为开发者提供优秀的工具和解决方案。

微信二维码


🎉 享受愉快的开发体验!
如果这个插件对你有帮助,请给我们一个 ⭐ Star!