{"id":324447,"date":"2026-06-15T07:58:50","date_gmt":"2026-06-15T07:58:50","guid":{"rendered":"https:\/\/pl.wordpress.org\/plugins\/beziworld-activity-log\/"},"modified":"2026-06-15T07:58:20","modified_gmt":"2026-06-15T07:58:20","slug":"beziworld-activity-log","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/beziworld-activity-log\/","author":23394266,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.5.1","stable_tag":"0.5.1","tested":"7.0","requires":"6.4","requires_php":"7.4","requires_plugins":null,"header_name":"BeziWorld Activity Log","header_author":"Kamil \u0106wiertnia","header_description":"Advanced, fast and secure user-activity log with a tamper-evident audit trail. Records logins, account and content changes in an indexed custom table with per-row HMAC integrity, a clean event viewer, configurable retention and granular event and exclusion controls.","assets_banners_color":"486c95","last_updated":"2026-06-15 07:58:20","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/beziworld.eu\/plugins\/activity-log","header_author_uri":"https:\/\/beziworld.eu","rating":0,"author_block_rating":0,"active_installs":0,"downloads":27,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"0.5.1":{"tag":"0.5.1","author":"beziworld","date":"2026-06-15 07:58:20"}},"upgrade_notice":{"0.5.1":"<p>Security and coding-standards hardening for the WordPress.org Plugin Directory. No functional or behavioural changes.<\/p>","0.5.0":"<p>Major feature release: notifications, reports, statistics, session management, integrity checkpoints, export, REST\/GraphQL and integrations.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3572574,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3572574,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3572574,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3572574,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["0.5.1"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3572574,"resolution":"1","location":"assets","locale":"","width":1240,"height":900},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3572574,"resolution":"2","location":"assets","locale":"","width":1240,"height":900},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3572574,"resolution":"3","location":"assets","locale":"","width":1240,"height":900},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3572574,"resolution":"4","location":"assets","locale":"","width":1240,"height":900},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3572574,"resolution":"5","location":"assets","locale":"","width":1240,"height":900}},"screenshots":{"1":"The activity log viewer \u2014 severity badges, filters, search and expandable detail rows.","2":"Statistics \u2014 headline figures, a daily-volume chart and a per-category breakdown.","3":"Settings \u2014 enable or disable individual events and override their severity.","4":"Notifications and anomaly detection \u2014 Slack, Discord, Telegram, email and webhook, with bulk-action and off-hours alerts.","5":"Users online \u2014 who currently holds a session, with their most recent action, time and IP."}},"plugin_section":[262246],"plugin_tags":[8531,8534,49509,600,8543],"plugin_category":[54],"plugin_contributors":[265339],"plugin_business_model":[],"class_list":["post-324447","plugin","type-plugin","status-publish","hentry","plugin_section-dashboard-widgets","plugin_tags-activity-log","plugin_tags-audit-log","plugin_tags-audit-trail","plugin_tags-security","plugin_tags-user-tracking","plugin_category-security-and-spam-protection","plugin_contributors-beziworld","plugin_committers-beziworld"],"banners":{"banner":"https:\/\/ps.w.org\/beziworld-activity-log\/assets\/banner-772x250.png?rev=3572574","banner_2x":"https:\/\/ps.w.org\/beziworld-activity-log\/assets\/banner-1544x500.png?rev=3572574","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/beziworld-activity-log\/assets\/icon-128x128.png?rev=3572574","icon_2x":"https:\/\/ps.w.org\/beziworld-activity-log\/assets\/icon-256x256.png?rev=3572574","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/beziworld-activity-log\/assets\/screenshot-1.png?rev=3572574","caption":"The activity log viewer \u2014 severity badges, filters, search and expandable detail rows."},{"src":"https:\/\/ps.w.org\/beziworld-activity-log\/assets\/screenshot-2.png?rev=3572574","caption":"Statistics \u2014 headline figures, a daily-volume chart and a per-category breakdown."},{"src":"https:\/\/ps.w.org\/beziworld-activity-log\/assets\/screenshot-3.png?rev=3572574","caption":"Settings \u2014 enable or disable individual events and override their severity."},{"src":"https:\/\/ps.w.org\/beziworld-activity-log\/assets\/screenshot-4.png?rev=3572574","caption":"Notifications and anomaly detection \u2014 Slack, Discord, Telegram, email and webhook, with bulk-action and off-hours alerts."},{"src":"https:\/\/ps.w.org\/beziworld-activity-log\/assets\/screenshot-5.png?rev=3572574","caption":"Users online \u2014 who currently holds a session, with their most recent action, time and IP."}],"raw_content":"<!--section=description-->\n<p>BeziWorld Activity Log records what users do on your WordPress site: who logged in, who failed to log in, who changed a role, who edited their profile, who created or edited content, and more. The focus is user activity, and the goal is to make the capabilities competing plugins reserve for paid upgrades available for free.<\/p>\n\n<p><strong>Designed for performance.<\/strong> Events are stored in a dedicated, indexed custom table (never in wp_posts), written in batches to keep request overhead low, while security-relevant events are persisted immediately. Retention pruning keeps the table lean automatically.<\/p>\n\n<p><strong>Designed for trust.<\/strong> Each event is signed with a per-site HMAC and sealed into a hash-chained sequence of checkpoints, making after-the-fact tampering \u2014 including row insertion or deletion \u2014 detectable. Because an attacker with full server access could recompute local signatures, the latest checkpoint signature can be anchored off-host (emailed or sent to a webhook) so the integrity proof leaves the machine.<\/p>\n\n<p><strong>Designed for privacy.<\/strong> IP logging is optional and can be anonymised at capture time. The plugin never phones home and never loads code from external servers.<\/p>\n\n<h4>Highlights<\/h4>\n\n<ul>\n<li>Authentication and account activity: logins, logouts, failed logins (rate-limited to prevent log flooding), registration, role changes, profile and user-metadata changes, password resets, application passwords, user deletion.<\/li>\n<li>Content activity: posts, pages and custom post types created, updated (with a field-level diff), status changes, trashing, restoring and permanent deletion; comments, media and taxonomy terms.<\/li>\n<li>Clean, readable event viewer with severity badges, expandable detail rows, sorting, filtering and full-text search.<\/li>\n<li>Granular configuration: enable or disable whole event groups or individual events.<\/li>\n<li>Exclusion rules by IP\/CIDR, user login, user ID, role and request path.<\/li>\n<li>Plugin\/theme and settings changes, navigation menus, and the GDPR personal-data request lifecycle.<\/li>\n<li>Optional integrations: WooCommerce (orders, status changes, stock) and Yoast SEO (metadata and settings).<\/li>\n<li>Real-time notifications \u2014 Slack, Discord, Telegram, email and generic webhook \u2014 by urgency or chosen event codes, delivered immediately or as an hourly digest. Free.<\/li>\n<li>Optional login geolocation (via a provider you wire) with an automatic alert on a login from a new country.<\/li>\n<li>Scheduled HTML summary reports emailed to the administrator (daily or weekly).<\/li>\n<li>Statistics screen with daily-volume chart and category, user and event breakdowns.<\/li>\n<li>Active session management: see who is logged in and terminate sessions. Free.<\/li>\n<li>Tamper-evident integrity: per-row HMAC plus a hash-chained checkpoint sequence with optional off-host anchoring (email\/webhook), verifiable with WP-CLI (<code>wp bzal verify-integrity<\/code>).<\/li>\n<li>Real-time notifications also fire on a chosen set of event codes, regardless of urgency.<\/li>\n<li>Configurable severity per event code, driving notifications and the security badge.<\/li>\n<li>Optional anomaly detection: flags a rapid bulk-delete burst by one user and off-hours admin logins as high-severity alerts.<\/li>\n<li>Admin-bar quick view: the latest events and a 24-hour security badge on every screen.<\/li>\n<li>\"Users online\" view: who currently holds a session, with their most recent action, time and IP.<\/li>\n<li>CSV and JSON export of the filtered log, with spreadsheet-formula-injection protection.<\/li>\n<li>Read access via the REST API (offset and cursor pagination, plus an integrity-anchor endpoint) and optionally GraphQL, gated by capability.<\/li>\n<li>Granular configuration: enable\/disable whole event groups or individual events; exclusion rules by IP\/CIDR, user, role and path.<\/li>\n<li>Configurable retention with on-demand cleanup; UTC storage with display in your chosen timezone.<\/li>\n<li>Fully translatable, with bundled Polish, German and Czech translations.<\/li>\n<\/ul>\n\n<h3>External services<\/h3>\n\n<p>This plugin works fully offline. It does not connect to any external service on its own. The following optional integrations are disabled by default and only ever contact a destination that you enter in the settings; each transmits a short summary of a logged event (such as the event description, the acting user's login, the time, and \u2014 when IP logging is enabled \u2014 the IP address) at the moment the event occurs or, in digest mode, once per hour.<\/p>\n\n<ul>\n<li><strong>Slack<\/strong> \u2014 when you enter a Slack Incoming Webhook URL, matching events are POSTed to that webhook. See the Slack Terms of Service (https:\/\/slack.com\/terms-of-service) and Privacy Policy (https:\/\/slack.com\/trust\/privacy\/privacy-policy).<\/li>\n<li><strong>Discord<\/strong> \u2014 when you enter a Discord webhook URL, matching events are POSTed to that webhook. See the Discord Terms (https:\/\/discord.com\/terms) and Privacy Policy (https:\/\/discord.com\/privacy).<\/li>\n<li><strong>Telegram<\/strong> \u2014 when you enter a Telegram bot token and chat ID, matching events are sent through the Telegram Bot API at api.telegram.org. See the Telegram Terms (https:\/\/telegram.org\/tos) and Privacy Policy (https:\/\/telegram.org\/privacy).<\/li>\n<li><strong>Generic webhook<\/strong> \u2014 when you enter a custom webhook URL (for notifications or for off-host integrity anchoring), the corresponding payload is POSTed to that URL. The destination is yours; review its provider's terms and privacy policy.<\/li>\n<li><strong>Login geolocation<\/strong> \u2014 disabled unless you both enable it and wire a provider through the <code>bzal_geolocate_country<\/code> filter. The plugin bundles no geolocation provider and makes no geolocation request by itself; any lookup is performed by the provider you supply, under that provider's terms.<\/li>\n<\/ul>\n\n<p>Summary reports and notification emails are delivered through your site's own WordPress mail system to the recipients you configure; they are not sent to any third party by this plugin.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>beziworld-activity-log<\/code> folder to <code>\/wp-content\/plugins\/<\/code>.<\/li>\n<li>Activate the plugin through the <em>Plugins<\/em> screen in WordPress.<\/li>\n<li>Open <em>Activity Log<\/em> in the admin menu to review events, and <em>Activity Log \u2192 Settings<\/em> to configure retention, events and exclusions.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"where%20are%20events%20stored%3F\"><h3>Where are events stored?<\/h3><\/dt>\n<dd><p>In dedicated custom database tables created on activation, not in the WordPress posts table, so your content queries are never affected.<\/p><\/dd>\n<dt id=\"will%20it%20slow%20down%20my%20site%3F\"><h3>Will it slow down my site?<\/h3><\/dt>\n<dd><p>Non-critical events are buffered and written in a single batched query on shutdown; security events are written immediately. Indexed columns keep the viewer responsive even on large logs.<\/p><\/dd>\n<dt id=\"does%20the%20plugin%20detect%20changes%20made%20directly%20in%20the%20database%3F\"><h3>Does the plugin detect changes made directly in the database?<\/h3><\/dt>\n<dd><p>No. Like every hook-based activity logger, it records actions that flow through WordPress. Direct SQL modifications bypass WordPress hooks and cannot be observed.<\/p><\/dd>\n<dt id=\"does%20it%20send%20my%20data%20anywhere%3F\"><h3>Does it send my data anywhere?<\/h3><\/dt>\n<dd><p>No. There is no tracking or telemetry, and the plugin never loads code from external servers. The only outbound requests are the optional integrations described under \"External services\" below \u2014 every one is off by default and is sent only to an endpoint you configure yourself.<\/p><\/dd>\n<dt id=\"does%20it%20provide%20wp-cli%20commands%3F\"><h3>Does it provide WP-CLI commands?<\/h3><\/dt>\n<dd><p>Yes:<\/p>\n\n<ul>\n<li><code>wp bzal verify-integrity<\/code> \u2014 verify the per-row signatures and the checkpoint chain, reporting any detected tampering.<\/li>\n<li><code>wp bzal checkpoint<\/code> \u2014 seal a new integrity checkpoint immediately.<\/li>\n<li><code>wp bzal purge<\/code> \u2014 apply the retention policy now.<\/li>\n<li><code>wp bzal stats<\/code> \u2014 print the number of recorded events for the current site.<\/li>\n<\/ul><\/dd>\n<dt id=\"can%20developers%20extend%20it%3F\"><h3>Can developers extend it?<\/h3><\/dt>\n<dd><p>Yes. The plugin exposes hooks for integration:<\/p>\n\n<ul>\n<li><code>do_action( 'bzal_event_logged', array $columns )<\/code> \u2014 fires after each event is stored; receives the event's column map, for forwarding to your own systems.<\/li>\n<li><code>apply_filters( 'bzal_geolocate_country', string $country, string $ip )<\/code> \u2014 return an ISO country code for an IP to power optional login geolocation (no provider is bundled).<\/li>\n<li><code>apply_filters( 'bzal_user_meta_denied', bool $denied, string $meta_key )<\/code> \u2014 return true to keep a specific user-meta key out of the log.<\/li>\n<li><code>do_action( 'bzal_plugin_booted' )<\/code> \u2014 fires once the plugin has finished booting, for registering your own extensions.<\/li>\n<\/ul><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>0.5.1<\/h4>\n\n<ul>\n<li>Hardening: settings inputs are now unslashed and sanitised at the point of access rather than across helper boundaries, satisfying Plugin Check static analysis.<\/li>\n<li>Removed the redundant <code>load_plugin_textdomain()<\/code> call; bundled Polish, German and Czech translations load through WordPress just-in-time loading (the <code>Text Domain<\/code> and <code>Domain Path<\/code> headers are declared).<\/li>\n<\/ul>\n\n<h4>0.5.0<\/h4>\n\n<ul>\n<li>Content, comment, media, taxonomy, menu, plugin\/theme, settings, GDPR-request and user-metadata sensors.<\/li>\n<li>WooCommerce and Yoast SEO integrations (loaded only when active).<\/li>\n<li>Real-time notifications: Slack, Discord, Telegram, email, generic webhook \u2014 by urgency or per chosen event codes; immediate or hourly digest.<\/li>\n<li>Optional login geolocation with a login-from-new-country alert.<\/li>\n<li>Scheduled HTML summary reports; statistics screen with charts; admin-bar quick view with a security badge.<\/li>\n<li>Active session management; CSV\/JSON export with formula-injection protection.<\/li>\n<li>Hash-chained integrity checkpoints with optional off-host anchoring and <code>wp bzal verify-integrity<\/code>; per-site partitioned on multisite networks.<\/li>\n<li>REST (offset + cursor pagination + integrity-anchor endpoint) and optional GraphQL read access; advanced filters; dashboard widget; same-request event correlation.<\/li>\n<li>Per-site partitioned integrity chain on multisite; optional full-text indexing of the event-data payload.<\/li>\n<li>Configurable per-event severity and optional behavioural anomaly detection (bulk-delete burst, off-hours admin login).<\/li>\n<li>Fast full-text search (MySQL FULLTEXT) across event object, user and message columns, with a LIKE fallback and an optional mode that also indexes the event-data payload.<\/li>\n<\/ul>\n\n<h4>0.1.0<\/h4>\n\n<ul>\n<li>Initial release: custom-table storage, per-row HMAC integrity, authentication\/account sensor, event viewer, configurable retention with on-demand cleanup, event toggles and exclusion rules.<\/li>\n<\/ul>","raw_excerpt":"Advanced, fast and secure user-activity log with a tamper-evident audit trail. Every feature free \u2014 no paid tiers.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/324447","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=324447"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/beziworld"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=324447"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=324447"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=324447"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=324447"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=324447"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=324447"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}