brezgalov/yii2-external-api-logger

API请求的日志记录器

dev-master 2022-10-31 09:30 UTC

This package is auto-updated.

Last update: 2024-09-07 13:16:32 UTC


README

此组件可以帮助您记录外部API交互

安装

composer require brezgalov/yii2-external-api-logger

使用

在配置文件中将记录器指定为应用程序组件

[
    bootstrap' => [
        'logger',
    ],
    'components' => [
        'logger' => [
            'class' => LoggerComponent::class,
            'logsStorage' => LogsStorageDb::class,
        ],
    ],
],

LogsStorageDb 类需要从 src/LogsStorageDb/Migrations 应用迁移

我更喜欢使用 yiisoft/yii2-httpclient 作为客户端,并使用 brezgalov/activity-id 作为 ActivityId 助手

您可以使用任何您想要的客户端。但是,ActivityId 是必填的构造函数参数。它作为数据库日志存储的主键。

您可以使用 uniqid() 代替 activity-id 库,或者您喜欢的任何唯一标识符。

// create activityId to bind logs all the way through
$activityId = \Yii::createObject(ActivityId::class, ['name' => Auth::ACTIVITY_ID_LOGIN]) ;

// bind request data
$eventRequestSent = \Yii::createObject(EventExternalApiRequestSent::class, ['activityId' => (string)$activityId,]);

$eventRequestSent->method = $request->getMethod();
$eventRequestSent->url = $request->getFullUrl();
$eventRequestSent->input = $request->getData();
$eventRequestSent->requestGroup = Auth::REQUEST_GROUP;
$eventRequestSent->requestId = Auth::REQUEST_ID_LOGIN;

// trigger event before sending request

\Yii::$app->trigger(LoggerComponent::EVENT_EXTERNAL_API_REQUEST_SENT, $eventRequestSent);

// send request

$response = $request->send();

// bind response params

$eventResponseReceived = \Yii::createObject(EventExternalApiResponseReceived::class, ['activityId' => (string)$activityId]);
$eventResponseReceived->statusCode = $response->statusCode;
$eventResponseReceived->response = $response->getContent();

// trigger event after response is received

\Yii::$app->trigger(LoggerComponent::EVENT_EXTERNAL_API_RESPONSE_RECEIVED, $eventResponseReceived);

// some usefull example code further

if ($response->isOk) {
    ...
}

SQL事务内的使用

当您在事务中记录API请求时,任何错误都可能破坏您的日志信息。 LogApiRequestDelayedBehavior 是避免此类问题的选项。

将您的组件配置替换为

[
    bootstrap' => [
        'logger',
    ],
    'components' => [
        'logger' => [
            'class' => DelayedLoggerComponent::class,
            'logsStorage' => LogsStorageDb::class,
            'fireStorageEvent' => \yii\base\Application::EVENT_AFTER_ACTION,
        ],
    ],
],

然后,将之前的日志事件触发代码替换为

    // create activityId to bind logs all the way through
    $activityId = (string)\Yii::createObject(ActivityId::class, ['name' => Auth::ACTIVITY_ID_SEND_SMS_CODE]);

    $request = // build \yii\httpclient\Request;

    // fill up request fields
    $requestLogDto = \Yii::createObject(ApiLogFullDto::class);
    $requestLogDto->activityId = $activityId;
    $requestLogDto->requestTime = time();
    $requestLogDto->method = $request->getMethod();
    $requestLogDto->url = $request->getFullUrl();
    $requestLogDto->input = $request->getData();
    $requestLogDto->requestGroup = Auth::REQUEST_GROUP;
    $requestLogDto->requestId = Auth::REQUEST_ID_SEND_SMS;

    $response = $request->send();

    // fill up response fields
    $requestLogDto->responseTime = time();
    $requestLogDto->statusCode = $response->statusCode;
    $requestLogDto->responseContent = $response->getContent();

    // delay event

    /** @var DelayedLoggerComponent $loggerComponent */
    $loggerComponent = \Yii::$app->get('logger');
    $loggerComponent->delayLogDto($requestLogDto);

然后在事务块外部触发配置的 "fireStorageEvent" 事件。我建议使用 EVENT_AFTER_ACTION 事件。