本文目录导读:

在 Laravel 中记录 API 响应时间有多种方法,以下是几种常用且高效的方案:
使用中间件(推荐)
基础版中间件
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\Response;
class ResponseTimeLogger
{
public function handle($request, Closure $next)
{
$startTime = microtime(true);
/** @var Response $response */
$response = $next($request);
$duration = (microtime(true) - $startTime) * 1000; // 转换为毫秒
// 记录日志
Log::channel('api_response_time')->info('API Response Time', [
'method' => $request->method(),
'url' => $request->fullUrl(),
'duration_ms' => round($duration, 2),
'status_code' => $response->getStatusCode(),
'ip' => $request->ip(),
'user_agent' => $request->userAgent(),
]);
// 可选:在响应头中添加响应时间
$response->headers->set('X-Response-Time', round($duration, 2) . 'ms');
return $response;
}
}
注册中间件
在 app/Http/Kernel.php 中注册:
protected $routeMiddleware = [
// ... 其他中间件
'response.time' => \App\Http\Middleware\ResponseTimeLogger::class,
];
// 或者全局注册
protected $middleware = [
// ...
\App\Http\Middleware\ResponseTimeLogger::class,
];
在路由中使用
Route::middleware('response.time')->group(function () {
Route::get('/api/users', 'UserController@index');
Route::post('/api/users', 'UserController@store');
});
使用事件监听器
创建监听器
<?php
namespace App\Listeners;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\Response;
class LogResponseTime
{
public function handle($event)
{
$startTime = defined('LARAVEL_START') ? LARAVEL_START : $_SERVER['REQUEST_TIME_FLOAT'];
$duration = (microtime(true) - $startTime) * 1000;
if ($duration > 1000) { // 只记录超过1秒的慢请求
Log::warning('Slow API Response', [
'method' => request()->method(),
'url' => request()->fullUrl(),
'duration_ms' => round($duration, 2),
]);
}
}
}
注册事件
在 app/Providers/EventServiceProvider.php 中:
protected $listen = [
'kernel.handled' => [
'App\Listeners\LogResponseTime',
],
];
使用 Laravel Debugbar(开发环境)
安装包:
composer require barryvdh/laravel-debugbar --dev
自动记录所有请求的耗时信息,包括:
- 请求时间
- 数据库查询时间
- 视图渲染时间
- 等
自定义日志通道
配置日志通道
在 config/logging.php 中添加:
'channels' => [
'api_response_time' => [
'driver' => 'daily',
'path' => storage_path('logs/api-response-time.log'),
'level' => 'info',
'days' => 30,
],
// ... 其他通道
],
高级版中间件(支持标记慢请求)
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Log;
class AdvancedResponseTimeLogger
{
const SLOW_THRESHOLD_MS = 2000; // 慢请求阈值
public function handle($request, Closure $next)
{
$startTime = hrtime(true);
$response = $next($request);
$duration = (hrtime(true) - $startTime) / 1e6; // 纳秒转毫秒
$logLevel = $duration > self::SLOW_THRESHOLD_MS ? 'warning' : 'info';
Log::channel('api_response_time')->$logLevel('API Response', [
'method' => $request->method(),
'url' => $request->fullUrl(),
'duration_ms' => round($duration, 2),
'status_code' => $response->getStatusCode(),
'parameters' => $request->except(['password', 'token']),
'memory_usage_mb' => round(memory_get_peak_usage(true) / 1048576, 2),
]);
return $response;
}
}
记录到数据库(分析用)
创建数据表
Schema::create('api_response_logs', function (Blueprint $table) {
$table->id();
$table->string('method', 10);
$table->string('url', 500);
$table->float('duration_ms');
$table->integer('status_code');
$table->string('ip', 45)->nullable();
$table->float('memory_mb')->nullable();
$table->timestamps();
$table->index('created_at');
$table->index('duration_ms');
});
对应的 Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class ApiResponseLog extends Model
{
protected $fillable = [
'method', 'url', 'duration_ms', 'status_code', 'ip', 'memory_mb'
];
}
中间件存储到数据库
public function handle($request, Closure $next)
{
$startTime = microtime(true);
$response = $next($request);
ApiResponseLog::create([
'method' => $request->method(),
'url' => $request->fullUrl(),
'duration_ms' => round((microtime(true) - $startTime) * 1000, 2),
'status_code' => $response->getStatusCode(),
'ip' => $request->ip(),
'memory_mb' => round(memory_get_peak_usage(true) / 1048576, 2),
]);
return $response;
}
监控告警(进阶)
当响应时间超过阈值时触发告警:
public function handle($request, Closure $next)
{
$startTime = microtime(true);
$response = $next($request);
$duration = (microtime(true) - $startTime) * 1000;
if ($duration > 5000) { // 5秒以上
// 发送告警
$this->sendAlert($request, $duration);
// 记录到专门的慢查询日志
Log::critical('ABNORMAL_LATENCY', [
'duration_ms' => $duration,
'url' => $request->fullUrl(),
'session_id' => session()->getId(),
]);
}
return $response;
}
private function sendAlert($request, $duration)
{
// 发送邮件、Slack、钉钉等通知
// 例如使用 Laravel 的通知系统
}
配合监控工具
Laravel Telescope(推荐)
composer require laravel/telescope
自动记录所有请求的详细信息。
Pulse(Laravel 11+)
php artisan install:pulse
内置响应时间监控仪表板。
最佳实践建议
- 按环境区分:开发环境使用 Debugbar,生产环境使用中间件
- 分级记录:正常请求记录 info,慢请求记录 warning 或 critical
- 关注 95/99 分位值:比平均值更有参考价值
- 关联上下文:记录用户ID、版本号等便于定位问题
- 定期清理:数据库记录要定期归档或删除
选择哪种方式取决于你的具体需求,个人推荐中间件 + Telescope的组合,既能精细控制,又有可视化界面。