Init Sentinel – Part 5: Building a Dashboard Widget for Security Log Monitoring

Once logging and retention are in place, the next step for Init Sentinel is observability. A dashboard widget is not meant to replace a full log viewer, but to act as a quick radar for administrators.

Init Sentinel – Part 5: Building a Dashboard Widget for Security Log Monitoring

This article explains how Init Sentinel implements a lightweight dashboard widget that surfaces recent security events while remaining fast, permission-aware, and tightly scoped.

The Role of the Dashboard Widget in Init Sentinel

The dashboard widget is not a data analysis tool. Its purpose is to quickly answer three questions: is something happening, what happened most recently, and should I investigate further.

Because of this, the widget must be fast, minimal, and never slow down wp-admin.

Registering the Widget with Proper Capability Checks

The widget should only be visible to users with sufficient privileges. Init Sentinel restricts access to high-level administrators to avoid exposing sensitive security data.

// Register dashboard widget
add_action('wp_dashboard_setup', function () {
    if ( ! current_user_can('manage_options') ) return;
    wp_add_dashboard_widget(
        'init_html_security_log_widget',
        __('Recent Security Logs', 'init-html'),
        'init_html_render_security_log_widget'
    );
});

Capability checks are applied both during registration and rendering to prevent accidental data exposure.

Safe Rendering with Table Existence Checks

The widget never assumes that the security log table exists. This avoids fatal errors during first-time setup or when the module is temporarily disabled.

// Render Sentinel widget
function init_html_render_security_log_widget() {
    if ( ! current_user_can('manage_options') ) {
        echo '<p>' . esc_html__('You do not have permission to view this widget.', 'init-html') . '</p>';
        return;
    }

    global $wpdb;
    $table = $wpdb->prefix . 'init_sentinel_security_log';

    $has_table = $wpdb->get_var( $wpdb->prepare(
        "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = %s",
        $table
    ) );

    if ( ! $has_table ) {
        echo '<p>' . esc_html__('Security log table not found.', 'init-html') . '</p>';
        return;
    }
}

This defensive approach ensures the dashboard remains stable under all conditions.

Limiting Rows and Using Cache to Keep wp-admin Fast

The widget displays only a small number of recent log entries, with a default limit of 25 rows that can be adjusted via filters.

Results are cached using the WordPress object cache to avoid repeated database queries on every dashboard load.

$limit = (int) apply_filters('init_html_security_log_widget_limit', 25);
if ($limit < 5) $limit = 5; if ($limit > 100) $limit = 100;

$cache_group = 'init_html_sentinel';
$cache_key   = 'widget_rows_' . $limit;
$ttl         = (int) apply_filters('init_html_security_log_widget_ttl', 10 * MINUTE_IN_SECONDS);

$rows = wp_cache_get($cache_key, $cache_group);
if ( false === $rows ) {
    $rows = $wpdb->get_results(
        $wpdb->prepare(
            "SELECT id, user_id, ip_address, endpoint, action, status_code, user_agent, created_at
             FROM {$table}
             ORDER BY created_at DESC
             LIMIT %d",
            $limit
        )
    );
    wp_cache_set($cache_key, $rows, $cache_group, $ttl);
}

Short-lived caching keeps the widget responsive while ensuring the data stays reasonably fresh.

Displaying Data with Readability in Mind

The widget focuses on the most relevant fields: timestamp, endpoint, action, status code, user or IP address, and user agent.

Status codes are visually classified to help administrators quickly assess severity.

Linking to the Full Security Logs Page

The widget is intentionally limited in scope. When deeper investigation is required, administrators need a dedicated page with filtering and pagination.

For this reason, the widget always includes a link to the full Security Logs page.

$logs_url = admin_url('admin.php?page=init-html-security-logs');
echo '<a href="' . esc_url($logs_url) . '">' . esc_html__('View all logs', 'init-html') . '</a>';

This creates a natural transition into the next stage of the Init Sentinel interface.

Conclusion

The Init Sentinel dashboard widget is designed as a lightweight observability tool rather than a full monitoring console. It stays fast, secure, and focused on early signal detection.

In the next article, we will build the full Security Logs admin page, where data can be explored, filtered, and analyzed in depth.

Comments


  • No comments yet.

Init Toolbox

Press Ctrl + \ on desktop, or swipe left anywhere on mobile.

Login