404 Not Found Tracking (plugin)

The idea of tracking 404 errors started from here (first posted by WP Mix). The problem is that the result of those tutorials is that you will receive an email for each 404 error, and that can be quite annoying.

So I created a plugin that saves the errors into a mySQL table and sends daily (hourly, twicedaily) email alerts using WordPress’ cron system. Save the code snippet below as nftracking.php and place it in your plugins folder:

/*
  Plugin Name: 404 Not Found Tracking
  Plugin URI: https://wpcrumbs.com/404-not-found-tracking-plugin/
  Description: Track every 404 not found page
  Version: 1.0
  Author: George Jipa
  Author URI: https://wpcrumbs.com
 */

class NFTracking {

    public $notification = 'daily'; // you can change with hourly or twicedaily
    public $tracking_table;
    public $wpdb;

    public function __construct() {
        global $wpdb;
        $this->wpdb = $wpdb;
        $this->tracking_table = $wpdb->prefix . 'nftracking';

        // activate / deactivate plugin
        register_activation_hook(__FILE__, array($this, 'activate_plugin'));
        register_deactivation_hook(__FILE__, array($this, 'deactivate_plugin'));

        // add tracking
        add_action('wp', array($this, 'tracking'));

        // add cron
        add_action('my_send_notifications', array($this, 'send_notifications'));
    }

    /**
     * Tracking
    */
    public function tracking() {
        if (!is_404()) {
            return;
        }

        // insert 404 information
        $insert = array(
            'data' => serialize(array(
                'referer' => isset($_SERVER['HTTP_REFERER']) ? sanitize_text_field($_SERVER['HTTP_REFERER']) : 'undefined',
                'request' => isset($_SERVER['REQUEST_URI']) && isset($_SERVER['HTTP_HOST']) ? sanitize_text_field('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']) : 'undefined',
                'query_string' => isset($_SERVER['QUERY_STRING']) ? sanitize_text_field($_SERVER['QUERY_STRING']) : 'undefined',
                'ip_address' => isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field($_SERVER['REMOTE_ADDR']) : 'undefined',
                'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field($_SERVER['HTTP_USER_AGENT']) : 'undefined',
                'remote' => isset($_SERVER['REMOTE_IDENT']) ? sanitize_text_field($_SERVER['REMOTE_IDENT']) : 'undefined'
            )),
            'insert_date' => date('Y-m-d H:i:s')
        );

        $this->wpdb->insert($this->tracking_table, $insert, array('%s', '%s'));
    }

    /**
     * Triggered when plugin is activated
    */
    public function activate_plugin() {
        // create table
        $sql = "CREATE TABLE IF NOT EXISTS `{$this->tracking_table}` (
            `id` bigint(20) NOT NULL AUTO_INCREMENT,
            `data` text NOT NULL,
            `insert_date` datetime NOT NULL,
            PRIMARY KEY (`id`),
            KEY `insert_date` (`insert_date`)
        );";

        require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
        dbDelta($sql);

        // set cronjob event
        if (!wp_next_scheduled('my_send_notifications')) {
            wp_schedule_event(current_time('timestamp'), $this->notification, 'my_send_notifications');
        }
    }

    /**
     * Triggered when plugin is deactivated
    */
    public function deactivate_plugin() {
        // clear cronjob event
        wp_clear_scheduled_hook('my_send_notifications');

        // delete plugin options
        delete_option('nftracking_last_notification');
    }

    /**
     * Send email notifications
    */
    public function send_notifications() {
        // get last check time
        $last_notification = get_option('nftracking_last_notification', 0);

        // check if there are any errors in the database
        $errors = $this->wpdb->get_results($this->wpdb->prepare("SELECT * FROM {$this->tracking_table} WHERE insert_date >= %s", $last_notification), ARRAY_A);

        if (!empty($errors)) {
            ob_start();
            ?>
            
                
                    
Time 404 Referrer Query string Remote address Remote identity User agent

TO DO's:

1. Show the 404 errors in WordPress admin area too.
2. Clean the 404 errors table periodically.
2. Any ideas ?

Leave a Reply

Your email address will not be published. Required fields are marked *