API Log Checker: How To Check Magento 2 Web API Log Details

This Wishusucess web API log checker module is basically developed for checking all the incoming requests on the Magento 2 store from different websites.

So you can use this web API module to check the error log in your Magento 2 store.

If you are not sure how a request is coming on your site and you want to check the log details with all the filled data with the send method of the API request then you can use this module.

Also if you are not sure how the data is coming or in which formate API request is coming so you can check the error log in var/webapi_rest/ folder for the API error log.

API Log Checker in Magento 2

 

Magento 2 API Log Checker Extension

So, in order to create this module, you have to create a plugin first then we can use that method in the logger handler class.

So here we have created some files, you have to follow this structure to create success in your app code directory.

app/code/Wishusucess/WebApiLog/registration.php

app/code/Wishusucess/WebApiLog/etc/module.xml

app/code/Wishusucess/WebApiLog/webapi_rest/di.xml

app/code/Wishusucess/WebApiLog/Plugin/Rest/Api.php

app/code/Wishusucess/WebApiLog/Logger/Handler.php

app/code/Wishusucess/WebApiLog/Logger/Handler/Debug.php

 

Step 1: Registration

app/code/Wishusucess/WebApiLog/registration.php

<?php
/**
* Developer: Hemant Singh Magento 2x Developer
* Category: Wishusucess_WebApiLog 
* Website: http://www.wishusucess.com/
*/
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Wishusucess_WebApiLog',
__DIR__
);

 

Step 2: Web API Module Information

This file is all about the web API module basic information like the version of the web API logger module and that module name.

app/code/Wishusucess/WebApiLog/etc/module.xml

<?xml version="1.0"?>
<!--
/**
* Developer: Hemant Singh Magento 2x Developer
* Category: Wishusucess_WebApiLog
* Website: http://www.wishusucess.com/
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Wishusucess_WebApiLog" setup_version="0.0.1" />
</config>

 

Step 3: API Log Checker Dependency Injection

Here, we have defined the preferences of the plugin which we are going to create in the Plugin folder.

So the plugin type of Magento\Webapi\Controller\Rest we have defined here and logger argument Wishusucess\WebApiLog\Logger\Handler also we have given here.

app/code/Wishusucess/WebApiLog/webapi_rest/di.xml

<?xml version="1.0"?>
<!--
/**
* Developer: Hemant Singh Magento 2x Developer
* Category: Wishusucess_WebApiLog
* Website: http://www.wishusucess.com/
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Webapi\Controller\Rest">
<plugin name="Wishusucess\WebApiLog" type="Wishusucess\WebApiLog\Plugin\Rest\Api" />
</type>
<type name="Magento\Framework\Webapi\Rest\Response">
<plugin name="Wishusucess\WebApiLog" type="Wishusucess\WebApiLog\Plugin\Rest\Api" />
</type>
<type name="Wishusucess\WebApiLog\Logger\Handler">
<arguments>
<argument name="name" xsi:type="string">webapi_logger</argument>
<argument name="handlers" xsi:type="array">
<item name="debug" xsi:type="object">Wishusucess\WebApiLog\Logger\Handler\Debug</item>
</argument>
</arguments>
</type>
</config>

 

Step 4: Plugin of API Log Checker

Here, we will check how the request is functioning and proceeding for the next.

So in order to change the behavior of Magento 2 rest API core class file, we have added some method which is aroundDispatch() and afterSendResponse() that two methods are going to change the existing behavior and will recreate new behavior of the class file.

Another method is the isAuthorizationRequest() function that will check whether the incoming request is authorized or not and that incoming request should be admin token authorized then only that will create the log details.

app/code/Wishusucess/WebApiLog/Plugin/Rest/Api.php

<?php
/**
* Developer: Hemant Singh Magento 2x Developer
* Category: Wishusucess_WebApiLog Get Product Image URL Using REST API
* Website: http://www.wishusucess.com/
*/
namespace Wishusucess\WebApiLog\Plugin\Rest;

class Api
{
/** @var \Wishusucess\WebApiLog\Logger\Handler */
protected $logger;

/** @var array */
protected $currentRequest;

/**
* Rest constructor.
* @param \Wishusucess\WebApiLog\Logger\Handler $logger
*/
public function __construct(\Wishusucess\WebApiLog\Logger\Handler $logger)
{
$this->logger = $logger;
}

/**
* @param \Magento\Webapi\Controller\Rest $subject
* @param callable $proceed
* @param \Magento\Framework\App\RequestInterface $request
* @return mixed
*/
public function aroundDispatch(
\Magento\Webapi\Controller\Rest $subject,
callable $proceed,
\Magento\Framework\App\RequestInterface $request
) {
try {
$this->currentRequest = [
'is_api' => true,
'is_auth' => $this->isAuthorizationRequest($request->getPathInfo()),
'request' => [
'method' => $request->getMethod(),
'uri' => $request->getRequestUri(),
'version' => $request->getVersion(),
'headers' => [],
'body' => '',
],
'response' => [
'headers' => [],
'body' => '',
],
];
foreach ($request->getHeaders()->toArray() as $key => $value) {
$this->currentRequest['request']['headers'][$key] = $value;
}
$this->currentRequest['request']['body'] = $this->currentRequest['is_auth'] ?
'Request body is not available for authorization requests.' :
$request->getContent();
} catch (\Exception $exception) {
$this->logger->debug(sprintf(
'Exception when logging API request: %s (%s::%s)',
$exception->getMessage(),
$exception->getFile(),
$exception->getLine()
));
}

return $proceed($request);
}


public function afterSendResponse(
\Magento\Framework\Webapi\Rest\Response $subject,
$result
) {
try {
foreach ($subject->getHeaders()->toArray() as $key => $value) {
$this->currentRequest['response']['headers'][$key] = $value;
}
$this->currentRequest['response']['body'] = $this->currentRequest['is_auth'] ?
'Response body is not available for authorization requests.' :
$subject->getBody();
$this->logger->debug('', $this->currentRequest);
} catch (\Exception $exception) {
$this->logger->debug('Exception when logging API response: ' . $exception->getMessage());
}

return $result;
}

/**
* @param string $path
* @return bool
*/
protected function isAuthorizationRequest(string $path) : bool
{
return preg_match('/integration\/(admin|customer)\/token/', $path) !== 0;
}
}

 

Step 5: WebApiLog Handler

app/code/Wishusucess/WebApiLog/Logger/Handler.php

<?php
/**
* Developer: Hemant Singh Magento 2x Developer
* Category: Wishusucess_WebApiLog Get Product Image URL Using REST API
* Website: http://www.wishusucess.com/
*/
namespace Wishusucess\WebApiLog\Logger;

class Handler extends \Monolog\Logger
{
}

 

Step 6: Web API Log Checker Debug

Now, this is the last step to get completed of this module so here we have to define how that log should be written in the file and where that log file should be created.

So for that two functionality, we will use two methods which are written (array $record) and another method is createDir($url).

app/code/Wishusucess/WebApiLog/Logger/Handler/Debug.php

<?php
/**
* Developer: Hemant Singh Magento 2x Developer
* Category: Wishusucess_WebApiLog Get Product Image URL Using REST API
* Website: http://www.wishusucess.com/
*/
namespace Wishusucess\WebApiLog\Logger\Handler;

class Debug extends \Magento\Framework\Logger\Handler\Debug
{
/** @var string */
private $errorMessage;

/** @var boolean */
private $dirCreated;

/**
* @param array $record
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function write(array $record)
{
if (!isset($record['context']['is_api']) || !$record['context']['is_api']) {
parent::write($record);
return;
}
$result = preg_match('/\/V1\/([^?]*)/', $record['context']['request']['uri'], $matches);
$url = sprintf(
'%s/var/log/webapi_%s/%s/%s.log',
BP,
'rest',
$result && count($matches) && $matches[1] ? trim($matches[1], '/') : 'default',
$record['datetime']->format('Ymd_His')
);

$logDir = $this->filesystem->getParentDirectory($url);
if (!$this->filesystem->isDirectory($logDir)) {
$this->filesystem->createDirectory($logDir);
}

$stream = null;

if (!is_resource($stream)) {
if (!$url) {
throw new \LogicException('Missing stream url, the stream can not be opened.');
}
$this->createDir($url);
$this->errorMessage = null;
set_error_handler(array($this, 'customErrorHandler'));
$stream = fopen($url, 'a');
if ($this->filePermission !== null) {
@chmod($url, $this->filePermission);
}
restore_error_handler();
if (!is_resource($stream)) {
$stream = null;
throw new \Magento\Framework\Exception\LocalizedException(
__('The stream or file "%1" could not be opened: %2', $url, $this->errorMessage)
);
}
}

if ($this->useLocking) {
flock($stream, LOCK_EX);
}

$request = $record['context']['request'];
$data = '';
$data .= sprintf("%s %s HTTP %s\n\n", $request['method'], $request['uri'], $request['version']);
foreach ($record['context']['request']['headers'] as $key => $value) {
$data .= sprintf("%s: %s\n", $key, $value);
}
$data .= sprintf("\n%s\n\n", $request['body']);
foreach ($record['context']['response']['headers'] as $key => $value) {
$data .= sprintf("%s: %s\n", $key, $value);
}
$data .= sprintf("\n%s\n", $record['context']['response']['body']);

fwrite($stream, $data);

if ($this->useLocking) {
flock($stream, LOCK_UN);
}

if (is_resource($stream)) {
fclose($stream);
}
$stream = null;
}

/**
* @param $code
* @param $msg
*/
private function customErrorHandler($code, $msg)
{
$this->errorMessage = preg_replace('{^(fopen|mkdir)\(.*?\): }', '', $msg);
}

/**
* @param string $stream
*
* @return null|string
*/
private function getDirFromStream($stream)
{
$pos = strpos($stream, '://');
if ($pos === false) {
return dirname($stream);
}

if ('file://' === substr($stream, 0, 7)) {
return dirname(substr($stream, 7));
}

return;
}

/**
* @param $url
* @throws \Magento\Framework\Exception\LocalizedException
*/
private function createDir($url)
{
if ($this->dirCreated) {
return;
}

$dir = $this->getDirFromStream($url);
if (null !== $dir && !is_dir($dir)) {
$this->errorMessage = null;
set_error_handler(array($this, 'customErrorHandler'));
$status = mkdir($dir, 0777, true);
restore_error_handler();
if (false === $status) {
throw new \Magento\Framework\Exception\LocalizedException(
__('There is no existing directory at "%1" and its not buildable: %2', $dir, $this->errorMessage)
);
}
}
$this->dirCreated = true;
}
}

 

Recommended Post:

Featured Product API: Get Featured Product Using Magento 2 REST API

How To Call Magento 2 REST API For Customer Account Update

 

GitHub Download Link

Leave a Reply