Laravel Events - Listens to a request made to a controller function and writes a log

Mohamad's interest is in Programming (Mobile, Web, Database and Machine Learning). He is studying at the Center For Artificial Intelligence Technology (CAIT), Universiti Kebangsaan Malaysia (UKM).
In Laravel, events are used to broadcast and listen to specific occurrences or actions within your application. Events can be triggered when certain conditions are met, such as when a user registers, when a new order is placed, or when a specific action is performed.
To work with Laravel events, you typically follow these steps:
Create an Event: You start by creating an event class that extends the base
Illuminate\Foundation\Events\Eventclass. This class defines the properties and methods associated with the event. For example, you might create aUserRegisteredevent class.Trigger an Event: Next, you trigger the event from the appropriate place in your application. For example, you might trigger the
UserRegisteredevent after a successful user registration process.Event Listeners: Event listeners are classes that handle the events triggered in your application. You can create event listeners that perform specific actions when an event occurs. For example, you might create a
SendWelcomeEmaillistener that sends a welcome email to the newly registered user. Listeners can be registered in theEventServiceProviderclass.Binding Listeners to Events: You need to bind the event listeners to their corresponding events. This can be done in the
EventServiceProviderclass, where you map events to their listeners.Handling Events: When an event is triggered, Laravel will automatically dispatch the event to its corresponding listeners. The listeners will then handle the event and perform the defined actions.
Laravel's event system provides a convenient way to decouple various components of your application and make it more modular. By using events, you can easily add or remove functionalities without tightly coupling your code.
[1] Register the event and listeners in the EventServiceProvider
Open the EventServiceProvider located in app/Providers/EventServiceProvider.php and add the following code within the $listen array:
<?php
namespace App\Providers;
use App\Events\RequestLogged;
use App\Listeners\LogRequest;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
protected $listen = [
RequestLogged::class => [
LogRequest::class,
],
];
// Other code...
}
The statement use App\Events\RequestLogged; and use App\Listeners\LogRequest; provides the information for creating the events and listener classes.
[2] Generate Events and Listener Classes
Run artisan command:
php artisan event:generate
The classes will be created in the respective paths stated in the above step.
[3] Edit Events and Listener Classes
[3.1] Events Class
File: Events/RequestLogged.php
Edit the constructor as follows:
...
public function __construct(Request $request)
{
$this->request = $request;
}
...
Full code:
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Http\Request;
class RequestLogged
{
use Dispatchable, InteractsWithSockets, SerializesModels;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct(Request $request)
{
$this->request = $request;
}
/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('channel-name');
}
}
[3.2] Listener Class
File: Listeners/LogRequest.php
Edit the handler as follows:
...
public function handle(RequestLogged $event)
{
$request = $event->request;
// Log the request
Log::info('Request logged:', [
'method' => $request->method(),
'url' => $request->fullUrl(),
'ip' => $request->ip(),
'user_agent' => $request->userAgent(),
]);
}
...
Full code:
<?php
namespace App\Listeners;
use App\Events\RequestLogged;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Log;
class LogRequest
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param \App\Events\RequestLogged $event
* @return void
*/
public function handle(RequestLogged $event)
{
$request = $event->request;
// Log the request
Log::info('Request logged:', [
'method' => $request->method(),
'url' => $request->fullUrl(),
'ip' => $request->ip(),
'user_agent' => $request->userAgent(),
]);
}
}
[4] Update the triggering class/method
Assuming you have an update method:
use App\Events\RequestLogged;
use Illuminate\Support\Facades\Log;
use DateTime;
...
public function update(Request $request, $id)
{
$validated = $request->validate([
'name' => 'required|unique:categories|max:50',
'image'=>'nullable',
]);
$category_updated = Category::where("id", $id)->update($validated);
/* CODE FOR THIS EXERCISE BEGIN */
// test event-listener
event(new RequestLogged($request));
// test direct logging
$dt = new DateTime();
Log::info("Update runs at:".$dt->format('Y-m-d H:i:s'));
/* CODE FOR THIS EXERCISE END */
return response()->json(
[
'data' => $category_updated,
'desc'=>'category_updated',
'stus' => 'success'
]
);
}
...
[5] Observe the outcome
Output: Logs/laravel.log

If data is not sent to log, probably it could be file permission error.
Try changing the file access mode:
chmod -R 755 storage/logs