Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Logging user actions in laravel

Tags:

php

laravel

I'm trying to log all actions that users do (login / logout / CRUD) to a logs table in my database, and from what I've seen events look to be the right way to do this.

I've added a did($action) method to the User model, which logs an action to the database for the given user.

Here's what I've got so far:

EventServiceProvider.php

namespace App\Events;

use Illuminate\Support\ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->events->subscribe(new UserEventSubscriber);
    }
}

UserEventSubscriber.php

namespace App\Events;

class UserEventSubscriber
{
    public function login(\User $user)
    {
        return $user->did('logged_in');
    }

    public function logout(\User $user)
    {
        return $user->did('logged_out');
    }

    public function subscribe($events)
    {
        $events->listen('user.login', 'App\Events\UserEventSubscriber@login');

        $events->listen('user.logout', 'App\Events\UserEventSubscriber@logout');
    }
}

To log an action:

Event::fire('user.logout', array(Auth::user()));

I'm still trying to wrap my mind around service providers, so I could be very off-base here.

My questions:

1) Is a service provider the right thing to use or this?

2) Is there a better approach that doesn't require manually passing Auth::user() to the event every time?

3) At what level should events be fired? I'm leaning towards model whenever possible, as it would provide more useful logs from bulk actions. Otherwise there's the controller or repository.

4) These events are only necessary in the admin area (/admin/*). Would it be beneficial to somehow restrict this to only that section of the site?

5) My searches regarding the logging of user actions have been very unfruitful. Is this just something developers don't do? If so, what do they do?

like image 227
wolfemm Avatar asked Jun 14 '14 20:06

wolfemm


People also ask

What is logging in Laravel?

Laravel logging is based on "channels". Each channel represents a specific way of writing log information. For example, the single channel writes log files to a single log file, while the slack channel sends log messages to Slack. Log messages may be written to multiple channels based on their severity.


1 Answers

Is a service provider the right thing to use or this?

Yes, it's a good idea to use a service provider for bootstraping things but not necessary. If you want you may completely exclude the EventServiceProvider service provider and can do same thing from your app/start/global.php file using this:

$app->events->subscribe(new Events\UserEventSubscriber);

Since $app is a global variable so you may use it here but it's not a cleaner way to do this in this (global.php) file but a service provider is only a neat and clean way to bootstrap things (like including php files using include "someClass.php") because the Laravel calls the register method defined in every service provider class during the bootup process of the framework so developers can do some bootstraping/initializing/including and such like things before the application dispatch the route.

Is there a better approach that doesn't require manually passing Auth::user() to the event every time?

There are other ways but in this case stick with you current approach because dependency is the Auth::user() means that, the currently logged in user so it's better to pass the use manually or you may also use \Auth::user()->did() directly like this:

public function login()
{
    return \Auth::user()->did('logged_in');
}

This is a different case but Laravel provides a nice way to automatically resolve the dependencies using the IoC container when you type cast any dependency in a __constructor class, for example:

class SomeClass {
    public function __construct(User $user)
    {
        $this->use = $user;
    }
}

In this case you don't need to pass the User class when you use this class because the IoC container can automatically inject the dependency when the framework instantiate it but in your case, he dependency is Auth::user()/looged in user so it's a bit different thing so manually do it or use Auth::user()->did() directly.

At what level should events be fired? I'm leaning towards model whenever possible, as it would provide more useful logs from bulk actions. Otherwise there's the controller or repository.

There is no level for this, it depends on your need and preference and maybe architecture of the application as well. Actually, you may build your application even without using events.

These events are only necessary in the admin area (/admin/*). Would it be beneficial to somehow restrict this to only that section of the site?

Maybe you can but no need, not a very big deal IMO.

My searches regarding the logging of user actions have been very unfruitful. Is this just something developers don't do? If so, what do they do?

Not completely sure what you are talking about but if you are talking about the logging of user actions then the answer is: depends. I did once for a travel agency, in their application the logging of user actions were very important so I logged almost everything a user does after (s)he logs in, such as: receiving a payment from a client, selling a ticket, their (employees/users) log in/out so higher authority could check their activities.

Don't hesitate about what others do, find out what you need to do, understand your requirements and develop accordingly.

like image 81
The Alpha Avatar answered Oct 12 '22 18:10

The Alpha