Enjoying these plugins? ☕ Buy me a coffee to support ongoing development.

Login Attempt Monitor

A comprehensive WordPress plugin that monitors and logs all login attempts (successful and failed) with detailed information including username, IP address, status, browser info, and timestamp.

Single File v1.0.1 Updated 3 days ago

YT Login Attempt Monitor

A comprehensive WordPress plugin that monitors and logs all login attempts (successful and failed) with detailed information including username, IP address, status, browser info, and timestamp.

Description

The Login Attempt Monitor plugin provides complete visibility into all login activity on your WordPress site. Track successful logins, monitor failed attempts, identify potential security threats, and maintain detailed logs for compliance and security auditing.

Features

  • Comprehensive Logging: Records both successful and failed login attempts
  • Detailed Information: Username, User ID, IP address, browser info, timestamp
  • Custom Database Table: Dedicated table for optimal performance
  • Admin Dashboard: Clean interface under Users → Login Log
  • Live Statistics: Total, successful, failed, and today's attempts
  • Advanced Filtering: Filter by status, search by username/IP
  • Pagination: Handle thousands of logs efficiently
  • Export to CSV: Download complete log history
  • Clear Logs: Bulk delete functionality
  • Auto Cleanup: Automatic deletion of old logs based on retention policy
  • IP Geolocation: Click IP addresses for lookup (external service)
  • Browser Detection: Parse and display browser information
  • Configurable Settings: Control what gets logged and for how long
  • Maximum Log Limit: Prevent database bloat with configurable limits
  • Time Formatting: Human-readable time differences ("2 hours ago")
  • Responsive Design: Mobile-friendly admin interface
  • Search Highlighting: Visual search term highlighting
  • Keyboard Shortcuts: Ctrl+R (refresh), Ctrl+E (export)
  • AJAX Operations: Delete logs without page reload
  • Security Focused: Proper escaping, nonces, and capability checks

Installation

  1. Upload yt-login-attempt-monitor.php to /wp-content/plugins/
  2. Upload yt-login-attempt-monitor.css to the same directory
  3. Upload yt-login-attempt-monitor.js to the same directory
  4. Activate the plugin through the 'Plugins' menu
  5. View logs at Users → Login Log
  6. Configure settings at Settings → Login Monitor

Usage

Viewing Login Logs

  1. Go to Users → Login Log
  2. View statistics at the top:
    • Total Attempts
    • Successful Logins
    • Failed Attempts
    • Today's Activity
  3. Browse the log table with full details
  4. Use filters to narrow results

Filtering Logs

By Status:

  • All Statuses
  • Successful only
  • Failed only

By Search:

  • Search by username
  • Search by IP address
  • Real-time search highlighting

Managing Logs

Delete Single Entry:

  • Click "Delete" button on any row
  • Confirm the action
  • Entry removed immediately

Clear All Logs:

  • Click "Clear All Logs" button
  • Confirm the action
  • All logs permanently deleted

Export Logs:

  • Click "Export CSV" button
  • Download CSV file with all log data
  • File named: login-attempts-YYYY-MM-DD.csv

Configuration

Go to Settings → Login Monitor:

Log Types

  • Log successful login attempts: Track successful logins
  • Log failed login attempts: Track failed attempts

Log Retention

  • Days: 1-365 (default: 30)
  • Description: Logs older than this are auto-deleted daily
  • Example: Set to 30 to keep only last month's data

Maximum Logs

  • Count: Minimum 100 (default: 1000)
  • Description: Maximum number of logs stored
  • Behavior: Oldest logs deleted when limit reached

Browser Info

  • Track Browser Info: Record user agent strings
  • Shows: Browser name (Chrome, Firefox, Safari, etc.)
  • Privacy: Optional if concerned about data collection

Settings Reference

Log Types

Log Successful Login Attempts

  • Default: Enabled
  • Purpose: Track all successful authentications
  • Use Case: Audit trail, user activity monitoring

Log Failed Login Attempts

  • Default: Enabled
  • Purpose: Monitor potential security threats
  • Use Case: Brute force detection, security alerts

Retention Days

Range: 1-365 days Default: 30 days Cleanup: Automatic daily via wp-cron

Recommendations:

  • 7 days: Minimal storage, quick troubleshooting only
  • 30 days: Good balance for most sites
  • 90 days: Compliance requirements
  • 365 days: Full year audit trail

Maximum Logs

Minimum: 100 Default: 1000 Purpose: Prevent database bloat

Calculation:

  • Average log size: ~200 bytes
  • 1000 logs ≈ 200 KB
  • 10000 logs ≈ 2 MB

Recommendations:

  • Small sites (< 10 users): 500-1000
  • Medium sites (10-100 users): 1000-5000
  • Large sites (100+ users): 5000-10000

Track Browser Info

Default: Enabled Data Collected: User agent string Privacy: Contains browser and OS info (no personal data)

Database Structure

Table Name

wp_login_attempts (with prefix)

Schema

CREATE TABLE wp_login_attempts (
  id bigint(20) NOT NULL AUTO_INCREMENT,
  user_login varchar(60) NOT NULL,
  user_id bigint(20) DEFAULT NULL,
  ip_address varchar(100) NOT NULL,
  user_agent text DEFAULT NULL,
  status varchar(20) NOT NULL,
  timestamp datetime NOT NULL,
  PRIMARY KEY (id),
  KEY user_login (user_login),
  KEY ip_address (ip_address),
  KEY status (status),
  KEY timestamp (timestamp)
);

Indexes

Optimized for common queries:

  • user_login: Search by username
  • ip_address: Search by IP
  • status: Filter by success/failed
  • timestamp: Sort by date, cleanup old logs

WordPress Hooks

Actions

Login Monitoring:

  • wp_login: Logs successful logins (priority 10)
  • wp_login_failed: Logs failed attempts

Admin:

  • plugins_loaded: Load text domain
  • admin_menu: Add admin pages
  • admin_init: Register settings
  • admin_enqueue_scripts: Load CSS/JS

Scheduled:

  • yt_lam_daily_cleanup: Daily log cleanup (wp-cron)

Filters

  • plugin_action_links_{basename}: Add "View Logs" and "Settings" links

AJAX Endpoints

  • yt_lam_delete_log: Delete single log entry
  • yt_lam_clear_logs: Delete all logs
  • yt_lam_export_logs: Export CSV file

Log Data Captured

For All Attempts

  • Username: Login attempted (sanitized)
  • IP Address: User's IP (supports proxies)
  • Timestamp: Date and time (MySQL format)
  • Status: success or failed
  • User Agent: Browser info (if enabled)

For Successful Logins

  • User ID: WordPress user ID
  • Link: Direct link to user profile

For Failed Logins

  • User ID: NULL (user doesn't exist or wrong password)
  • Username: Attempted username (may not exist)

IP Address Detection

The plugin detects IP addresses from multiple sources (in order):

  1. HTTP_CF_CONNECTING_IP (Cloudflare)
  2. HTTP_CLIENT_IP
  3. HTTP_X_FORWARDED_FOR (Proxy)
  4. HTTP_X_FORWARDED
  5. HTTP_X_CLUSTER_CLIENT_IP
  6. HTTP_FORWARDED_FOR
  7. HTTP_FORWARDED
  8. REMOTE_ADDR (Direct)

Fallback: 0.0.0.0 if detection fails

Browser Detection

Simple browser parsing from user agent:

  • Chrome: "Chrome" in user agent
  • Firefox: "Firefox" in user agent
  • Safari: "Safari" in user agent
  • Edge: "Edge" in user agent
  • Opera: "Opera" in user agent
  • Unknown: Anything else

CSV Export Format

Filename: login-attempts-YYYY-MM-DD.csv

Columns:

  1. ID
  2. Username
  3. User ID
  4. IP Address
  5. Status
  6. Browser
  7. Timestamp

Encoding: UTF-8 Delimiter: Comma Headers: Yes (first row)

Admin Interface

Statistics Boxes

  • Total Attempts: All-time count (blue)
  • Successful: Success count (green)
  • Failed: Failed count (red)
  • Today: Today's count (yellow)

Filters & Actions Bar

Left Side:

  • Status filter dropdown
  • Search input (username/IP)
  • Filter button

Right Side:

  • Refresh button
  • Export CSV button
  • Clear All Logs button

Log Table Columns

  1. Time: Relative time + full timestamp
  2. Username: Username + link to user (if exists)
  3. IP Address: Clickable for lookup
  4. Status: Color-coded badge
  5. Browser: Parsed browser name
  6. Actions: Delete button

Pagination

  • 20 logs per page
  • Next/Previous navigation
  • Page numbers
  • Accessible URLs (bookmarkable)

Keyboard Shortcuts

  • Ctrl/Cmd + R: Refresh page
  • Ctrl/Cmd + E: Export CSV
  • Tab: Navigate through interface

Performance

Database Impact

Per Login:

  • 1 INSERT query (~1ms)
  • Index maintained automatically
  • No SELECT queries (unless viewing logs)

Viewing Logs:

  • 1 COUNT query (for pagination)
  • 1 SELECT query (for log entries)
  • Both queries use indexes

Optimization Features

  • Indexed Columns: Fast searches and filters
  • Auto Cleanup: Prevents unlimited growth
  • Max Logs Limit: Hard cap on table size
  • AJAX Operations: No full page reloads
  • Paginated Display: Only load 20 rows at a time

Benchmarks

  • 1000 logs: <100 KB database space
  • 10000 logs: <1 MB database space
  • Log insertion: <1ms per entry
  • Log retrieval: <50ms for 20 entries
  • CSV export: ~1 second for 10000 logs

Security Features

Data Security

  • Nonce Verification: All AJAX requests
  • Capability Checks: manage_options required
  • Input Sanitization:
    • sanitize_user() for usernames
    • sanitize_text_field() for general input
    • absint() for IDs
    • filter_var() for IP validation
  • Output Escaping:
    • esc_html() for text
    • esc_attr() for attributes
    • esc_url() for URLs
  • SQL Injection Prevention: Prepared statements only
  • XSS Prevention: All output escaped

Privacy Considerations

Data Collected:

  • Usernames (public information)
  • IP addresses (potentially personal)
  • User agents (device/browser info)
  • Timestamps

GDPR Compliance:

  • IP addresses are personal data
  • User agents may contain identifying info
  • Consider adding to privacy policy
  • Respect retention limits
  • Provide data export (CSV)

Best Practices:

  • Set reasonable retention period (30-90 days)
  • Document in privacy policy
  • Don't share data with third parties
  • Disable browser tracking if not needed

Use Cases

Security Monitoring

Scenario: Detect brute force attacks How: Monitor failed attempts from same IP Action: Review logs daily, block suspicious IPs

User Activity Audit

Scenario: Track employee logins How: Filter by specific usernames Action: Generate weekly reports via CSV export

Compliance Requirements

Scenario: Maintain 90-day audit trail How: Set retention to 90 days Action: Export logs monthly for archival

Troubleshooting Access Issues

Scenario: User can't login How: Search for username in logs Action: Check for failed attempts, identify issue

Site Migration Verification

Scenario: Verify all admins can access new site How: Review successful logins post-migration Action: Confirm all users logged in successfully

Frequently Asked Questions

How long are logs kept?

Logs are kept based on your retention setting (default: 30 days). You can change this in Settings → Login Monitor.

Can I prevent the database from growing too large?

Yes, set a maximum log limit (default: 1000). When the limit is reached, oldest logs are automatically deleted.

Does this slow down my site?

No. The plugin only runs during login attempts and when viewing the admin page. Normal page loads are not affected.

Can I see which country users are from?

The plugin records IP addresses. Click an IP to look it up on an external service that provides geolocation.

Is this GDPR compliant?

The plugin can be GDPR compliant if configured properly:

  • Set reasonable retention period
  • Document in privacy policy
  • Provide data export option (CSV)
  • Consider disabling user agent tracking

Can I track custom post type logins?

This plugin tracks WordPress user logins only. It doesn't track custom authentication systems.

What if someone changes their IP?

Each login attempt is logged separately with its IP at that time. Users with dynamic IPs will show different IPs for different logins.

Can I block IPs with failed attempts?

This plugin logs attempts but doesn't block IPs. Consider using a security plugin like Wordfence for IP blocking.

Does it work with two-factor authentication?

Yes, it logs attempts before 2FA. If 2FA fails, the attempt is logged as successful (password was correct).

Can I customize the CSV export?

Not currently, but you can modify the ajax_export_logs() method to add/remove columns.

Troubleshooting

Logs not recording

  1. Check Settings → Login Monitor
  2. Ensure "Log successful" and "Log failed" are checked
  3. Test a login (correct and wrong password)
  4. Check Users → Login Log

Database table not created

  1. Deactivate and reactivate the plugin
  2. Check file permissions on plugin folder
  3. Verify database user has CREATE TABLE permission
  4. Check WordPress debug log for errors

CSV export not working

  1. Check browser popup blocker
  2. Verify you have manage_options capability
  3. Check PHP memory limit (increase if needed)
  4. Try exporting smaller date range

Old logs not cleaning up

  1. Verify wp-cron is working: wp cron event list
  2. Check retention days setting
  3. Manually trigger: wp cron event run yt_lam_daily_cleanup
  4. Check WordPress debug log for errors

Statistics not accurate

  1. Statistics are real-time from database
  2. Clear all logs and test fresh
  3. Check for database corruption: REPAIR TABLE wp_login_attempts
  4. Review retention and max log settings

Uninstallation

When you delete the plugin through WordPress:

  1. Database table dropped: wp_login_attempts removed
  2. Options deleted: All plugin settings removed
  3. Scheduled events: wp-cron cleanup job removed
  4. Cache cleared: WordPress cache flushed
  5. No data remains: Complete cleanup

Note: Deactivation keeps data. Only deletion removes everything.

Changelog

1.0.0 (2025-01-XX)

  • Initial release
  • Login attempt logging (success and failed)
  • Custom database table with indexes
  • Admin interface with statistics
  • Advanced filtering and search
  • CSV export functionality
  • Clear all logs feature
  • Auto cleanup based on retention
  • Maximum log limit enforcement
  • IP address detection
  • Browser detection
  • Settings page
  • AJAX operations
  • Responsive design
  • Keyboard shortcuts
  • Translation ready

Developer Notes

Line Count

  • PHP: 988 lines
  • CSS: ~370 lines
  • JS: ~430 lines
  • Total: ~1,788 lines

Extending the Plugin

Custom Log Processing

add_action('yt_lam_after_log', function($log_data) {
    // Send email alert for failed logins
    if ($log_data['status'] === 'failed') {
        wp_mail(
            get_option('admin_email'),
            'Failed Login Attempt',
            'IP: ' . $log_data['ip_address']
        );
    }
}, 10, 1);

Custom Cleanup Logic

add_action('yt_lam_before_cleanup', function() {
    // Custom pre-cleanup tasks
    error_log('Cleaning up old login logs');
});

Modify Retention Period

add_filter('yt_lam_retention_days', function($days) {
    return 60; // Override to 60 days
});

Database Queries

All queries use prepared statements:

// Safe query example
$wpdb->prepare(
    "SELECT * FROM {$table_name} WHERE user_login = %s AND ip_address = %s",
    $username,
    $ip_address
);

Contributing

Follow WordPress Coding Standards:

phpcs --standard=WordPress yt-login-attempt-monitor.php

Support

For issues, questions, or feature requests:

License

GPL v2 or later

Author

Krasen Slavov


Monitor your WordPress login activity with confidence!