4

I am trying to create a Request and Response Logger for a web service created in Yii 2.0.5 for debugging purpose.

Basically my motive is to track all the request, request data, response data and for this purpose I am using Yii Events. So far I have coded something like this:

UserController

use yii\rest\ActiveController;
use yii\base\Event;
use yii\web\Response;

Event::on(ActiveController::className(), ActiveController::EVENT_AFTER_ACTION, ['app\models\LogHandler', 'saveRequest'], ['request' => Yii::$app->request->getRawBody(), 'response' => Yii::$app->response->content]);

class UserController extends ActiveController
{

    public $modelClass = 'app\models\User';

    public function behaviors()
    {
        $behaviors = parent::behaviors();

        $behaviors['contentNegotiator']['formats']['text/html'] = Response::FORMAT_XML;

        return $behaviors;
    }

    // POST demo
    public function actionDemo()
    {
        $data = array('status' => 200, 'message' => 'Success');
        return $data;
    }

}

In the above code if you have noticed then I have used the Class level Event handler (doc). Here I am trying to capture the Controllers EVENT_AFTER_ACTION event and passing the Request & Response object to my LogHandler's static method. However in my handler I am able to get the request's raw body but I am not able to get the response data which the actionDemo() is returning.

LogHandler

namespace app\models;

use yii\db\ActiveRecord;

class LogHandler extends ActiveRecord
{
    public static function tableName()
    {
        return 'request_log';
    }

    public static function saveRequest($event)
    {
//        self::load($event);
//        self::save();
        var_dump($event);
    }

}

How do I get the response data as well...

Sagar Guhe
  • 1,041
  • 1
  • 11
  • 35
  • Hi... I'm basically talking for my own shop, but have you looked at [yii2-audit](https://github.com/bedezign/yii2-audit)? It's free, based on the debug component and very thourough – Blizz Aug 13 '15 at 20:11
  • @Blizz thanks for introducing me to the yii2-audit, I would need to check and test this extension, at this moment I am not sure whether this tool help me achieve my task or not.. I will get back after testing.. – Sagar Guhe Aug 14 '15 at 07:05
  • Hope it serves your needs. If you want to see it in action without having to install it, use [the demo site](http://yii2-audit.herokuapp.com). – Blizz Aug 14 '15 at 07:27
  • I just checked the demo site It looks the same as yii-debugger but this have represented the data in more understandable way but this also doesn't log the response content given to the requester :( – Sagar Guhe Aug 14 '15 at 07:46
  • That could be easily added by adding your own panel. I guess if this doesn't work for you, you are free to steal what you need to get it to do what you want. It is open source after all :) – Blizz Aug 14 '15 at 11:27

1 Answers1

2

According to the Yii guide here, the best way to create a logger component is to override the class yii\log\Target. Then to send the logs, you need to override the abstract method export() of this class

Since this class is accessed after the life cycle of the request, you will have the request and response data Yii::$app->request and Yii::$app->response and you can access them to create whatever message you want. This is an example of the LogHandler class (this can be edited to include whatever details you want about the request and response)

namespace app\models;

use yii\db\ActiveRecord;

class LogHandler extends ActiveRecord {
    $requestPath;
    $responseBody;

    public static function tableName() {
        return 'request_log';
    }    
}

And an example of a logger class is as follows:

namespace app\components\Logs;

use yii\helpers\VarDumper;
use yii\log\Target;
use Yii;

class LoggerComponent extends Target {

    public function export() {
        $logMessage = new LogHandler();
        $logMessage->requestPath = VarDumper::export(Yii::$app->request->absoluteUrl);
        $logMessage->responseBody = VarDumper::export(Yii::$app->response->data);
        $logMessage->save();
    }

}
mrateb
  • 2,317
  • 5
  • 27
  • 56