You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel中无需逐函数编码实现Controller所有方法自动打info日志

实现控制器方法自动日志记录的方案(基于Laravel框架)

针对你提到的场景,推荐两种常用的无侵入实现方案,不需要修改每个控制器的业务方法:

方案1:重写控制器基类callAction方法(适配所有继承基类的控制器)

Laravel框架所有控制器方法执行时都会调用基类的callAction方法,直接重写该方法即可全局植入日志逻辑:

  1. 打开项目基类控制器文件app/Http/Controllers/Controller.php,添加如下代码:
<?php

namespace App\Http\Controllers;

use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Support\Facades\Log;

class Controller extends BaseController
{
    use AuthorizesRequests, ValidatesRequests;

    // 重写callAction方法植入日志逻辑
    public function callAction($method, $parameters)
    {
        // 仅开发环境记录日志,生产环境可关闭
        if (!app()->environment('local')) {
            return parent::callAction($method, $parameters);
        }

        $actionTag = static::class . '@' . $method;
        // 记录方法启动和入参,可自行过滤password、token等敏感字段
        Log::info("Start {$actionTag}", $this->filterSensitiveParams($parameters));
        
        // 执行原业务逻辑
        $result = parent::callAction($method, $parameters);
        
        // 记录方法结束和返回结果,二进制/文件响应可跳过记录内容
        Log::info("End {$actionTag}", [
            'result' => is_string($result) || is_array($result) || is_object($result) ? $result : 'unrecorded type'
        ]);
        
        return $result;
    }

    // 敏感参数过滤,可自定义需要过滤的字段
    private function filterSensitiveParams(array $params): array
    {
        $sensitiveKeys = ['password', 'password_confirmation', 'api_token', 'access_token'];
        foreach ($params as $key => $value) {
            if (in_array($key, $sensitiveKeys)) {
                $params[$key] = '***';
            }
        }
        return $params;
    }
}

该方案的优势是零额外配置,所有继承该基类的控制器方法都会自动记录日志,不需要修改路由或者业务代码。

方案2:使用路由中间件(适配指定路由组)

如果你只需要给部分路由对应的控制器记录日志,可以用中间件实现:

  1. 生成中间件文件:
php artisan make:middleware LogControllerAction
  1. 编辑中间件文件app/Http/Middleware/LogControllerAction.php:
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Log;

class LogControllerAction
{
    public function handle($request, Closure $next)
    {
        if (!app()->environment('local')) {
            return $next($request);
        }

        $action = $request->route()->getAction();
        $actionTag = $action['controller'] ?? 'UnknownController@unknownMethod';

        // 记录请求入参
        Log::info("Start {$actionTag}", $this->filterSensitiveParams($request->all()));

        $response = $next($request);

        // 记录返回结果
        Log::info("End {$actionTag}", [
            'result' => $response->original ?? $response->getContent()
        ]);

        return $response;
    }

    private function filterSensitiveParams(array $params): array
    {
        $sensitiveKeys = ['password', 'password_confirmation', 'api_token', 'access_token'];
        foreach ($params as $key => $value) {
            if (in_array($key, $sensitiveKeys)) {
                $params[$key] = '***';
            }
        }
        return $params;
    }
}
  1. 注册中间件,打开app/Http/Kernel.php,将中间件添加到需要的路由组中:
protected $middlewareGroups = [
    'web' => [
        // 其他中间件
        \App\Http\Middleware\LogControllerAction::class,
    ],
    'api' => [
        // 其他中间件
        \App\Http\Middleware\LogControllerAction::class,
    ],
];

也可以单独给指定路由绑定中间件,灵活控制日志覆盖范围。

注意事项

  • 如果返回结果是文件、二进制流等大体积内容,建议跳过结果记录,避免日志文件过大
  • 生产环境建议关闭该类调试日志,或者将日志级别调整为debug,避免占用过多存储
  • 敏感字段一定要做过滤,避免密码、密钥等信息泄露到日志中

内容的提问来源于stack exchange,提问作者Thinh Nguyen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 04:39:00