WP Manifestindependent plugin directory
manifest / developer / logger

Alley Logger WP Registry grade B. Medium-severity findings · 1 findingWP RegistryMedium-severity findings · 1 findingOpen the reportB

A Monolog-based logging tool for WordPress. Supports storing log message in a custom post type or in individual posts and terms.

★ 30stars
515kcomposer installs
v2.6.4latest · 8mo ago

Install

Download source zip No release zip yet

This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/alleyinteractive/logger/archive/refs/heads/develop.zip

On Packagist as alleyinteractive/logger:

composer require alleyinteractive/logger
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

Providing a WordPress integration with Monolog, allowing site-wide and post and term specific logging.

Screenshot of Example Log

Documentation

See the wiki for complete information and more examples.

Installation

Logger requires PHP 8.2 and Composer to run properly.

composer require alleyinteractive/logger

You can also install the plugin as a submodule by using the *-built tag of a release.

Usage

AI Logger is a complete interface to Monolog with some nice WordPress handlers built in.

// Log site-wide to the ai_log post type.
ai_logger()->info( 'Log message...' );

\AI_Logger\AI_Logger::info( 'Another format for logging.' );

Logging to a Specific Post

Logs will be appended to a post's meta for review.

ai_logger_to_post( $post_id, 'meta-key' )->info( 'This will log to the <meta-key> for a specific post.' );

Logging to a Specific Term

Logs will be appended to a term's meta for review.

ai_logger_to_term( $term_id, 'meta-key' )->info( 'This will log to the <meta-key> for a specific term.' );

Logging to Query Monitor

ai_logger_to_qm()->info( 'This will show up in Query Monitor!' );

Logging with Default Context

ai_logger()->with_context( 'example-context' )->info( 'This will log to the example-context.' );

Also supports an array of default log context:

ai_logger()->with_context(
    [
        'context' => 'example-context',
        'key'     => 'value',
    ]
)->info( 'This will log to the example-context with key=>value.' );

You can also pass the context to ai_logger() directly:

ai_logger( 'example-context' )->info( 'This will log to the example-context.' );

Changelog

Please see CHANGELOG for more information on what has changed recently.

Maintainers

This project is actively maintained by Alley Interactive. Like what you see? Come work with us.

Alley logo

License

This software is released under the terms of the GNU General Public License version 2 or any later version.

Releases

Newest 25 of 27 recorded releases.

Tag
Published
v2.6.4 latest
Feb 11, 2026 8mo ago
Sep 26, 2025 1 year ago
Sep 12, 2025 1 year ago
Apr 22, 2025 1 year ago
Apr 21, 2025 1 year ago
Dec 20, 2024 1 year ago
Sep 4, 2024 2 years ago
Aug 26, 2024 2 years ago
Jul 2, 2024 2 years ago
Jun 28, 2024 2 years ago
Apr 30, 2024 2 years ago
Apr 30, 2024 2 years ago
Jan 18, 2024 2 years ago
Mar 20, 2023 3 years ago
Mar 20, 2023 3 years ago
Dec 19, 2022 3 years ago
Sep 2, 2022 4 years ago
May 27, 2022 4 years ago
Apr 8, 2022 4 years ago
Apr 8, 2022 4 years ago
Mar 30, 2022 4 years ago
Mar 24, 2022 4 years ago
Feb 15, 2022 4 years ago
Jan 14, 2021 5 years ago
Jan 11, 2021 5 years ago
All releases on GitHub →

These releases are tags only. The author does not attach a packaged zip, so there are no download counts to report.

B grade

Security

Alley Logger 2.6.4 · audited by WP Registry

Medium-severity findings.

1 medium
Audited release
2.6.4
Findings
1
Worst severity
medium
Content hash
28fa087bf018f7a6029d2617…

Findings

  • medium Unauthenticated stored XSS via JS logger args and unescaped admin JSON

    xss_stored

    JavaScript logging is off by default (apply_filters('ai_logger_enable_js_logging', false)). When a site enables it, AI_Logger_JS registers wp_ajax_ and wp_ajax_nopriv_ ai_logger_insert and localizes a nonce on every front-end, admin, and login request. log() runs sanitize_text_field over POST args into $clean_args, then ignores that array: $level comes from the raw decoded JSON and $logger->$level($message, $args) persists the unsanitized structure (WordPress sanitize_text_field returns '' for arrays, so nested objects survive). method_exists() is used instead of a PSR-level allowlist, so level=error/alert is accepted and production Post_Handler will insert (info/debug are filtered out unless WP_DEBUG). Data_Structures renders _logger_record in wp-admin; ai_logger_render_table() esc_html's scalars but echo's wp_json_encode() for arrays/objects with no HTML encoding, which is a script-executing sink in a <pre>. An unauthenticated visitor POSTs a unique error-level message with nested context such as {"level":"error","evil":{"x":"</pre><script>alert(1)</script>"}}; an administrator with create_users who opens Logs → that entry executes the script in wp-admin. The same unescaped json_encode is used in template-parts/object-log-display.php for post/term log meta boxes.

    inc/class-ai-logger-js.php:22-90

    Recommendation

    Log recursively sanitized $clean_args (or wp_kses/sanitize_text_field walking nested arrays), not the raw JSON. Whitelist PSR-3 levels instead of method_exists() + dynamic $logger->$level(). Escape JSON in log-display.php and object-log-display.php with esc_html() or wp_json_encode(..., JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS|JSON_HEX_QUOT). Keep JS logging off by default; if it stays public, rate-limit inserts and do not allow ALERT+ from unauthenticated callers.

WP Registry hashes the installable build and reports on that exact bytes-for-bytes copy. Embargoed findings are withheld until they are disclosed, so a clean verdict means nothing public is outstanding. WP Manifest does not audit code itself.