WordPress User Activity Monitor
Lightweight, privacy-conscious user login and activity monitoring optimized for high-traffic WordPress sites.
by Amirreza Shayesteh Far · github.com/amirrezashf/wordpress-user-activity-monitor · website
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/amirrezashf/wordpress-user-activity-monitor/archive/refs/heads/main.zipReadme
WordPress User Activity Monitor
A lightweight, privacy-conscious WordPress plugin for tracking successful logins and coarse logged-in browser activity without using user_meta for analytical reporting.
GitHub Description: Lightweight, privacy-conscious user login and activity monitoring optimized for high-traffic WordPress sites.
Features
- One indexed custom-table row per user.
- Records last successful login, last browser activity, login count, and coarse device/browser categories.
- Does not store IP addresses or raw User-Agent strings.
- Browser-side activity throttle reduces database writes on frequently viewed pages.
- Indexed
last_loginandlast_activitycolumns for efficient filtering/statistics. - Adds Activity and Logins columns to Users → All Users.
- Sort users by last activity or login count.
- Filter users by online, active today, or never logged in.
- Cached WordPress Dashboard summary.
- Removes orphaned activity rows when users are deleted.
- Automatically imports compatible rows from the legacy
codecloude_user_activitytable when upgrading from the supplied WPCode snippet. - Localization-ready with the
wordpress-user-activity-monitortext domain.
Requirements
- WordPress 6.0 or newer
- PHP 7.4 or newer
- MySQL/MariaDB supported by the installed WordPress version
WooCommerce is not required.
Installation
- Download
WordPress-User-Activity-Monitor.zip. - In WordPress, open Plugins → Add New Plugin → Upload Plugin.
- Upload the ZIP and activate it.
- Visit Users → All Users to see activity information.
- The Dashboard also receives a compact User Activity widget for users with the
list_userscapability.
Usage
No configuration screen is required. After activation, successful logins are recorded automatically. Normal logged-in page loads update last_activity, subject to the activity throttle.
The activity cookie is named wpuam_ping_<USER_ID>. It only stores the timestamp before which another browser activity write can be skipped. It is a performance optimization, not a security mechanism.
Background cron, WP-CLI, REST, and AJAX requests are not treated as browser activity.
How It Works
The plugin creates one row per user in:
{$wpdb->prefix}wpuam_user_activity
Schema:
| Column | Purpose |
|---|---|
user_id |
Primary key / WordPress user ID |
last_login |
Unix timestamp of last successful login |
last_activity |
Unix timestamp of last tracked browser activity |
login_count |
Number of successful logins recorded by the plugin |
device |
Coarse device/platform category |
browser |
Coarse browser category |
Indexes are created on last_login and last_activity.
Settings and Filters
There is intentionally no settings page. Timing values can be adjusted with filters:
add_filter( 'wpuam_online_window_seconds', function () {
return 15 * MINUTE_IN_SECONDS;
} );
add_filter( 'wpuam_activity_throttle_seconds', function () {
return 15 * MINUTE_IN_SECONDS;
} );
add_filter( 'wpuam_stats_cache_ttl_seconds', function () {
return 10 * MINUTE_IN_SECONDS;
} );
Minimum accepted value for each filter is one minute.
Storage Architecture
A dedicated table is used instead of user_meta because the feature performs analytical filtering, sorting, and aggregate counts. One row per user avoids unbounded event-history growth.
Activity timestamps are Unix timestamps. Human-readable dates are rendered using the site's configured WordPress timezone.
The plugin intentionally preserves its table and data on deactivation/uninstall. This avoids destructive data loss. Remove the table manually only when you explicitly intend to erase the activity history.
Security
- No public AJAX or REST endpoints are exposed.
- Admin data is shown only to users who have the
list_userscapability. - Request filter values are sanitized and allow-listed.
- Dynamic SQL values use
$wpdb->prepare(). - Custom table identifiers are derived only from trusted WordPress database prefixes and plugin constants.
- Raw User-Agent values are not persisted.
- The activity cookie is not trusted for authorization or data-integrity decisions.
Privacy
Stored data is limited to:
- WordPress user ID
- login/activity timestamps
- login count
- coarse device category
- coarse browser category
The plugin does not store IP addresses, raw User-Agent strings, email addresses, names, or arbitrary request payloads in its activity table.
Site owners remain responsible for disclosing activity monitoring where required by their privacy policy or applicable law and for defining suitable retention practices.
Performance Notes
- Activity writes are normally limited to one write per logged-in browser per throttle window.
- Login updates use an atomic
INSERT ... ON DUPLICATE KEY UPDATEquery. - The Users screen tries to load visible activity rows in a single batched query to avoid N+1 reads.
- Filtering/sorting uses indexed custom-table fields instead of
meta_query. - Dashboard statistics are cached with a bounded TTL.
- Activity writes deliberately do not invalidate dashboard cache, preventing cache churn and stampedes on high-traffic sites.
A user can delete/manipulate the performance cookie and therefore cause more activity writes from their own browser. This does not provide additional privileges or alter another user's data.
Legacy Migration
On activation/schema upgrade, the plugin checks for the old table:
{$wpdb->prefix}codecloude_user_activity
If present, compatible rows are copied into the new table. Existing new-table rows retain the newest known timestamps and greatest known login count. The legacy table and option are not deleted, so migration is non-destructive.
The old branding/storage name appears only for backward-compatible migration and is not used as current plugin branding.
Multisite Limitation
Activity storage is site-prefix based. The standard per-site Users screen is supported. Network Admin user reporting is intentionally not modified in version 1.0.0 because network-wide aggregation requires separate cross-site storage/reporting semantics.
Other Limitations
- “Online” is an approximation based on the most recently recorded browser activity, not a live socket/session presence signal.
- Activity tracking excludes REST, AJAX, cron, and WP-CLI requests by design.
- Device/browser detection is intentionally coarse and may report
Unknownfor uncommon clients. - Existing historical logins from before this plugin (or its compatible legacy snippet) cannot be reconstructed accurately.
- The browser throttle reduces writes but is not a server-enforced rate limit.
License
GPL-3.0
Author
Amirreza Shayesteh Far
GitHub: https://github.com/amirrezashf
Repository: https://github.com/amirrezashf/WordPress-User-Activity-Monitor
مانیتور فعالیت کاربران وردپرس
این افزونه برای ثبت سبک و بهینهی آخرین ورود و آخرین فعالیت کاربران لاگینشده طراحی شده و برای گزارشگیری سنگین از user_meta استفاده نمیکند.
امکانات
- فقط یک ردیف ایندکسشده برای هر کاربر در جدول اختصاصی.
- ثبت آخرین ورود موفق، آخرین Activity، تعداد ورودها و دستهبندی ساده Device/Browser.
- عدم ذخیره IP و User-Agent خام.
- Throttle سمت مرورگر برای کاهش Writeهای دیتابیس.
- ستونهای Activity و Logins در Users → All Users.
- مرتبسازی بر اساس آخرین Activity یا تعداد ورود.
- فیلتر کاربران آنلاین، فعال امروز و بدون سابقه ورود.
- ویجت خلاصه آمار در Dashboard با Cache زماندار.
- حذف ردیف Activity هنگام حذف کاربر.
- Migration غیرمخرب از جدول قدیمی
codecloude_user_activityدر صورت وجود.
نیازمندیها
- WordPress 6.0+
- PHP 7.4+
- MySQL/MariaDB سازگار با نسخه WordPress نصبشده
WooCommerce برای این افزونه لازم نیست.
نصب و استفاده
ZIP افزونه را از Plugins → Add New Plugin → Upload Plugin نصب و فعال کنید. پس از فعالسازی، اطلاعات Activity در صفحه کاربران نمایش داده میشود و Dashboard نیز یک ویجت خلاصه دریافت میکند.
تنظیمات گرافیکی جداگانهای وجود ندارد. سه Filter زیر برای تغییر زمانها در دسترساند:
wpuam_online_window_secondswpuam_activity_throttle_secondswpuam_stats_cache_ttl_seconds
حداقل مقدار هرکدام یک دقیقه است.
ساختار ذخیرهسازی و Performance
جدول اصلی:
{$wpdb->prefix}wpuam_user_activity
هر کاربر فقط یک Row دارد. last_login و last_activity ایندکس هستند. Queryهای صفحه Users بهصورت batch انجام میشوند و Dashboard از transient cache استفاده میکند.
برخلاف snippet اولیه، ثبت Activity باعث پاکشدن مداوم cache داشبورد نمیشود؛ آمار بر اساس TTL تازه میشود تا روی سایتهای پرترافیک cache churn ایجاد نشود.
امنیت و Privacy
هیچ REST/AJAX عمومی اضافه نشده است. نمایش اطلاعات مدیریتی نیازمند capability list_users است. ورودی Filterها sanitize و allow-list میشوند و مقادیر SQL پویا با $wpdb->prepare() ارسال میشوند.
در جدول Activity فقط User ID، timestampها، تعداد ورود و دستهبندی ساده Device/Browser ذخیره میشود. IP، User-Agent خام، نام، ایمیل و payload درخواست ذخیره نمیشوند.
Cookie افزونه فقط برای Performance است و هیچ تصمیم امنیتی بر اساس آن گرفته نمیشود.
Migration داده قدیمی
اگر جدول زیر از snippet قبلی وجود داشته باشد:
{$wpdb->prefix}codecloude_user_activity
اطلاعات سازگار به جدول جدید منتقل میشوند. جدول قدیمی حذف نمیشود و migration غیرمخرب است.
محدودیتها
- وضعیت Online تقریبی است و بر اساس آخرین Activity ثبتشده محاسبه میشود.
- REST، AJAX، cron و WP-CLI Activity محسوب نمیشوند.
- تشخیص Browser/Device عمداً ساده است.
- تاریخچه قبل از نصب افزونه، اگر در جدول legacy موجود نباشد، قابل بازسازی دقیق نیست.
- Network Admin در Multisite در نسخه 1.0.0 گزارشگیری cross-site ندارد.
- حذف یا دستکاری Cookie توسط کاربر میتواند تعداد Writeهای مرورگر خودش را بیشتر کند، اما دسترسی امنیتی ایجاد نمیکند.
مجوز و نویسنده
License: GPL-3.0
Author: Amirreza Shayesteh Far
GitHub: https://github.com/amirrezashf