0 Day Analytics – Error Log Module Developer Documentation
Table of Contents
1. Overview & Architecture
The Error Log Viewer is the primary module of the Advanced Analytics plugin. It reads the PHP error log file in reverse order (newest first), parses each entry into structured data, and renders them in a WordPress WP_List_Table at wp-admin/admin.php?page=advan_logs.
Key Capabilities
- Reverse-reading of the PHP error log with memory and time safety limits
- Regex-based parsing of log lines into structured entries with severity, timestamp, source, and stack traces
- Severity-based colour-coded filtering with per-type toggle and single-severity mode
- Text search across messages and stack traces
- Plugin/theme source detection by matching error file paths to installed plugins and themes
- Source code viewing in a modal with syntax highlighting (SyntaxHighlighter library)
- CSV export with batched processing and progress tracking
- Log file download with HTTP Range support for resumable downloads
- Log truncation (full clear or keep last N records) with scheduled cron-based auto-truncation
- Admin bar live notifications via REST API
- Browser push notifications with configurable polling interval
- New error tracking via transients with menu badge count
Technology Stack
- PHP 7.4+ (strict types)
- WordPress
WP_List_TableAPI - WordPress REST API (namespace
0-day/v1) - WordPress AJAX API
- SyntaxHighlighter for source code viewing
- Browser Notification API for push notifications
- Web Share API for error sharing
2. File Map
advanced-analytics/
├── classes/
│ └── vendor/
│ ├── lists/
│ │ ├── class-logs-list.php — Main WP_List_Table (data read, parse, render)
│ │ ├── class-abstract-list.php — Base abstract WP_List_Table class
│ │ ├── views/
│ │ │ └── class-logs-list-view.php — Page rendering & page_load handler
│ │ └── traits/
│ │ └── class-list-trait.php — Screen options, per-page, column mgmt
│ ├── controllers/
│ │ ├── class-error-log.php — Log file autodetection, clear, truncate
│ │ ├── class-reverse-line-reader.php — Reverse file reader with memory safety
│ │ └── api/
│ │ └── class-endpoints.php — REST API route registration
│ └── helpers/
│ ├── class-log-line-parser.php — Log line regex parser
│ ├── class-ajax-helper.php — All AJAX endpoint handlers
│ ├── class-settings.php — Options, menus, admin bar, notifications
│ ├── class-file-helper.php — File download, streaming, size formatting
│ ├── class-plugin-theme-helper.php — Error source detection (plugin/theme)
│ ├── class-wp-error-handler.php — Shutdown handler, Slack/Telegram alerts
│ └── class-miscellaneous.php — Utility functions
├── js/
│ ├── admin/
│ │ └── endpoints.js — Admin bar live notification via REST API
│ ├── admin-export-csv.js — Batched CSV export with progress
│ └── sh/
│ ├── scripts/
│ │ ├── shCore.js — SyntaxHighlighter core
│ │ └── shBrushPhp.js — PHP syntax brush
│ └── styles/
│ ├── shCore.css — SyntaxHighlighter core styles
│ └── shThemeDefault.css — Default theme
└── css/
├── admin/
│ └── style.css — Admin page styles
└── admin-export-csv.css — Export progress bar styles
3. Core Classes
3.1 ADVAN\Lists\Logs_List
The main list table class. Extends Abstract_List (which extends WP_List_Table). Orchestrates data fetching, parsing, filtering, and rendering of the error log entries.
Constants
<?php
public const PAGE_SLUG = 'toplevel_page_advan_logs';
public const SCREEN_OPTIONS_SLUG = 'advanced_analytics_logs_list';
public const SEARCH_INPUT = 'sgp';Key Methods
| Method | Return | Description |
|---|---|---|
hooks_init() |
void | Attaches the page_load action on the log page load hook |
init() |
void | Registers the auto-truncate cron hook filter via advan_cron_hooks |
prepare_items() |
void | Orchestrates column setup, data fetching, pagination |
get_error_items($write_temp, $items, $first_only) |
array | Main data collection — reads log file, parses entries, applies severity/search/plugin filters |
fetch_table_data() |
array | Delegates to get_error_items(true) for table display |
format_column_value($item, $column_name) |
string | Renders HTML output for each column (timestamp, severity, message, source) |
extra_tablenav($which) |
void | Renders action buttons (truncate, download, export), severity toggles, log file info |
search_box($text, $input_id) |
void | Renders the search input with plugin filter dropdown |
extract_last_item() |
WP_REST_Response | REST callback: returns the last error entry for admin bar |
set_severity_status($request) |
WP_REST_Response | REST callback: toggle a severity on/off |
set_single_severity($request) |
WP_REST_Response | REST callback: show only one severity type |
get_notification_data() |
array | Returns data for browser push notifications |
add_cron_job($crons) |
array | Registers the auto-truncate cron callback |
truncate_error_log() |
void | Cron callback: truncates log keeping last N records |
3.2 ADVAN\Lists\Views\Logs_List_View
Handles the rendering of the error log viewer admin page and the page_load() processing.
Public Static Methods
| Method | Description |
|---|---|
render() |
Main render method — capability check, log autodetection, table preparation, HTML output |
page_load() |
Called on load-toplevel_page_advan_logs — processes query parameters, registers screen options |
3.3 ADVAN\Controllers\Error_Log
Controls all operations on the error log file: autodetection, clearing, truncation, and file metadata.
Public Static Methods
| Method | Return | Description |
|---|---|---|
autodetect() |
string|WP_Error | Detects the error log file path with full validation |
clear($filename) |
bool | Truncates the log file (empties it completely) |
get_file_size($filename) |
int | Returns file size (restricted to detected log only) |
get_modification_time($filename) |
int | Returns file modification time (restricted to detected log only) |
extract_file_name($file) |
string | Resolves resource handle or string to filename |
truncate_and_keep_errors() |
void | Keeps the last N errors (per settings), clears the rest |
suppress_error_logging() |
void | Temporarily disables PHP error logging during operations |
enable_error_logging() |
void | Re-enables PHP error logging |
Autodetection Logic
The autodetect() method determines the log file path with this sequence:
- If
keep_reading_error_logsetting is OFF (default): requires bothWP_DEBUGandWP_DEBUG_LOGconstants to betrue - If
keep_reading_error_logsetting is ON: bypasses the WP_DEBUG/WP_DEBUG_LOG checks - Reads
ini_get('error_log')for the file path - Validates: error logging is enabled, path is absolute, file exists, is readable, and is writable
- Returns the path string on success or a
WP_Erroron failure
WP_Error Codes
| Error Code | Condition |
|---|---|
wp_debug_off |
WP_DEBUG is disabled |
wp_debug_log_off |
WP_DEBUG_LOG is disabled |
log_errors_off |
PHP log_errors disabled in php.ini |
error_log_not_set |
No error_log path configured |
error_log_uses_relative_path |
Path is relative (unsupported) |
error_log_not_exists |
File does not exist |
error_log_not_writable |
File is not writable |
error_log_not_accessible |
File is not readable |
3.4 ADVAN\Controllers\Reverse_Line_Reader
Reads the error log file backwards (from end to beginning) for efficient display of newest entries first.
Constants
<?php
private const BUFFER_SIZE = 16384; // 16 KB read buffer (adaptive)
private const MEMORY_LIMIT_MB = 32; // Stop if memory exceeds 32 MB
private const TIME_LIMIT_SECONDS = 25; // Stop after 25 seconds
private const MAX_COLLECTED_ITEMS = 1000; // Max entries to collectKey Methods
| Method | Description |
|---|---|
read_file_from_end($file, $callback, &$max_lines, $pos, $temp_writer) |
Main reader loop — reads file backwards, calls $callback per line |
readline() |
Reads one line from the buffer |
write_temp_file($line) |
Writes a line to php://temp buffer |
write_memory_file($line) |
Writes a line to php://memory (with disk overflow at 80% limit) |
flush_memory_file_to_temp() |
Reverses the in-memory buffer into php://temp |
read_temp_file() |
Outputs temp file contents |
reset_class_globals() |
Cleans up all file handles and memory buffers |
Safety Mechanisms
- Memory guard: Terminates if memory usage exceeds
MEMORY_LIMIT_MB(32 MB); creates disk overflow file at 80% of limit - Time guard: Terminates after
TIME_LIMIT_SECONDS(25 seconds) - Item limit: Stops collecting after
MAX_COLLECTED_ITEMS(1,000 entries) - Buffer strategy: Uses
php://memoryfor in-memory buffer, spills tophp://tempand disk overflow files when needed - HTML escaping: Each line is
esc_html()escaped before being written to the temp buffer
3.5 ADVAN\Helpers\Log_Line_Parser
Parses individual PHP error log lines into structured arrays using regex pattern matching.
Key Methods
| Method | Return | Description |
|---|---|---|
parse_php_error_log_line($line) |
array|false | Parses a single log line into structured data |
parse_php_error_log_stack_line($message) |
array|false | Parses a stack trace frame line |
parse_entry_with_stack_trace($line) |
bool | Determines if a line is a stack trace marker |
store_last_parsed_timestamp() |
void | Saves last read timestamp to transient for new-error tracking |
get_lines_to_show_interface() |
int | Returns accumulated new error count since last view |
delete_last_parsed_timestamp() |
void | Clears the timestamp transient (used after truncation) |
Parsed Line Structure
<?php
$parsed_line = array(
'timestamp' => '2026-04-03 10:30:00', // Parsed via strtotime()
'severity' => 'error', // Lowercase severity name
'source' => 'PHP', // Origin: PHP, WordPress database, REST API, WP_Error
'message' => 'Undefined variable $foo in /path/to/file.php on line 42',
'error_file' => '/path/to/file.php', // Extracted source file path
'error_line' => 42, // Error line number
'isContext' => false, // Whether line contains [ELM_context_*] tags
'sub_items' => array(), // Stack trace frames (if present)
);Recognized Severity Types
The parser detects the following severity levels from log lines: error, warning, notice, fatal, deprecated, parse, user, info, success, request, rest_no_route, rest_forbidden, not set.
Stack Trace Parsing
Stack trace frames follow the format #N path(line): call(). The parser handles:
- Standard frames with file paths and line numbers
- PHAR archive paths
- Windows drive letters (e.g.,
C:\path) - Internal PHP functions (
[internal function]) {main}entries- Truncated / partial stack traces
3.6 ADVAN\Helpers\Ajax_Helper
Registers and handles all AJAX endpoints for the Error Log Viewer module.
Registered Actions
| AJAX Action | Handler Method | Nonce |
|---|---|---|
advanced_analytics_truncate_log_file |
truncate_log_file() |
advan-plugin-data |
advanced_analytics_truncate_and_keep_log_file |
truncate_and_keep_log_file() |
advan-plugin-data |
advanced_analytics_download_log_file |
download_log_file() |
advan-plugin-data |
log_source_view |
ajax_view_source() |
source-view |
aadvana_get_notification_data |
get_notification_data() |
advan-plugin-data |
aadvana_export_large_csv |
export_large_csv() |
export_large_csv_nonce |
aadvana_export_large_csv_cleanup |
export_large_csv_cleanup() |
export_large_csv_nonce |
advana_error_log_filtering_dismiss_notice |
error_log_filtering_dismiss_notice() |
— (direct) |
3.7 ADVAN\Helpers\Settings
Manages plugin options, admin menu registration, admin bar live notifications, and asset enqueuing.
Key Methods
| Method | Description |
|---|---|
init() |
Registers admin_menu, admin_bar_menu (priority 1000), admin_enqueue_scripts, admin_footer hooks |
add_options_page() |
Registers the top-level “0 Day” menu and all sub-menus |
get_option($key) |
Retrieves a plugin option from the 0-day-analytics_options option array |
build_option($args) |
Renders a settings form field (checkbox, radio, text, etc.) |
admin_bar_show($wp_admin_bar) |
Adds the live notification node to the admin bar |
show_error_count() |
Renders the menu badge with new error count via inline JS |
3.8 ADVAN\Helpers\File_Helper
Provides secure file download with streaming, path validation, and download link generation.
Key Methods
| Method | Description |
|---|---|
download($file_path) |
Streams file download with HTTP Range support, 8 MB chunks |
download_link($filename) |
Generates an AJAX URL for file download with nonce |
write_to_file($path, $content) |
Writes content to file with base directory validation |
is_file_valid_php($path) |
Validates that a file path points to a valid PHP file |
format_file_size($bytes) |
Formats file size to human-readable string |
Security Measures
- All download paths validated against
WP_CONTENT_DIRbase viarealpath() - Symlinks are blocked
- Proper response headers:
Content-Disposition,X-Content-Type-Options: nosniff,Cache-Control: private, no-store
3.9 ADVAN\Helpers\Plugin_Theme_Helper
Matches error file paths against installed plugins and themes to identify the source of errors.
Key Methods
| Method | Return | Description |
|---|---|---|
get_plugin_from_file_path($path) |
string|false | Matches file path to an installed plugin |
get_theme_from_file_path($path) |
string|false | Matches file path to an installed theme (including parent themes) |
get_sources() |
array | Returns all plugins/themes that appear as error sources |
get_plugins_bases() |
array | Returns installed plugin base directories for filter validation |
Additionally detects WP Core (wp-includes/) and WP Admin Core (wp-admin/) paths.
3.10 ADVAN\Helpers\WP_Error_Handler
Registers a PHP shutdown handler and a doing_it_wrong handler. Supports Slack and Telegram notifications on fatal errors.
Key Features
- Shutdown handler catches fatal errors via
error_get_last() doing_it_wronghandler logs WordPress-specific developer misuse warnings- Sensitive data redaction: passwords, tokens, cookies, and other secrets are redacted from error messages via
redact_data() - Optional Slack and Telegram notification support for real-time alerting
4. Data Flow & Execution
Page Load Sequence
admin_menuhook →Settings::add_options_page()registers the top-level menu at position 3load-toplevel_page_advan_logshook →Logs_List_View::page_load()processes query params, registers screen options- Page render →
Logs_List_View::render()is called - Capability check:
current_user_can('manage_options') Error_Log::autodetect()determines the log file path (or returnsWP_Error)Logs_List::prepare_items()orchestrates data fetchingLogs_List::get_error_items()invokes the reverse readerReverse_Line_Reader::read_file_from_end()reads the log file backwards- Each line is parsed by
Log_Line_Parser::parse_php_error_log_line() - Severity filter, search filter, and plugin filter are applied
- Results are paginated and rendered via
WP_List_Table
Log Line Processing Pipeline
Raw log file
│
▼
Reverse_Line_Reader::read_file_from_end()
│ (reads backwards, 16 KB buffer)
▼
Log_Line_Parser::parse_php_error_log_line()
│ (regex: [timestamp] Source Severity: message)
├── Extracts: timestamp, severity, source, message, error_file, error_line
├── Detects stack traces → parse_php_error_log_stack_line()
└── Groups sub_items under parent error
│
▼
Plugin_Theme_Helper::get_plugin_from_file_path()
│ (matches error file to installed plugins/themes)
▼
Severity filter (enabled/disabled severities)
│
▼
Search filter (strpos on message + sub_items)
│
▼
Plugin filter (match plugin field)
│
▼
Logs_List::format_column_value()
│ (renders HTML for each column)
▼
WP_List_Table display5. REST API Endpoints
All endpoints are registered under namespace 0-day/v1 and require manage_options capability.
| Route | Method | Callback | Description |
|---|---|---|---|
/0-day/v1/live/get_last_item |
GET | Logs_List::extract_last_item() |
Returns the last error log entry. Used by admin bar live notifications. |
/0-day/v1/severity/{severity_name}/{status}/ |
GET | Logs_List::set_severity_status() |
Enable or disable a severity filter. {status} = enable or disable. |
/0-day/v1/single_severity/{severity_name}/ |
GET | Logs_List::set_single_severity() |
Show only one severity type (all others hidden). Use none_selected to reset. |
Permission Callback
<?php
// All endpoints use this permission check:
public static function check_permissions(): bool {
return current_user_can( 'manage_options' );
}Example: Fetch Last Error via REST API
wp.apiFetch( { path: '/0-day/v1/live/get_last_item' } )
.then( function( response ) {
console.log( 'Last error:', response );
} );Example: Toggle Severity
// Disable "warning" severity
wp.apiFetch( { path: '/0-day/v1/severity/warning/disable/' } )
.then( function() {
location.reload();
} );
// Show only "fatal" errors
wp.apiFetch( { path: '/0-day/v1/single_severity/fatal/' } )
.then( function() {
location.reload();
} );
// Reset to show all severities
wp.apiFetch( { path: '/0-day/v1/single_severity/none_selected/' } )
.then( function() {
location.reload();
} );6. AJAX Endpoints
All AJAX actions require nonce verification and manage_options capability.
| Action | Nonce | Handler | Description |
|---|---|---|---|
advanced_analytics_truncate_log_file |
advan-plugin-data |
Ajax_Helper::truncate_log_file() |
Completely clears the error log file |
advanced_analytics_truncate_and_keep_log_file |
advan-plugin-data |
Ajax_Helper::truncate_and_keep_log_file() |
Truncates log keeping last N records (per keep_error_log_records_truncate setting) |
advanced_analytics_download_log_file |
advan-plugin-data |
Ajax_Helper::download_log_file() |
Triggers download of the error log file with streaming |
log_source_view |
source-view |
Ajax_Helper::ajax_view_source() |
Opens PHP source in ThickBox with SyntaxHighlighter |
aadvana_get_notification_data |
advan-plugin-data |
Ajax_Helper::get_notification_data() |
Returns data for browser push notifications |
aadvana_export_large_csv |
export_large_csv_nonce |
Ajax_Helper::export_large_csv() |
Batched CSV export with configurable batch_size (default 500) |
aadvana_export_large_csv_cleanup |
export_large_csv_nonce |
Ajax_Helper::export_large_csv_cleanup() |
Cleans up temporary export files after download |
advana_error_log_filtering_dismiss_notice |
— (direct) | Ajax_Helper::error_log_filtering_dismiss_notice() |
Stores user meta _aadvana_filter_error_log_notice_dismissed |
Example: Truncate Log via AJAX
jQuery.post( ajaxurl, {
action: 'advanced_analytics_truncate_log_file',
_wpnonce: advancedAnalytics.nonce // 'advan-plugin-data' nonce
}, function( response ) {
if ( response.success ) {
location.reload();
}
} );7. Hooks & Filters
Actions ACTION
| Hook | Location | Description |
|---|---|---|
load-toplevel_page_advan_logs |
Logs_List::hooks_init() |
Triggers Logs_List_View::page_load() on page load |
admin_menu |
Settings::init() |
Registers the “0 Day” menu and sub-menus |
admin_bar_menu (priority 1000) |
Settings::init() |
Adds live notification node to admin bar |
admin_enqueue_scripts |
Settings::init() |
Loads CSS/JS assets on plugin pages |
admin_footer (priority PHP_INT_MAX) |
Settings::init() |
Shows error count badge in admin menu |
rest_api_init |
Endpoints::init() |
Registers all REST API routes |
AJAX Actions AJAX
| Action | Handler |
|---|---|
wp_ajax_advanced_analytics_truncate_log_file |
Ajax_Helper::truncate_log_file() |
wp_ajax_advanced_analytics_truncate_and_keep_log_file |
Ajax_Helper::truncate_and_keep_log_file() |
wp_ajax_advanced_analytics_download_log_file |
Ajax_Helper::download_log_file() |
wp_ajax_log_source_view |
Ajax_Helper::ajax_view_source() |
wp_ajax_aadvana_get_notification_data |
Ajax_Helper::get_notification_data() |
wp_ajax_aadvana_export_large_csv |
Ajax_Helper::export_large_csv() |
wp_ajax_aadvana_export_large_csv_cleanup |
Ajax_Helper::export_large_csv_cleanup() |
wp_ajax_advana_error_log_filtering_dismiss_notice |
Ajax_Helper::error_log_filtering_dismiss_notice() |
Filters FILTER
| Filter | Location | Description |
|---|---|---|
advan_cron_hooks |
Logs_List::init() |
Register custom cron jobs. The auto-truncate cron is added via this filter. |
manage_{screen_id}_columns |
Settings::add_options_page() |
Manages the visible columns for the log table. |
set-screen-option |
List_Trait::set_screen_option() |
Saves the per-page screen option value. |
0-day-analytics fs_base_dir |
File_Helper::write_to_file() |
Allowed base directory for file write operations. Default: WP_CONTENT_DIR |
0-day-analytics download_base_dir |
File_Helper::download() |
Allowed base directory for file downloads. Default: WP_CONTENT_DIR |
Example: Change the Allowed Download Base Directory
<?php
\add_filter( '0-day-analytics_download_base_dir', function( $base_dir ) {
// Allow downloads from /var/log/ as well
return '/var/log';
} );Example: Add a Custom Cron Job
<?php
\add_filter( 'advan_cron_hooks', function( $crons ) {
$crons['my_custom_log_task'] = array(
'schedule' => 'daily',
'callback' => 'my_custom_log_handler',
);
return $crons;
} );
function my_custom_log_handler() {
// Custom log processing logic
}8. Settings Reference
All settings are stored in the 0-day-analytics_options option in the WordPress wp_options table.
Reading Settings Programmatically
<?php
use ADVAN\Helpers\Settings;
// Get a specific option value
$keep_reading = Settings::get_option( 'keep_reading_error_log' );
$records_keep = Settings::get_option( 'keep_error_log_records_truncate' );
$auto_clear = Settings::get_option( 'advana_error_log_clear' );
$severities = Settings::get_option( 'severities' );Error Log Options
| Option Key | Type | Default | Description |
|---|---|---|---|
keep_reading_error_log |
bool | false |
Read error log even when WP_DEBUG/WP_DEBUG_LOG are off |
keep_error_log_records_truncate |
int | 10 |
Number of records to keep when using “Truncate (keep last records)” |
advana_error_log_clear |
string | '-1' |
Cron schedule for automatic log truncation (-1 = disabled) |
protected_config_source |
bool | true |
Block viewing of config/settings files in source viewer |
Notification Options
| Option Key | Type | Default | Description |
|---|---|---|---|
live_notifications_admin_bar |
bool | true |
Show latest error in WordPress admin bar |
browser_notifications_seconds |
int | 10 |
Polling interval for browser push notifications (seconds, min 5) |
browser_notifications_not_send |
bool | false |
Disable browser push notifications entirely |
General Options
| Option Key | Type | Default | Description |
|---|---|---|---|
menu_admins_only |
bool | true |
Restrict menu to manage_options capability |
plugin_debug_enable |
bool | false |
Enable plugin debug features |
Severity Configuration
The severities option stores an associative array of severity types. Each entry has:
<?php
$severities = array(
'deprecated' => array( 'name' => 'Deprecated', 'color' => '#c4b576', 'display' => true ),
'error' => array( 'name' => 'Error', 'color' => '#ffb3b3', 'display' => true ),
'success' => array( 'name' => 'Success', 'color' => '#00ff00', 'display' => true ),
'info' => array( 'name' => 'Info', 'color' => '#aeaeec', 'display' => true ),
'notice' => array( 'name' => 'Notice', 'color' => '#feeb8e', 'display' => true ),
'warning' => array( 'name' => 'Warning', 'color' => '#ffff00', 'display' => true ),
'fatal' => array( 'name' => 'Fatal', 'color' => '#f09595', 'display' => true ),
'parse' => array( 'name' => 'Parse', 'color' => '#e3bb8d', 'display' => true ),
'user' => array( 'name' => 'User', 'color' => '#85b395', 'display' => true ),
'not set' => array( 'name' => 'Not Set', 'color' => '#7a6f72', 'display' => true ),
'request' => array( 'name' => 'Request', 'color' => '#759b71', 'display' => true ),
'rest_no_route' => array( 'name' => 'REST No Route', 'color' => '#759b71', 'display' => true ),
'rest_forbidden' => array( 'name' => 'REST Forbidden', 'color' => '#759b71', 'display' => true ),
);9. Constants
| Constant | Value | Description |
|---|---|---|
ADVAN_VERSION |
'5.0.0' |
Plugin version |
ADVAN_SETTINGS_NAME |
'0-day-analytics_options' |
Options table key for plugin settings |
ADVAN_PREFIX |
'aadvana_' |
Prefix for AJAX actions and transient keys |
ADVAN_INNER_SLUG |
'0-day' |
Internal slug used for REST API namespace |
10. Transients
| Transient Key | Scope | Purpose |
|---|---|---|
advan_timestamp |
Site | Tracks the timestamp of the last-read error entry to detect new errors |
advan_newer_lines |
Site | Accumulates count of new error entries since the user last viewed the log |
aadvan_notification |
Site | Stores timestamp of last reported browser notification to prevent duplicates |
How New Error Tracking Works
- When the log is read,
Log_Line_Parser::store_last_parsed_timestamp()saves the newest entry’s timestamp to theadvan_timestamptransient - On subsequent reads, entries newer than the stored timestamp are counted in
advan_newer_lines - The menu badge displays this count via
Settings::show_error_count() - When the user visits the Error Log page, the count resets
- On log truncation,
Log_Line_Parser::delete_last_parsed_timestamp()clears both transients
11. Security Architecture
Capability Checks
| Context | Requirement |
|---|---|
| Menu visibility | manage_options (when menu_admins_only is true) or read |
| Page render | current_user_can('manage_options') guard in Logs_List_View::render() |
| All AJAX actions | Nonce verification via WP_Helper::verify_admin_nonce() |
| All REST API endpoints | current_user_can('manage_options') via Endpoints::check_permissions() |
page_load() |
Capability check before processing query parameters |
Nonce Verification
| Context | Nonce Action | Nonce Field |
|---|---|---|
| Page form | advan-plugin-data |
advanced-analytics-security |
| Source viewer | source-view |
— |
| CSV export | export_large_csv_nonce |
— |
| General AJAX | advan-plugin-data |
— |
Path Validation & File Security
Error_Log::clear()— validates the filename matches the detected log viais_same_log_file()usingrealpath()File_Helper::download()— validates path againstWP_CONTENT_DIRbase, blocks symlinksFile_Helper::write_to_file()— validates against allowed base directory, blocks symlinks- Source viewer —
is_file_valid_php()check, config file protection viaprotected_config_sourcesetting Reverse_Line_Reader::set_temp_handle_from_file_path()— rejects null bytes, non-file schemes, validates directory existence/writability, resolvesrealpath()
Input Sanitization
- Search input:
sanitize_text_field()+wp_unslash() - Plugin filter: validated against
Plugin_Theme_Helper::get_plugins_bases()whitelist - Severity names: validated against
Settings::get_option('severities')keys - File names in source viewer: validated as valid PHP file
- Browser notifications JS:
sanitize_field()strips<>and newlines,isSafeUrl()validates HTTPS protocol - Export data: content pre-escaped with
esc_html() - Sensitive data in errors: redacted via
WP_Error_Handler::redact_data()(passwords, tokens, cookies, etc.)
12. JavaScript Components
Admin Bar Live Notifications
File: js/admin/endpoints.js
- Calls
GET /0-day/v1/live/get_last_itemviawp.apiFetchonce on DOM ready - Updates the admin bar node
#wp-admin-bar-aadvan-menuwith the latest error message and severity styling
Browser Push Notifications
Inline in class-settings.php
- Uses the browser
NotificationAPI with configurable poll interval (browser_notifications_seconds) - Polls AJAX endpoint
aadvana_get_notification_dataat the configured interval - Shows notification with error severity, message, plugin icon, and clickable link to the log page
- Notifications auto-dismiss after 5 seconds
- Deduplication via
aadvan_notificationsite transient
Severity Toggle
Inline in class-logs-list.php
- Checkbox toggles call REST API
severity/{name}/{enable|disable}thenlocation.reload() - Single severity dropdown calls REST API
single_severity/{name}/
Log Management Actions
Inline in class-logs-list.php
- Truncate: Confirm dialog, then AJAX POST to
advanced_analytics_truncate_log_file, reloads page - Truncate & Keep: Same pattern with
advanced_analytics_truncate_and_keep_log_file - Download: Creates a temporary
<a>element pointing toFile_Helper::download_link() - Copy to clipboard: Clicking clipboard icon copies error message + stack trace to clipboard
- Share: Uses
navigator.share()API (Web Share API) when available - Show details: Toggles
.log_details_showdiv for stack trace expansion
CSV Export
File: js/admin-export-csv.js
- Batched export with progress bar and cancel support
- Posts to
aadvana_export_large_csvwith batch number, batch_size (default 500), and filter params - Cleanup via
aadvana_export_large_csv_cleanupafter download (delayed 10 seconds)
Raw Log View
Inline in class-logs-list.php
- Raw log content displayed in
<pre id="debug-log">block (black background, white text, max-height 400px, scrollable) - Selecting text in this block auto-copies to clipboard with tooltip feedback
Dark Skin Toggle
- Checks
localStorage.getItem('aadvana-backend-skin')for'dark'value - Adds
aadvana-darkskinclass to<html>element - All severity-related styles have
html.aadvana-darkskinoverrides
13. Code Examples
Example 1: Autodetect the Error Log File
<?php
use ADVAN\Controllers\Error_Log;
$log_path = Error_Log::autodetect();
if ( is_wp_error( $log_path ) ) {
echo 'Error: ' . $log_path->get_error_message();
echo 'Code: ' . $log_path->get_error_code();
} else {
echo 'Log file: ' . $log_path;
echo 'Size: ' . Error_Log::get_file_size( $log_path ) . ' bytes';
echo 'Last modified: ' . gmdate( 'Y-m-d H:i:s', Error_Log::get_modification_time( $log_path ) );
}Example 2: Parse a Log Line
<?php
use ADVAN\Helpers\Log_Line_Parser;
$line = '[03-Apr-2026 10:30:00 UTC] PHP Warning: Undefined variable $foo in /var/www/html/wp-content/plugins/my-plugin/main.php on line 42';
$parsed = Log_Line_Parser::parse_php_error_log_line( $line );
if ( $parsed ) {
echo 'Timestamp: ' . $parsed['timestamp']; // 2026-04-03 10:30:00
echo 'Severity: ' . $parsed['severity']; // warning
echo 'Source: ' . $parsed['source']; // PHP
echo 'Message: ' . $parsed['message'];
echo 'File: ' . $parsed['error_file']; // /var/www/.../main.php
echo 'Line: ' . $parsed['error_line']; // 42
}Example 3: Identify Plugin from Error Path
<?php
use ADVAN\Helpers\Plugin_Theme_Helper;
$error_file = '/var/www/html/wp-content/plugins/woocommerce/includes/class-wc-cart.php';
$plugin_name = Plugin_Theme_Helper::get_plugin_from_file_path( $error_file );
if ( $plugin_name ) {
echo 'Error originated from plugin: ' . $plugin_name;
} else {
$theme_name = Plugin_Theme_Helper::get_theme_from_file_path( $error_file );
if ( $theme_name ) {
echo 'Error originated from theme: ' . $theme_name;
} else {
echo 'Source unknown or WP core';
}
}Example 4: Clear the Error Log Programmatically
<?php
use ADVAN\Controllers\Error_Log;
$log_path = Error_Log::autodetect();
if ( ! is_wp_error( $log_path ) ) {
// Completely clear the log
$cleared = Error_Log::clear( $log_path );
if ( $cleared ) {
echo 'Error log cleared successfully.';
}
// Or truncate keeping last 20 records
// (uses the keep_error_log_records_truncate setting)
Error_Log::truncate_and_keep_errors();
}Example 5: Get the Last Error for External Monitoring
<?php
use ADVAN\Lists\Logs_List;
// Fetch the last error entry (same as the REST API endpoint)
$logs_list = new Logs_List();
$response = $logs_list->extract_last_item();
$data = $response->get_data();
if ( ! empty( $data ) ) {
echo 'Latest error severity: ' . $data['severity'];
echo 'Latest error message: ' . $data['message'];
echo 'Timestamp: ' . $data['timestamp'];
}Example 6: Generate a Log File Download Link
<?php
use ADVAN\Helpers\File_Helper;
use ADVAN\Controllers\Error_Log;
$log_path = Error_Log::autodetect();
if ( ! is_wp_error( $log_path ) ) {
$download_url = File_Helper::download_link( $log_path );
echo '<a href="' . esc_url( $download_url ) . '">Download Error Log</a>';
}Example 7: Check and Modify Severity Settings
<?php
use ADVAN\Helpers\Settings;
// Get all severity configurations
$severities = Settings::get_option( 'severities' );
// Check if a severity is enabled for display
if ( $severities['warning']['display'] ) {
echo 'Warnings are visible in the log viewer.';
}
// Check notification settings
$admin_bar_enabled = Settings::get_option( 'live_notifications_admin_bar' );
$polling_interval = Settings::get_option( 'browser_notifications_seconds' );
$notifications_off = Settings::get_option( 'browser_notifications_not_send' );
echo 'Admin bar notifications: ' . ( $admin_bar_enabled ? 'Enabled' : 'Disabled' );
echo 'Browser notification polling: every ' . $polling_interval . ' seconds';Example 8: Customize the Download Base Directory
<?php
// Allow downloads from a custom log directory outside wp-content
\add_filter( '0-day-analytics_download_base_dir', function( $base_dir ) {
return '/var/log/wordpress';
} );
// Allow file writes to a custom directory
\add_filter( '0-day-analytics_fs_base_dir', function( $base_dir ) {
return '/var/log/wordpress';
} );Example 9: Suppress Error Logging During Operations
<?php
use ADVAN\Controllers\Error_Log;
// Temporarily suppress PHP error logging
// (useful during operations that might produce expected errors)
Error_Log::suppress_error_logging();
// Perform operations that might trigger PHP errors...
@some_potentially_noisy_function();
// Re-enable error logging
Error_Log::enable_error_logging();See
Error Log Module User Guide for more details about configuration, practical usage and information.