With the help of hooks in WordPress you can modify how Simple History works. You can for example change who can see the log and customize what is logged.
Actions and filters are prefixed with simple_history/, for example 'simple_history/log/do_log'.
💡 For more information on how to use hooks in WordPress see the hooks documentation on wordpress.org.
There are many actions and filters in the plugin. For a list of all see the source code of the plugin. You can search the code on GitHub for all hooks (requires that you are logged in to GitHub).
Below are the filters and actions that are used the most.
simple_history/add_custom_logger
do_action(
'simple_history/add_custom_logger',
Simple_History $simple_history
);Code language: PHP (php)
Fires after the list of loggers to load are populated. Can for example be used by plugins to load their own custom loggers.
See register_logger() for more info.
simple_history/log/inserted
do_action(
'simple_history/log/inserted',
array $context,
array $data_parent_row,
Logger $logger
);Code language: PHP (php)
Fired after an event has been logged.
- @param array $context Array with all context data that was used to log event.
- @param array $data_parent_row Array with data used for parent row.
- @param Logger $logger The logger that logged the event.
simple_history/view_history_capability
apply_filters(
'simple_history/view_history_capability',
string $capability
)Code language: PHP (php)
Filters the capability required to view the log. Default is edit_pages, which means Editors and Administrators.
Example: Only let Administrators view the log:
add_filter(
'simple_history/view_history_capability',
function ( $capability ) {
return 'manage_options';
}
);Code language: PHP (php)
simple_history/view_settings_capability
apply_filters(
'simple_history/view_settings_capability',
string $capability
)Code language: PHP (php)
Filters the capability required to view the settings page and clear the log. Default is manage_options, which means Administrators.
simple_history/dashboard_pager_size
apply_filters(
'simple_history/dashboard_pager_size',
int $pager_size
)Code language: PHP (php)
Filter the pager size setting for the dashboard.
simple_history/db_purge_days_interval
apply_filters(
'simple_history/db_purge_days_interval',
int $days
)Code language: PHP (php)
Filter to modify number of days of history to keep. The value from the settings page is passed in, and whatever the filter returns is used instead. Default is 30 days on new installs and 60 days on sites that installed Simple History before version 5.25.0.
Example: Keep only the most recent 7 days in the log:
add_filter(
"simple_history/db_purge_days_interval",
function( $days ) {
$days = 7;
return $days;
}
);
Code language: PHP (php)
Example: Expand the log to keep 90 days in the log.
add_filter(
"simple_history/db_purge_days_interval",
function( $days ) {
$days = 90;
return $days;
}
);Code language: PHP (php)
simple_history/purge_db_where
apply_filters(
'simple_history/purge_db_where',
string $where,
int $days,
string $table_name
)Code language: PHP (php)
Filter the SQL WHERE clause used when purging old events. This allows advanced customization of which events to delete, such as per-logger retention periods or keeping certain events forever.
- @param string $where SQL WHERE clause (without “WHERE” keyword).
- @param int $days Default retention days from settings.
- @param string $table_name Events table name.
Available columns in the events table: id, logger, level, date, message, initiator. You are responsible for returning valid SQL, so always use $wpdb->prepare() for dynamic values. The examples use MySQL date functions and will not work on sites that use SQLite.
Example: Keep SimpleOptionsLogger events forever (exclude from purge):
add_filter( 'simple_history/purge_db_where', function( $where, $days, $table ) {
global $wpdb;
return $where . $wpdb->prepare( ' AND logger != %s', 'SimpleOptionsLogger' );
}, 10, 3 );Code language: PHP (php)
Example: Keep events with level “warning” or higher forever:
add_filter( 'simple_history/purge_db_where', function( $where, $days, $table ) {
return $where . " AND level NOT IN ('warning', 'error', 'critical', 'alert', 'emergency')";
}, 10, 3 );Code language: PHP (php)
Example: Different retention per logger (login events 1 year, others use default):
add_filter( 'simple_history/purge_db_where', function( $where, $days, $table ) {
global $wpdb;
return $wpdb->prepare(
'(logger = %s AND DATE_ADD(date, INTERVAL 365 DAY) < NOW())
OR (logger != %s AND DATE_ADD(date, INTERVAL %d DAY) < NOW())',
'SimpleUserLogger',
'SimpleUserLogger',
$days
);
}, 10, 3 );Code language: PHP (php)
simple_history/log/do_log
apply_filters(
'simple_history/log/do_log',
bool $doLog,
string $level,
string $message,
array $context,
Logger $logger
)
Code language: PHP (php)
- @param bool $doLog Whether to log or not.
- @param string $level The loglevel.
- @param string $message The log message.
- @param array $context The message context.
- @param Logger $instance Logger instance.
Example: Disable all logging.
add_filter(
'simple_history/log/do_log',
'__return_false'
)Code language: JavaScript (javascript)
Example: Do not log some post types, for example pages and attachments in this case.
add_filter(
'simple_history/log/do_log',
function ( $do_log = null, $level = null, $message = null, $context = null, $logger = null ) {
$post_types_to_not_log = array(
'page',
'attachment',
);
if ( ( isset( $logger->slug ) && ( $logger->slug === 'SimplePostLogger' || $logger->slug === 'SimpleMediaLogger' ) ) && ( isset( $context['post_type'] ) && in_array( $context['post_type'], $post_types_to_not_log ) ) ) {
$do_log = false;
}
return $do_log;
},
10,
5
);Code language: PHP (php)
simple_history/log/do_log/{$logger_slug}
apply_filters(
"simple_history/log/do_log/{$logger_slug}",
bool $do_log
)Code language: PHP (php)
Example filter names:
simple_history/log/do_log/SimpleUserLoggersimple_history/log/do_log/SimplePostLogger
Example: Disable logging of any user login/logout/failed login activity:
add_filter(
'simple_history/log/do_log/SimpleUserLogger',
'__return_false'
);Code language: JavaScript (javascript)
simple_history/log/do_log/{$logger_slug}/{$message_key}
apply_filters(
"simple_history/log/do_log/{$logger_slug}/{$message_key}",
bool $do_log
)Code language: PHP (php)
Easy shortcut method to disable logging of messages from a specific logger and message.
Example filter names:
simple_history/log/do_log/SimpleUserLogger/user_logged_insimple_history/log/do_log/SimplePostLogger/post_updated
Example: Log failed logins, but not successful ones:
add_filter(
'simple_history/log/do_log/SimpleUserLogger/user_logged_in',
'__return_false'
);Code language: JavaScript (javascript)
simple_history/pause
do_action('simple_history/pause')
Disables logging completely until next page load or until simple_history/resume is triggered.
Useful for example when importing many things using PHP because then the log can be overwhelmed with data.
A code snippet to show the behavior:
// Creation of this post is logged.
wp_insert_post(array(
'post_title' => 'Test before pause (will be logged) ' . time(),
'post_content' => 'Test',
'post_status' => 'publish',
'post_type' => 'post',
));
// Pause logging.
do_action('simple_history/pause');
// Creation of these 100 posts will not be logged.
for ( $i = 0; $i < 100; $i++ ) {
wp_insert_post(array(
'post_title' => 'Test after pause (should not be logged) ' . time(),
'post_content' => 'Test',
'post_status' => 'publish',
'post_type' => 'post',
));
}
// Enable logging again.
do_action('simple_history/resume');
// Creation of this post is logged.
wp_insert_post(array(
'post_title' => 'Test after resume (should be logged again) ' . time(),
'post_content' => 'Test',
'post_status' => 'publish',
'post_type' => 'post',
));Code language: PHP (php)
simple_history/resume
See documentation for simple_history/pause.
simple_history/maps_api_key
Allows you to set a Google Maps API key, so that the popover you get when clicking an IP address in the log shows a map of the location.
// Use filter to set API key that we own.
add_filter(
'simple_history/maps_api_key',
function() {
return 'your-google-maps-key';
}
);Code language: JavaScript (javascript)
After supplying your API key Simple History shows a map when you click an IP address, for example on a successful login:

By default Simple History masks IP addresses before storing them, so the address that is looked up is the first address in the masked subnet. If the stored IP address is 142.250.75.x, the address used to find the location is 142.250.75.0. The location can therefore be wrong, since the user could have had the address 142.250.75.96, which could be somewhere else.
To overcome this you can use a filter to allow storing the full IP address. See simple_history/privacy/anonymize_ip_address for more info.
simple_history/privacy/anonymize_ip_address
$anonymize_ip_address = apply_filters(
'simple_history/privacy/anonymize_ip_address',
true
);Code language: PHP (php)
Filter to control if IP addresses should be masked before they are stored. Defaults to true. The last part of an IPv4 address is removed, and IPv6 addresses keep only the first half. This is done for privacy reasons, for example the GDPR.
<?php
// Disable IP masking to allow the full
// IP address to be added to events.
// e.g. "17.253.144.10" will be stored
// instead of "17.253.144.x".
add_filter( 'simple_history/privacy/anonymize_ip_address', '__return_false' );
Code language: HTML, XML (xml)
simple_history/view_ip_address_capability
/**
* Filters the capability required to see IP addresses in the log.
*
* @since 5.35.0
*
* @param string $capability Capability. Default "manage_options".
*/
apply_filters( 'simple_history/view_ip_address_capability', 'manage_options' );Code language: PHP (php)
Since version 5.35.0, IP addresses in the log are only shown to users with the manage_options capability, which by default means administrators. Editors and other roles that can read the log still see the events, but without IP addresses in events, event details, exports or search. Use this filter to choose another capability.
// Let Editors see IP addresses again.
add_filter(
'simple_history/view_ip_address_capability',
function () {
return 'edit_pages';
}
);Code language: PHP (php)
WP-CLI commands always show IP addresses. For requests that are allowed in some other way than by a logged in user, like the RSS feed with a valid secret, use the filter simple_history/current_user_can_view_ip_addresses. It receives a boolean and returns whether IP addresses may be shown.
simple_history/get_log_row_plain_text_output/output
/**
* Filter the plain text output for a log row.
*
* @since 4.6.0
*
* @param string $output Plain text output for a log row.
* @param object $row Log row object.
* @param Logger $logger Logger instance.
*/
apply_filters(
'simple_history/get_log_row_plain_text_output/output',
$logger->get_log_row_plain_text_output( $row ),
$row,
$logger
);
Code language: PHP (php)
Filters the “plain text” message output. The output can be for example “Updated page ‘About the company’” and using this filter you can prepend or append text to the message.
Examples: Add post id to each post or WooCommerce event.
simple_history/log_insert_context
Filters the context to store for an event, before it is saved.
/**
* Filters the context to store for this event/row
* @param array $context Array with all context data to store. Modify and return this.
* @param array $data Array with data used for parent row.
* @param Logger $logger Reference to logger instance.
*/
$context = apply_filters(
'simple_history/log_insert_context',
$context,
$data,
$logger
);Code language: PHP (php)
simple_history/admin_menu_location
Filters the placement of Simple History in the Admin Menu.
Valid locations:
- ‘top’ for placement close to dashboard at top of main menu
- ‘bottom’ for placement near below settings
- ‘inside_tools’ for placement inside the tools menu
- ‘inside_dashboard’ for placement inside the dashboard menu
// Example: Set location to bottom of main menu.
add_filter(
"simple_history/admin_menu_location",
function() {
return 'bottom';
}
);Code language: JavaScript (javascript)