# Simple Admin Activity Log

> Records logins, plugin and theme changes, updates, role changes and deleted content, and lists the last 300 events under Tools > Activity Log.

- Type: PHP
- Runs: Run everywhere
- Category: [Security](https://wpide.com/library/category/security/)
- Tags: security, logging, audit
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/admin-activity-log/

## Code

```php
$wpide_activity = function ( $message ) {
    $user  = wp_get_current_user();
    $log   = get_option( 'wpide_activity_log', array() );
    $log   = is_array( $log ) ? $log : array();
    $log[] = array(
        'time' => time(),
        'user' => $user->exists() ? $user->user_login : '',
        'ip'   => isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : '',
        'msg'  => $message,
    );

    update_option( 'wpide_activity_log', array_slice( $log, -300 ), false );
};

add_action( 'wp_login', function ( $login ) use ( $wpide_activity ) {
    $wpide_activity( sprintf( 'Logged in as %s', $login ) );
} );
add_action( 'activated_plugin', function ( $plugin ) use ( $wpide_activity ) {
    $wpide_activity( 'Activated plugin ' . $plugin );
} );
add_action( 'deactivated_plugin', function ( $plugin ) use ( $wpide_activity ) {
    $wpide_activity( 'Deactivated plugin ' . $plugin );
} );
add_action( 'switch_theme', function ( $name ) use ( $wpide_activity ) {
    $wpide_activity( 'Switched theme to ' . $name );
} );
add_action( 'upgrader_process_complete', function ( $upgrader, $extra ) use ( $wpide_activity ) {
    if ( ! empty( $extra['type'] ) && ! empty( $extra['action'] ) ) {
        $wpide_activity( sprintf( 'Ran %s for %s', $extra['action'], $extra['type'] ) );
    }
}, 10, 2 );
add_action( 'set_user_role', function ( $user_id, $role, $old ) use ( $wpide_activity ) {
    if ( $old ) {
        $user = get_userdata( $user_id );
        $wpide_activity( sprintf( 'Changed role of %s to %s', $user ? $user->user_login : '#' . $user_id, $role ) );
    }
}, 10, 3 );
add_action( 'deleted_user', function ( $user_id ) use ( $wpide_activity ) {
    $wpide_activity( 'Deleted user #' . $user_id );
} );
add_action( 'before_delete_post', function ( $post_id, $post ) use ( $wpide_activity ) {
    if ( $post && ! in_array( $post->post_type, array( 'revision', 'customize_changeset', 'oembed_cache', 'wp_global_styles' ), true ) && 'auto-draft' !== $post->post_status ) {
        $wpide_activity( sprintf( 'Permanently deleted %s "%s"', $post->post_type, $post->post_title ) );
    }
}, 10, 2 );

add_action( 'admin_menu', function () {
    add_management_page( 'Activity Log', 'Activity Log', 'manage_options', 'wpide-activity-log', function () {
        $log = array_reverse( (array) get_option( 'wpide_activity_log', array() ) );
        echo '<div class="wrap"><h1>Activity Log</h1><table class="widefat striped"><thead><tr><th>Time</th><th>User</th><th>Event</th><th>IP</th></tr></thead><tbody>';
        if ( ! $log ) {
            echo '<tr><td colspan="4">Nothing recorded yet.</td></tr>';
        }
        foreach ( $log as $row ) {
            printf(
                '<tr><td>%1$s</td><td>%2$s</td><td>%3$s</td><td><code>%4$s</code></td></tr>',
                esc_html( wp_date( 'Y-m-d H:i:s', (int) $row['time'] ) ),
                esc_html( $row['user'] ? $row['user'] : 'system' ),
                esc_html( $row['msg'] ),
                esc_html( $row['ip'] )
            );
        }
        echo '</tbody></table></div>';
    } );
} );
```

## Notes

A lightweight log for small sites; use a dedicated audit plugin when you need search, export or retention rules.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Simple Admin Activity Log" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
