openb8 / webman-trace
A request trace plugin for Webman framework
dev-main
2025-06-30 22:45 UTC
Requires
- php: >=8.0
- workerman/webman-framework: ^1.0 || ^2.0
This package is not auto-updated.
Last update: 2025-07-01 02:05:11 UTC
README
一个功能强大的 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, // 仅在调试模式记录
🔗 相关链接
- Webman 官网: https://www.workerman.net/webman
- 插件市场: https://www.workerman.net/plugin
- GitHub: https://github.com/openb8/webman-trace
- 问题反馈: https://github.com/openb8/webman-trace/issues
🤝 贡献指南
欢迎提交 PR 和 Issue!
- Fork 项目
- 创建功能分支:
git checkout -b feature/new-feature
- 提交更改:
git commit -m 'Add new feature'
- 推送分支:
git push origin feature/new-feature
- 提交 Pull Request
📄 开源协议
MIT License - 详见 LICENSE 文件
👥 关于作者
OpenB8 - 每个字节,都是起点
OpenB8 是一个专注于高质量开源项目的组织,致力于为开发者提供优秀的工具和解决方案。
- 🌐 官网: www.openb8.com
- 📧 邮箱: allen@openb8.com
- 💬 微信: 扫描下方二维码
🎉 享受愉快的开发体验!
如果这个插件对你有帮助,请给我们一个 ⭐ Star!