assimtech / dislog
API调用日志记录器
Requires
- php: ^7.2.5|^8
- symfony/options-resolver: ^3|^4|^5|^6
Requires (Dev)
- doctrine/common: ^2|^3
- doctrine/orm: ^2
- guzzlehttp/psr7: ^1.7|^2
- phing/phing: *
- phpspec/phpspec: *
- psr/http-client: ^1
- psr/http-message: ^1
- psr/log: ^1
- sebastian/phpcpd: *
- squizlabs/php_codesniffer: *
Suggests
- guzzlehttp/psr7: Required if using LoggingHttpClient
- psr/http-client: Required if using LoggingHttpClient
- psr/http-message: Required if using LoggingHttpClient
README
Dislog 是一个 API 调用日志记录器。API 调用与普通日志事件不同,因为它们由请求和响应组成,这些请求和响应在不同时间发生,但应一起记录,因为它们是相关的。
框架集成
用法
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
)。