PHP三大主流框架 如何優(yōu)雅的實(shí)現(xiàn)日志功能
在一些管理系統(tǒng)中,經(jīng)常會(huì)要求記錄客戶端的請(qǐng)求和響應(yīng)日志,方便系統(tǒng)出現(xiàn)問題及時(shí)的排查,以及業(yè)務(wù)的核查。今天就用Laravel框架、Webman框架和ThinkPHP框架來實(shí)現(xiàn)這樣的功能。
Laravel實(shí)現(xiàn)
可以創(chuàng)建一個(gè)自定義的服務(wù)提供者來記錄請(qǐng)求和響應(yīng)日志。下面是使用服務(wù)器提供者記錄請(qǐng)求日志和響應(yīng)日志的一般步驟:
- 創(chuàng)建一個(gè)服務(wù)提供者類
可以使用 Artisan 命令 php artisan make:provider 來創(chuàng)建服務(wù)提供者類。在服務(wù)提供者類中,需要實(shí)現(xiàn) register 和 boot 方法,其中 register 方法用于將服務(wù)注冊(cè)到服務(wù)容器中,boot 方法用于服務(wù)啟動(dòng)時(shí)執(zhí)行的代碼。
namespace?App\Providers;
use?Illuminate\Support\ServiceProvider;
use?Illuminate\Support\Facades\Log;
class?LoggingServiceProvider?extends?ServiceProvider
{
????public?function?register()
????{
????????//
????}
????public?function?boot()
????{
????????$this->app['router']->matched(function?($route)?{
????????????$logMessage?=?'Request:?'?.?$route->getName()?.?'?'?.?$route->uri()?.?'?';
????????????$logMessage?.=?'Parameters:?'?.?json_encode($route->parameters())?.?'?';
????????????Log::info($logMessage);
????????});
????????$this->app->make('Illuminate\Contracts\Http\Kernel')->pushMiddleware(LoggingMiddleware::class);
????}
}
- 實(shí)現(xiàn)中間件類
在服務(wù)提供者中,可以使用 pushMiddleware 方法將中間件類添加到應(yīng)用程序中。在本例中,我們將創(chuàng)建一個(gè)名為 LoggingMiddleware 的中間件類。該中間件類用于記錄響應(yīng)日志。
namespace?App\Http\Middleware;
use?Closure;
use?Illuminate\Support\Facades\Log;
class?LoggingMiddleware
{
????public?function?handle($request,?Closure?$next)
????{
????????$response?=?$next($request);
????????Log::info('Response:?'?.?$response->status()?.?'?'?.?$response->content());
????????return?$response;
????}
}
- 注冊(cè)服務(wù)提供者
最后,在 config/app.php 文件中注冊(cè)服務(wù)提供者:
'providers'?=>?[
????//?...
????App\Providers\LoggingServiceProvider::class,
],
現(xiàn)在,當(dāng)有請(qǐng)求時(shí),會(huì)將請(qǐng)求信息記錄到日志中,當(dāng)響應(yīng)時(shí),會(huì)將響應(yīng)信息記錄到日志中。你可以在日志文件中查看記錄的請(qǐng)求和響應(yīng)信息。
需要注意的是,如果你想在生產(chǎn)環(huán)境中使用這個(gè)服務(wù)提供者記錄日志,你需要確保對(duì)日志文件進(jìn)行適當(dāng)?shù)谋Wo(hù),以防止敏感信息泄露。
Webman實(shí)現(xiàn)
在 Webman 中,可以通過創(chuàng)建一個(gè)中間件來實(shí)現(xiàn)請(qǐng)求和響應(yīng)的記錄。下面是一般的實(shí)現(xiàn)步驟:
- 創(chuàng)建一個(gè)中間件類
在 Webman 中,可以通過創(chuàng)建中間件類來實(shí)現(xiàn)請(qǐng)求和響應(yīng)的記錄。下面是一個(gè)示例中間件類:
namespace?App\Middleware;
use?Webman\MiddlewareInterface;
use?Webman\Http\Response;
use?Psr\Http\Message\ServerRequestInterface;
use?Psr\Http\Message\ResponseInterface;
use?Swoole\Coroutine;
class?LoggingMiddleware?implements?MiddlewareInterface
{
????public?function?process(ServerRequestInterface?$request,?callable?$next):?ResponseInterface
????{
????????$start?=?microtime(true);
????????$response?=?$next($request);
????????$end?=?microtime(true);
????????$logMessage?=?'Request:?'?.?$request->getMethod()?.?'?'?.?$request->getUri()->getPath()?.?'?';
????????$logMessage?.=?'Parameters:?'?.?json_encode($request->getQueryParams())?.?'?';
????????$logMessage?.=?'Time:?'?.?round($end?-?$start,?6)?.?'s';
????????Coroutine::create(function?()?use?($logMessage)?{
????????????app('log')->info($logMessage);
????????});
????????Coroutine::create(function?()?use?($response)?{
????????????app('log')->info('Response:?'?.?$response->getStatusCode()?.?'?'?.?$response->getBody());
????????});
????????return?$response;
????}
}
- 注冊(cè)中間件類
在 Webman 的 config/app.php 文件中,可以使用 middleware 配置項(xiàng)注冊(cè)中間件類。例如:
'middleware'?=>?[
????//?...
????\App\Middleware\LoggingMiddleware::class,
],
- 使用中間件
將中間件類添加到 Webman 的路由定義中,例如:
use?Webman\Route;
Route::get('/',?function?()?{
????return?'Hello,?Webman!';
})->middleware([\App\Middleware\LoggingMiddleware::class]);
現(xiàn)在,當(dāng) Webman 應(yīng)用程序收到請(qǐng)求時(shí),將記錄請(qǐng)求信息和響應(yīng)信息到日志中。你可以在日志文件中查看這些信息。
需要注意的是,如果你想在生產(chǎn)環(huán)境中使用這個(gè)中間件記錄日志,你需要確保對(duì)日志文件進(jìn)行適當(dāng)?shù)谋Wo(hù),以防止敏感信息泄露。
ThinkPHP實(shí)現(xiàn)
在 ThinkPHP6 中,可以通過創(chuàng)建中間件來實(shí)現(xiàn)請(qǐng)求和響應(yīng)的記錄。下面是一般的實(shí)現(xiàn)步驟:
- 創(chuàng)建一個(gè)中間件類
在 ThinkPHP6 中,可以通過創(chuàng)建中間件類來實(shí)現(xiàn)請(qǐng)求和響應(yīng)的記錄。下面是一個(gè)示例中間件類:
namespace?app\middleware;
use?Closure;
class?LoggingMiddleware
{
????public?function?handle($request,?Closure?$next)
????{
????????$start?=?microtime(true);
????????$response?=?$next($request);
????????$end?=?microtime(true);
????????$logMessage?=?'Request:?'?.?$request->method()?.?'?'?.?$request->url()?.?'?';
????????$logMessage?.=?'Parameters:?'?.?json_encode($request->param())?.?'?';
????????$logMessage?.=?'Time:?'?.?round($end?-?$start,?6)?.?'s';
????????app('log')->info($logMessage);
????????$logMessage?=?'Response:?'?.?$response->getStatusCode()?.?'?'?.?$response->getContent();
????????app('log')->info($logMessage);
????????return?$response;
????}
}
- 注冊(cè)中間件類
在 ThinkPHP6 的 app/middleware.php 文件中,可以使用 alias 方法注冊(cè)中間件類。例如:
return?[
????//?...
????'logging'?=>?\app\middleware\LoggingMiddleware::class,
];
- 使用中間件
在需要記錄請(qǐng)求和響應(yīng)的路由定義中,使用 middleware 方法引入中間件。例如:
use?think\facade\Route;
Route::get('/',?function?()?{
????return?'Hello,?ThinkPHP6!';
})->middleware('logging');
現(xiàn)在,當(dāng) ThinkPHP6 應(yīng)用程序收到請(qǐng)求時(shí),將記錄請(qǐng)求信息和響應(yīng)信息到日志中。你可以在日志文件中查看這些信息。
需要注意的是,如果你想在生產(chǎn)環(huán)境中使用這個(gè)中間件記錄日志,你需要確保對(duì)日志文件進(jìn)行適當(dāng)?shù)谋Wo(hù),以防止敏感信息泄露。
