I know what you did last session : Using Monolog for Logging in Laravel Framework

When your system is used by so many users, it will be hard to blame somebody when something wrong happen. As the users are getting bigger and bigger it will hard to find it. There are ways to tracing back who is the suspect. One of it is by logging what action that users’ have done on their session. Especially on my work as CMS (developers.kudo.co.id/2016/09/15/pengenalan-sistem-manajemen-konten/) developer which related with databases (developers.kudo.co.id/2016/06/09/cms-faster-data-retrival-with-sql-query-optimization/), it is crucial.

Based on my experience when using Laravel framework, logging is an easy piece of cake. Laravel can integrate with Monolog. What exactly is Monolog? Monolog is PHP library for sending log file into your database, sockets, inbox and various web services.

Then why we need to logging users’ action? First thing is you cannot remember every action you already done, while logging yes, it stays on your DB. Then tracing activity will be easier, you only need to find it on DB. It is pretty useful for me to know who did the changes.
 
Here are steps that you can follow to generate monolog in Laravel
After install it (follow link: https://github.com/seldaek/monolog)
You can use monolog on basic usage like this:

<?php;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

// create a log channel
$log = new Logger('name');
$log->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING));

// add records to the log
$log->warning('Foo');
$log->error('Bar');

 

But our team decided to save logging on our database server, we custom the code so the handler will update date into database.
 
First we create library for handler to mySql :

<?php;
namespace App\Library; 
use Monolog\Logger; 
use Monolog\Handler\AbstractProcessingHandler; 
use PDO; 
use PDOStatement; 
class MonologHandler extends AbstractProcessingHandler 
{ 
private $initialized = false;
    protected $pdo;
    private $statement;
    private $table = 'monolog';
    private $data = array();
    
    public function __construct(PDO $pdo = null, $table, $level = Logger::DEBUG)
    {
        if (!is_null($pdo)) {
            $this->pdo = $pdo;
        }
        $this->table = $this-> $table;
        parent::__construct($level);
    }
    
    private function initialize()
    {
        $stmt = 'INSERT INTO `'.$this->table.'` (value_id, value_type, action) VALUES (:value_id, :value_type, :action_time, :action, :detail)'; //decide what value you wan to store
        $this->statement = $this->pdo->prepare($stmt);
        $this->initialized = true;
    }
    
    protected function write(array $record)
    {
        $contentArray = $record['context'];

        if (!$this->initialized) {
            $this->initialize();
        }
        $this->statement->execute($contentArray);
    }
}

 
Then we also create library for creating the request of log itself:

<?php;
namespace App\Library;

use App\Library\MonologMysqlHandler;
use Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class MonologRequest
{
    public static function did($action ,$value_type)
    {
        $msg = "";
        $value_id = Auth::id(); //store user_id

        // Create handler
        try {
            $pdo = DB::connection("monolog")->getPdo();
            $handler = new MonologMysqlHandler($pdo, $feature, \Monolog\Logger::DEBUG);
        } catch (\Exception $e) {
            $msg = 'Caught exception: '. $e->getMessage(). "\n";
            Log::warning("Log Not Write, ".$msg);
        }

        // Create logger
        $logger = new \Monolog\Logger($value_id);
        $logger->pushHandler($handler);

        // Send It!
        $action_time = date('Y-m-d H:i:s');

        try {
            $data = array('value_id'  => $ value_id, 'action_time' => $action_time, 'action' => $action, 'value_type' => $value_type);
            $logger->addWarning($action, $data);
        } catch (\Exception $e) {
            $msg = 'Caught exception: '. $e->getMessage(). "\n";
            Log::warning("Log Not Write, ".$msg);
        }
        return $msg;
    }
}

 
After all of the library are ready, we can use directly when user hit the action. Just put it on the controller:
Example, getting action user login :

use App\Library\MonologRequest;
class UserLoginController extends Controller
{
public function doLogin(Request $request)
    {
        $remember = $request->remember;
        $user_credential = [
            'email' => $request->email,
            'password' => $request->password
        ];

        $rules = [
            'email' => 'required',
            'password' => 'required'
        ];

        $validator = Validator::make($user_credential, $rules);
        if ($validator->passes()) {
            if (Auth::attempt($user_credential, $remember)) {
                $id = Auth::user()->id;
                if ($id) {
                    session()->put('id', $id);
                }
                //Logging
                MonologRequest::did('user', 'login'); //($table_name,$action)

                return redirect()->to('/dashboard');
            } else {
                return redirect()->back()->with(['message' => 'cannot log in, email or password is invalid!']);
            }
        } else {
            return redirect()->back()->withErrors($validator);
        }
    }
}

 

None of this is complicated if you familiar with Laravel. We just customize a bit. Using this Logging, now we can easily track what people are doing during their session.
Cheers 😀
Source :
• https://github.com/seldaek/monolog
• https://laravel.com/docs/5.2/errors#logging

Comments

comments

stefanusardhito

You Might Also Like

No Comment

Leave your thought