assimtech/dislog

API调用日志记录器

3.0.1 2023-02-10 01:32 UTC

This package is auto-updated.

Last update: 2024-09-10 04:48:08 UTC


README

Latest Stable Version Total Downloads Latest Unstable Version License

Dislog 是一个 API 调用日志记录器。API 调用与普通日志事件不同,因为它们由请求和响应组成,这些请求和响应在不同时间发生,但应一起记录,因为它们是相关的。

框架集成

Symfony - DislogBundle

用法

LoggingHttpClientInterface

如果要从 Psr\Http\Client\ClientInterface 记录 HTTP 请求,则提供了一个兼容 PSR-18 的 LoggingHttpClient

注意:如果您使用 Assimtech\Dislog\LoggingHttpClient,您必须在项目中安装以下依赖项

  • guzzlehttp/psr7 这仅用于将 Psr\Http\Message{RequestInterface,ResponseInterface} 转换为字符串
  • psr/http-client
  • psr/http-message
/**
 * @var Psr\Http\Client\ClientInterface $httpClient
 * @var Assimtech\Dislog\ApiCallLoggerInterface $apiCallLogger
 */
$loggingHttpClient = new Assimtech\Dislog\LoggingHttpClient(
    $httpClient,
    $apiCallLogger
);

/**
 * @var Psr\Http\Message\ResponseInterface $response
 */
$response = $loggingHttpClient->sendRequest(
    /* Psr\Http\Message\RequestInterface */ $request,
    /* ?string */ $appMethod = null, // The method in the application that triggered this API call, setting to null will disable API logging
    /* ?string */ $reference = null, // The reference for this specific call (e.g. id or key if available), helps with searching API logs
    /* callable[]|callable|null */ $requestProcessors = null, // Processors to apply to $request, see Processors section below
    /* callable[]|callable|null */ $responseProcessors = null, // Processors to apply to $response, see Processors section below
    /* bool */ $omitPayload = false, // If set to true, request/response will not be logged however metadata will, useful for monitoring without logging full request or response
);

省略负载

如果您只想在某些响应上记录元数据(除了原始请求/响应之外的所有内容),则可以使用 $omitPayload。如果您在调用 API 后决定确实想要记录原始请求/响应,则可以强制记录负载。

$response = $loggingHttpClient->sendRequest(
    $request,
    $appMethod,
    $reference,
    $requestProcessors,
    $responseProcessors,
    true, // $omitPayload - Do not log raw request / response but still log all other metadata, this allows us to still monitor api calls
);
if (200 !== $response->getStatusCode()) {
    $loggingHttpClient->logLastPayload();
}

ApiCallLogger

ApiCallLogger 可以用于记录客户端和服务器端 API 的请求和响应。请求和响应负载都是可选的。如果您正在记录 FTP 文件上传,则在成功上传后可能没有响应。您仍然可以调用 logResponse 来指示服务器已接受文件。

/**
 * @var Assimtech\Dislog\ApiCallLoggerInterface $apiCallLogger
 * @var Assimtech\Dislog\Model\ApiCallInterface $apiCall
 */
$apiCall = $apiCallLogger->logRequest(
    /* ?string */ $request,
    /* ?string */ $endpoint,
    /* ?string */ $appMethod,
    /* ?string */ $reference,
    /* callable[]|callable|null */ $processors
);

$response = $api->transmit($request);

$this->apiCallLogger->logResponse($apiCall, $response);

以下是一个在假 API 中使用 dislog 的示例

use Assimtech\Dislog;

class Api
{
    protected $apiLogger;

    public function __construct(Dislog\ApiCallLoggerInterface $apiCallLogger)
    {
        $this->apiCallLogger = $apiCallLogger;
    }

    public function transmit($request)
    {
        return '<some response />';
    }

    public function doSomething()
    {
        $request = '<some request />';
        $endpoint = 'http://my.endpoint';
        $reference = time();

        $apiCall = $this->apiCallLogger->logRequest(
            $request,
            $endpoint,
            __METHOD__,
            $reference
        );

        $response = $this->transmit($request);

        $this->apiCallLogger->logResponse(
            $apiCall,
            $response
        );
    }
}

$stream = fopen('/tmp/my.log', 'a');
$uniqueIdentity = new Dislog\Identity\UniqueIdGenerator();
$stringSerializer = new Dislog\Serializer\StringSerializer();
$streamHandler = new Dislog\Handler\Stream($stream, $uniqueIdentity, $stringSerializer);
$apiCallFactory = new Dislog\Factory\ApiCallFactory();
$apiCallLogger = new Dislog\ApiCallLogger($apiCallFactory, $streamHandler);

$api = new Api($apiCallLogger);
$api->doSomething();

可以通过调用支持的处理程序上的 remove 来清理旧日志

$handler->remove(60 * 60 * 24 * 30); // keep 30 days worth of logs

处理程序

Stream

此处理程序接受一个可写流资源。您还必须提供身份生成器和序列化器。

use Assimtech\Dislog;

$stream = fopen('/tmp/my.log', 'a');
$uniqueIdentity = new Dislog\Identity\UniqueIdGenerator();
$stringSerializer = new Dislog\Serializer\StringSerializer();

$streamHandler = new Dislog\Handler\Stream($stream, $uniqueIdentity, $stringSerializer);

DoctrineDocumentManager

此处理程序接受一个 Doctrine\ODM\MongoDB\DocumentManager

注意:您必须在文档管理器中设置任何映射到 Assimtech\Dislog\Model\ApiCallInterface 的映射 警告:建议不要使用应用程序的默认文档管理器作为 flush(),因为 dislog 的 flush() 可能会干扰您的应用程序

$documentHandler = new Dislog\Handler\DoctrineDocumentManager($documentManager);

DoctrineEntityManager

此处理程序接受一个 Doctrine\ORM\EntityManagerInterface

注意:您必须在实体管理器中设置任何映射到 Assimtech\Dislog\Model\ApiCallInterface 的映射 警告:建议不要使用应用程序的默认实体管理器作为 flush(),因为 dislog 的 flush() 可能会干扰您的应用程序

$entityHandler = new Dislog\Handler\DoctrineEntityManager($entityManager);

处理器

处理器是一个可调用的函数,它在请求或响应负载上执行。它们可以在处理 ApiCall 之前修改请求或响应。一个例子可能是屏蔽信用卡号或混淆密码。

处理器与 logRequest 和/或 logResponse 调用一起传递以处理适当的负载。

注意:在 null 请求/响应 上不会调用处理器。

function getMaskedCard($card)
{
    $firstSix = substr($card, 0, 6);
    $lastFour = substr($card, -4);
    $middle = str_repeat('*', strlen($card) - 10);
    return $firstSix . $middle . $lastFour;
}

$endpoint = 'https://my.endpoint';
$appMethod = 'processPayment';
$reference = time();
$card = '4444333322221111';
$cvv = '123';
$request = json_encode([
    'amount' => 12.95,
    'card' => $card,
    'expiry' => '2021-04',
    'cvv' => $cvv,
]);

$maskCard = function ($request) use ($card) {
    $maskedCard = getMaskedCard($card);
    return str_replace($card, $maskedCard, $request);
};
$obfuscateCvv = function ($request) use ($cvv) {
    return str_replace($cvv, '***', $request);
};
$apiCallLogger->logRequest(
    $request,
    $endpoint,
    $appMethod,
    $reference,
    [
        $maskCard,
        $obfuscateCvv,
    )
);

StringReplace

此处理器基于 php 的 str_replace。它将在请求/响应中替换已知的字符串。

$maskedCard = getMaskedCard($card);
$obfuscatedCvv = '***';
$stringReplace = new Assimtech\Dislog\Processor\StringReplace([
    $card,
    $cvv,
], [
    $maskedCard,
    $obfuscatedCvv,
]);
$apiCallLogger->logRequest(
    $request,
    $endpoint,
    $appMethod,
    $reference,
    $stringReplace
);

RegexReplace

此处理器基于 php 的 preg_replace。它将在请求/响应中替换正则表达式。

$response = '{social_security_number: "1234567890"}';
$regexReplace = new Assimtech\Dislog\Processor\RegexReplace(
    '/social_security_number: "(\d\d)\d+(\d\d)"/',
    'social_security_number: "$1***$2"'
);
$apiCallLogger->logResponse(
    $apiCall,
    $response,
    $regexReplace
);

序列化器

序列化器是一个可调用的函数,它将 ApiCall 转换为处理程序可以处理的某种东西。并非所有处理程序都需要与序列化器配对,并且可以处理原始 ApiCall(例如,DoctrineObjectManager)。