在 Laravel 中记录用户操作

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24224175/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 09:39:14  来源:igfitidea点击:

Logging user actions in laravel

phplaravel

提问by wolfemm

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.

我正在尝试将用户执行的所有操作(登录/注销/CRUD)记录到我的数据库中的日志表中,并且从我所看到的事件看起来是正确的方法。

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

did($action)在 User 模型中添加了一个方法,该方法将给定用户的操作记录到数据库中。

Here's what I've got so far:

这是我到目前为止所得到的:

EventServiceProvider.php

事件服务提供者.php

namespace App\Events;

use Illuminate\Support\ServiceProvider;

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

UserEventSubscriber.php

用户事件订阅者.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?

1) 服务提供商是正确的使用方法还是这个?

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

2)是否有更好的方法不需要Auth::user()每次都手动传递给事件?

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.

3)应该在什么级别触发事件?我尽可能倾向于模型,因为它会从批量操作中提供更有用的日志。否则有控制器或存储库。

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?

4) 这些事件仅在管理区域 (/admin/*) 中是必需的。以某种方式将其限制在网站的那个部分是否有益?

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

5)我对用户操作记录的搜索非常徒劳。这只是开发人员不做的事情吗?那么,是什么他们做什么?

回答by The Alpha

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

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

是的,使用 aservice provider来引导事物是个好主意,但不是必需的。如果您愿意,您可以使用以下命令完全排除EventServiceProvider service provider并且可以从您的app/start/global.php文件中执行相同的操作:

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

Since $appis 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 provideris only a neat and clean way to bootstrap things (like including phpfiles using include "someClass.php") because the Laravelcalls the registermethod defined in every service providerclass 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.

因为$app是一个全局变量,所以你可以在这里使用它,但它不是在这个 ( global.php) 文件中执行此操作的更service provider简洁的方法,但 a只是引导事物(例如php使用包含文件include "someClass.php")的一种简洁明了的方法,因为Laravel调用了在中register定义的方法service provider框架启动过程中的每个类,因此开发人员可以在应用程序调度路由之前进行一些引导/初始化/包含等类似的事情。

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

是否有更好的方法不需要每次都手动将 Auth::user() 传递给事件?

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:

还有其他方法,但在这种情况下,请坚持使用当前方法,因为依赖是Auth::user()当前登录用户的方式,因此最好手动传递使用,或者您也\Auth::user()->did()可以像这样直接使用:

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

This is a different case but Laravelprovides a nice way to automatically resolve the dependencies using the IoCcontainer when you type cast any dependency in a __constructorclass, for example:

这是一种不同的情况,但Laravel提供了一种很好的方法来IoC在您在__constructor类中键入 cast 任何依赖项时使用容器自动解析依赖项,例如:

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

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

在这种情况下,您User在使用此类时不需要传递该类,因为IoC容器可以在框架实例化它时自动注入依赖项,但在您的情况下,他的依赖项Auth::user()/looged in user有点不同,因此手动执行或使用Auth::user()->did()直接地。

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 levelfor 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.

没有level这个,这取决于您的需要和偏好,也可能取决于应用程序的架构。实际上,即使不使用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?

这些事件仅在管理区域 (/admin/*) 中是必需的。以某种方式将其限制在网站的那个部分是否有益?

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

也许你可以但没有必要,没什么大不了的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 loggingof user actions then the answer is: depends. I did once for a travel agency, in their application the loggingof 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/outso higher authority could check their activities.

不完全确定您在说什么,但如果您在谈论logging用户操作,那么答案是:depends. 我曾经为一家旅行社做过一次,在他们的应用程序中logging,用户操作非常重要,因此我记录了用户登录后所做的几乎所有事情,例如:从客户那里收到付款,出售机票,他们的(员工/用户)登录,in/out以便更高的权限可以检查他们的活动。

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

不要犹豫别人做什么,找出你需要做什么,了解你的要求并相应地发展。

回答by Adel Abou Elezz

you can make helper function like that

你可以制作这样的辅助功能

function LogSystem($table,$action,$custom=null)
{
    $table::$action(function ($service) use ($action,$custom){
        if( ! is_null($custom))
        {
            $url='/panel/'.$custom.'/'.$service->id.'/edit';
        }
        else
        {
            $url=\Illuminate\Support\Facades\Request::fullUrl();
        }
        \Illuminate\Support\Facades\DB::table('log_activity')->insert([
            'subject' => $action.'::=='.$service->title,
            'url' => $url,
            'method' => \Illuminate\Support\Facades\Request::method(),
            'agent' => \Illuminate\Support\Facades\Request::header('user-agent'),
            'ip' => \Illuminate\Support\Facades\Request::ip(),
            'created_at'=>\Carbon\Carbon::now(),
            'user_id' => auth('admin')->check() ? auth('admin')->user()->id : 1,
        ]);
//
    });
}

Then Go to serviceproviders

然后转到服务提供商

LogSystem('\App\Services','created','services');

you Can call this for all croud system for any module you want

您可以为您想要的任何模块的所有croud系统调用它