How to track any WordPress user activity

Learn how to track any WordPress user activity with Advanced Access Manager plugin (version 4.3 or higher) and free AAM User Activity extension.

Tracking user activities in WordPress is crucial for different reasons. It can be audit, user performance tracking, security etc. There are few well established plugins in the official WordPress repository that track the very basic list of activities like changes to posts, pages, users, plugins, core etc. However they are limited to certain, predefined by plugin’s developer activities.

With AAM User Activity extension we take different approach. We give you the power to decide what do you want to track and how do you want to display the logged activity. The entire functionality is based on the WordPress core concept of filters and actions (hooks). When some activity occurs, WordPress triggers one of few hooks with data related to that activity, this is where AAM User Activity captures this activity and stores it to the database.

For example, when any post, page or custom post type is modified, WordPress triggers save_post hook with information about a post. This activity can be captured and presented to you as following:

WordPress user activity log

= Quick start =

The AAM User Activity extension, by default, tracks only core AAM access denied events however you will notice the “Install free AAM User Activity Helper plugin to track more activities.” notification. This plugin is hosted on GitHub so anybody can contribute to it. We constantly are adding more tracking activities to it. Contact us today and we will add your desired activity for no cost.

= Customize user tracking =

To track your desired activities you would have to configure AAM to listen specific hooks. To do that, you can either use AAM ConfigPress or utilize aam-user-activity-hooks-filter hook that should return the configuration array.

In this tutorial we will explore the first option however you can find the example for the configuration array in the AAM User Activity Helper plugin.

Please note! If it is getting to complicated and overwhelming, contact us immediately and we will help you asap.

Step 1. Install ConfigPress extension
Make sure that you have ConfigPress extension installed. It is free and you can find it on the Extensions tab under the list of Free extensions.

Step 2. Get familiar with user activity configurations.
On the ConfigPress tab you can configure the list of hooks to listen. For example, let’s configure activated_plugin event that is triggered when any plugin is activated.

activity.hook.activated_plugin = "Plugin {$0} was activated"

The configurations are based on the INI format and starts with section definition. It tells AAM that all settings below the line belongs to AAM.

All the hooks come with leading activity.hook. prefix and following with the hook name. The next is defined a human readable message that you will see on the User Activity page. The message contains one or more markers that correspond to the arguments that are passed to the hook. For example, the hook activated_plugin is triggered with two arguments $plugin and $network_wide as specified in the official hook’s documentation. The {$0} marker is replaced with content of the first passed argument (in our case it is string $plugin).

When argument is more complex than just a scalar value then you can define a full path to the specific element or property as following {$N.depth1.depth2…depthN}. For example we can track comment editing activity and show the comment content after it was updated.

activity.hook.edit_comment = "Comment with ID {$0} updated to {$1.comment_content}"

The edit_comment hook is triggered with two arguments where the first argument is comment ID and the second is an associated array with the comment data. This way you can access any element or property disregarding whether it is array or object.

In some instances you may want to define callback function that can prepare the activity message. For example let’s show the trashed post’s title. The core trashed_post hook triggers only with one argument which is $post_id. In our scenario we would have to get post to find it’s title.

First let’s define the callback method that will take event data and prepare the message.

 * AAM user activity helper
 * @package AAM
 * @author Vasyl Martyniuk 
class AAM_UserActivity_Helper {

     * Decorate event message
     * Decorate post trashed event message
     * @param array $event
     * @return string
     * @access public
    public static function trashedPost($event) {
        $metadata = unserialize($event['metadata']); //metadata is always serialized
        $post     = get_post($metadata[0]); //the first argument $post_id

        if (is_a($post, 'WP_Post')) {
            $message = sprintf(
                'Post %s (ID: %d) was moved to trash', 
        } else {
            $message = sprintf('Post with ID %s was moved to trash', $metadata[0]);

        return $message;


The final step is to configure AAM to use this callback method.

activity.hook.trashed_post.messageCallback = "AAM_UserActivity_Helper::trashedPost"

The result of this configuration is as following:

WordPress trash post traching

Do not hesitate to contact us if you need assistance in configuring your user activity tracking.

Get Development Package with all extensions included for unlimited number of sites

Learn More

Get the latest updates and promos.