Fork me on GitHub

Audit log

To enable the optional audit log simply set the AUDIT_ENABLED variable to true in the .env file as shown below:

AUDIT_ENABLED=true

By default the audit log is disabled. When enabled some user actions can log an entry in the application audit log by calling the static function Audit::log() as demonstrated below:

// Create simple audit log entry
Audit::log(Auth::user()->id, 'User', 'Access list of users.');

The full parameter list for the log() function is:

log($user_id, $category, $message, Array $attributes = null, $data_parser = null, $replay_route = null)

Parameter info:

  • $user_id: The id of the user that triggered the action, can be null when a user is not authenticated.
  • $category: Free text to group log entries, later we should be able to filter and search by the category.
  • $message: Free text containing the main message.
  • $attributes: An array containing any additional data that should either be displayed on the show page or be used by the replay action.
  • $data_parser: The full name, including namespace and class name of the function to call to parse the data array stored in $attributes.
  • $replay_route: The name of the Laravel route that will be called to replay this action.

Replay action

The replay action feature, as the name suggests, allows to replay or repeat an action that was previously logged from the audit log. For the replay action to be available both the attributes and the replay_route parameters must be specified. Perhaps the best and easiest way to understand how it functions is to follow a concrete example. Below I will describe how the replay action is used in the case of a user edit.

Creating a replay-able audit log entry
  1. The operator (human) click on the link to edit the entry of a user, say ID #3, the URL would look something like this http://lesk/admin/users/3/edit.

  2. The controller UsersController and its function edit are invoked. The edit function prepares the data that will be displayed and edited then pass it all to the view admin.users.edit. Note that in the edit function an audit log entry is created stating that the operator initiated the edition of the user. This is just a simple audit log entry that does not save any attributes or sets the replay_route, it is there simply for audit purposes.

  3. The view is built and returned to the operator to see in his browser.

  4. The operator makes the changes that are required and submits the form.

  5. The controller UsersController and its function update are invoked. As expected update function will capture the data and update the user's record in the database, but it will also create an audit log entry that can be replayed. Here are the steps required in details:

  6. Capture the posted attributes from the request:

    $attributes = $request->all();

  7. Add any data that would be needed by the replay function, here we want to make sure to add the id of the user since it was passed as a separate parameter to the update function:

    $replayAtt["id"] = $id;

  8. Finally, create the audit log entry:

    Audit::log( Auth::user()->id, 'User', "Edit user: $user->username",
    $replayAtt, "App\Http\Controllers\UsersController::ParseUpdateAuditLog", "admin.users.replay-edit" );

That is it, you are done, a replay-able audit log entry has been created. Note the 4th and 6th parameters. The 4th parameter (replayAtt) is the array of attributes that will be filtered to remove the session token and passwords, then converted into JSON and stored in the data column. The 6th parameter (admin.users.replay-edit) is the name of the Laravel route that will be invoked when a replay action is requested. The 5th parameter is the fully qualified function name that will be used to parse the data field. That will be described in a section below on displaying entry details and custom rendering partials.

Triggering a replayable entry

Following the example above, here is a description of how triggering a replayable action function:

  1. The operator (human) access the audit log page at: http://lesk/admin/audit">http://my-lesk-site/admin/audit
  2. Locates the replay-able entry by it's spinning recycling icon in the action column, and click on it.
  3. The replay function of the AuditsController controller is invoked. The replay function locates the audit log entry from the id passed in, and redirect to the Laravel route that is stored in the replay_route. In this case, it is admin.users.replay-edit.
  4. The admin.users.replay-edit route triggers the function replayEdit in the UsersController controller, as defined in the app\Http\routes.php file.
  5. The replayEdit function performs the following:
  6. Locates the audit log entry from the ID passed in from AuditsController::replay().
  7. Grabs the data field and decodes it from json the associative array.
  8. Locates the user object in question from the ID field of the data array.
  9. Creates a new audit log entry for good measure.
  10. Update or overwrite the value of the user object with the value from the data array.
  11. Save the user object.
  12. Redirect to the user's edit page for the operator to confirm or edit some more.
Displaying entry details and custom rendering partials

An audit log entry that is replayable will most likely have some data attributes that make it unique and has to be processed in order to be displayed properly. In the call to the Audit::log() function above that creates the replay-able entry, the 5th parameter, the data_parser, is the fully qualified name of a function that will get called to prepare the data before returning the view displaying the details to the browser. Additionally, the data_parser function can add to the data array an entry with a key of show_partial that points to a partial blade file that will be responsible for rendering the parsed data of the audit log entry. If no show_partial is specified the default behaviour is to use var_dump() to simply dump the value on the page.