Effective debugging and logging are essential for maintaining a healthy ShahiAssist installation. This guide covers comprehensive debugging techniques, logging strategies, and error handling practices.
Debug Configuration
WordPress Debug Setup
`php
// wp-config.php – Enable debugging
define(‘WP_DEBUG’, true);
define(‘WPDEBUGLOG’, true);
define(‘WPDEBUGDISPLAY’, false); // Don’t show errors on frontend
// ShahiAssist specific debug settings
define(‘SHAHIASSISTDEBUG’, true);
define(‘SHAHIASSISTDEBUGLOG’, WPCONTENT_DIR . ‘/logs/shahi-assist-debug.log’);
define(‘SHAHIASSISTDEBUG_LEVEL’, ‘INFO’); // ERROR, WARNING, INFO, DEBUG
`
Debug Helper Class
`php
class ShahiAssist_Debug {
private static $log_file;
private static $debug_level;
public static function init() {
self::$logfile = defined(‘SHAHIASSISTDEBUGLOG’) ? SHAHIASSISTDEBUGLOG : WPCONTENT_DIR . ‘/debug.log’;
self::$debuglevel = defined(‘SHAHIASSISTDEBUGLEVEL’) ? SHAHIASSISTDEBUG_LEVEL : ‘INFO’;
// Ensure log directory exists
$logdir = dirname(self::$logfile);
if (!fileexists($logdir)) {
wpmkdirp($log_dir);
}
}
public static function log($message, $level = ‘INFO’, $context = []) {
if (!self::should_log($level)) {
return;
}
$timestamp = current_time(‘Y-m-d H:i:s’);
$userid = getcurrentuserid();
$ip = $SERVER[‘REMOTEADDR’] ?? ”;
$log_entry = sprintf(
“[%s] %s: %s (User: %s, IP: %s)”,
$timestamp,
$level,
$message,
$user_id,
$ip
);
if (!empty($context)) {
$logentry .= ‘ | Context: ‘ . jsonencode($context);
}
errorlog($logentry . “\n”, 3, self::$log_file);
// Also log to WordPress debug.log if enabled
if (defined(‘WPDEBUGLOG’) && WPDEBUGLOG) {
errorlog(‘ShahiAssist: ‘ . $logentry);
}
}
private static function should_log($level) {
$levels = [‘ERROR’ => 1, ‘WARNING’ => 2, ‘INFO’ => 3, ‘DEBUG’ => 4];
$currentlevel = $levels[self::$debuglevel] ?? 3;
$message_level = $levels[$level] ?? 3;
return $messagelevel <= $currentlevel;
}
public static function error($message, $context = []) {
self::log($message, ‘ERROR’, $context);
}
public static function warning($message, $context = []) {
self::log($message, ‘WARNING’, $context);
}
public static function info($message, $context = []) {
self::log($message, ‘INFO’, $context);
}
public static function debug($message, $context = []) {
self::log($message, ‘DEBUG’, $context);
}
}
// Initialize debug logging
addaction(‘init’, [‘ShahiAssistDebug’, ‘init’]);
`
Error Handling
Global Error Handler
`php
// Set up global error handling
seterrorhandler(function($errno, $errstr, $errfile, $errline) {
// Only handle errors, not warnings/notices in production
if (!(error_reporting() & $errno)) {
return false;
}
$error_type = [
E_ERROR => ‘ERROR’,
E_WARNING => ‘WARNING’,
E_PARSE => ‘PARSE’,
E_NOTICE => ‘NOTICE’,
ECOREERROR => ‘CORE_ERROR’,
ECOREWARNING => ‘CORE_WARNING’,
ECOMPILEERROR => ‘COMPILE_ERROR’,
ECOMPILEWARNING => ‘COMPILE_WARNING’,
EUSERERROR => ‘USER_ERROR’,
EUSERWARNING => ‘USER_WARNING’,
EUSERNOTICE => ‘USER_NOTICE’,
E_STRICT => ‘STRICT’,
ERECOVERABLEERROR => ‘RECOVERABLE_ERROR’,
E_DEPRECATED => ‘DEPRECATED’,
EUSERDEPRECATED => ‘USER_DEPRECATED’,
];
$type = $error_type[$errno] ?? ‘UNKNOWN’;
ShahiAssist_Debug::error(“PHP $type: $errstr in $errfile:$errline”);
// Don’t execute PHP’s internal error handler
return true;
});
// Handle fatal errors
registershutdownfunction(function() {
$error = errorgetlast();
if ($error !== null && inarray($error[‘type’], [EERROR, EPARSE, ECOREERROR, ECOMPILE_ERROR])) {
ShahiAssist_Debug::error(
“Fatal error: {$error[‘message’]} in {$error[‘file’]}:{$error[‘line’]}”
);
}
});
`
Exception Handling
`php
class ShahiAssist_Exception extends Exception {
protected $context;
public function __construct($message, $code = 0, $context = [], Exception $previous = null) {
$this->context = $context;
parent::__construct($message, $code, $previous);
ShahiAssistDebug::error($message, arraymerge($context, [
‘file’ => $this->getFile(),
‘line’ => $this->getLine(),
‘trace’ => $this->getTraceAsString()
]));
}
public function getContext() {
return $this->context;
}
}
// Custom exception handler
setexceptionhandler(function($exception) {
ShahiAssist_Debug::error(‘Uncaught exception: ‘ . $exception->getMessage(), [
‘file’ => $exception->getFile(),
‘line’ => $exception->getLine(),
‘trace’ => $exception->getTraceAsString()
]);
// Show user-friendly error page
if (!WP_DEBUG) {
wp_die(‘An error occurred. Please try again later.’, ‘Error’, [‘response’ => 500]);
}
});
`
AJAX Error Handling
`php
// Handle AJAX errors
addaction(‘wpajaxshahiassistaction’, ‘handleajax_request’);
addaction(‘wpajaxnoprivshahiassistaction’, ‘handleajaxrequest’);
function handleajaxrequest() {
try {
// Verify nonce
if (!wpverifynonce($POST[‘nonce’] ?? ”, ‘shahiassist_nonce’)) {
throw new ShahiAssist_Exception(‘Invalid nonce’, 403);
}
// Process request
$result = processajaxrequest($_POST);
ShahiAssist_Debug::info(‘AJAX request processed successfully’, [
‘action’ => $_POST[‘action’] ?? ‘unknown’,
‘userid’ => getcurrentuserid()
]);
wpsendjson_success($result);
} catch (ShahiAssist_Exception $e) {
wpsendjson_error([
‘message’ => $e->getMessage(),
‘code’ => $e->getCode()
], $e->getCode());
} catch (Exception $e) {
ShahiAssist_Debug::error(‘Unexpected AJAX error: ‘ . $e->getMessage());
wpsendjson_error([
‘message’ => ‘An unexpected error occurred’,
‘code’ => 500
], 500);
}
}
`
Logging Strategies
Structured Logging
`php
class ShahiAssist_Logger {
public static function logticketaction($ticketid, $action, $userid = null, $details = []) {
$userid = $userid ?? getcurrentuser_id();
self::log(‘ticket_action’, ‘INFO’, [
‘ticketid’ => $ticketid,
‘action’ => $action,
‘userid’ => $userid,
‘details’ => $details,
‘timestamp’ => current_time(‘mysql’),
‘ipaddress’ => $SERVER[‘REMOTE_ADDR’] ?? ”,
‘useragent’ => $SERVER[‘HTTPUSERAGENT’] ?? ”
]);
}
public static function logapirequest($endpoint, $method, $response_code, $duration = null) {
self::log(‘api_request’, ‘INFO’, [
‘endpoint’ => $endpoint,
‘method’ => $method,
‘responsecode’ => $responsecode,
‘duration’ => $duration,
‘userid’ => getcurrentuserid(),
‘timestamp’ => current_time(‘mysql’)
]);
}
public static function logperformancemetric($operation, $duration, $metadata = []) {
self::log(‘performance’, ‘DEBUG’, array_merge($metadata, [
‘operation’ => $operation,
‘duration’ => $duration,
‘memoryusage’ => memorygetpeakusage(true),
‘timestamp’ => current_time(‘mysql’)
]));
}
private static function log($category, $level, $data) {
$logentry = jsonencode([
‘category’ => $category,
‘level’ => $level,
‘data’ => $data
]);
ShahiAssistDebug::log(“[$category] ” . $logentry, $level);
// Store in database for admin viewing
self::storelogentry($category, $level, $data);
}
private static function storelogentry($category, $level, $data) {
global $wpdb;
$tablename = $wpdb->prefix . ‘shahiassist_logs’;
$wpdb->insert($table_name, [
‘category’ => $category,
‘level’ => $level,
‘message’ => json_encode($data),
‘createdat’ => currenttime(‘mysql’)
]);
// Clean old logs (keep last 30 days)
$wpdb->query($wpdb->prepare(“
DELETE FROM $table_name
WHERE createdat < DATESUB(NOW(), INTERVAL 30 DAY)
“));
}
}
// Usage examples
ShahiAssistLogger::logticketaction($ticketid, ‘created’);
ShahiAssistLogger::logapi_request(‘/wp-json/shahi-assist/v1/tickets’, ‘GET’, 200, 0.15);
ShahiAssistLogger::logperformancemetric(‘ticketquery’, 0.05, [‘query_count’ => 1]);
`
Log Rotation and Management
`php
class ShahiAssistLogManager {
public static function rotate_logs() {
$logfile = ShahiAssistDebug::$log_file;
if (!fileexists($logfile)) {
return;
}
$max_size = 10 1024 1024; // 10MB
$filesize = filesize($logfile);
if ($filesize > $maxsize) {
$backupfile = $logfile . ‘.’ . date(‘Y-m-d-H-i-s’) . ‘.bak’;
rename($logfile, $backupfile);
// Compress old logs
if (function_exists(‘gzcompress’)) {
$compressed = gzcompress(filegetcontents($backup_file));
fileputcontents($backup_file . ‘.gz’, $compressed);
unlink($backup_file);
}
ShahiAssist_Debug::info(‘Log file rotated’, [
‘originalsize’ => $filesize,
‘backupfile’ => basename($backupfile)
]);
}
}
public static function cleanupoldlogs() {
$logdir = dirname(ShahiAssistDebug::$log_file);
$files = glob($log_dir . ‘/.log..gz’);
$max_age = 30 24 60 * 60; // 30 days
foreach ($files as $file) {
if (filemtime($file) < time() - $max_age) {
unlink($file);
}
}
}
}// Schedule log maintenance
addaction(‘shahiassistdailymaintenance’, [‘ShahiAssistLogManager’, ‘rotate_logs’]);
addaction(‘shahiassistdailymaintenance’, [‘ShahiAssistLogManager’, ‘cleanupoldlogs’]);
`
Debug Tools and Techniques
Debug Bar Integration
`php
// Add ShahiAssist panel to Debug Bar
addfilter(‘debugbar_panels’, function($panels) {
require_once ‘class-shahi-assist-debug-bar-panel.php’;
$panels[] = new ShahiAssistDebugBar_Panel();
return $panels;
});
class ShahiAssistDebugBarPanel extends DebugBar_Panel {
public function init() {
$this->title = ‘ShahiAssist’;
}
public function render() {
echo ‘
ShahiAssist Debug Information
‘;
// Show current settings
echo ‘
Settings
‘;
echo ‘
' . eschtml(printr(getoption('shahiassist_settings'), true)) . '‘;
// Show recent logs
echo ‘
Recent Logs
‘;
global $wpdb;
$logs = $wpdb->get_results(“
SELECT * FROM {$wpdb->prefix}shahiassistlogs
ORDER BY created_at DESC LIMIT 10
“);
if ($logs) {
echo ‘
| Time | Category | Level | Message |
|---|---|---|---|
| ‘ . eschtml($log->createdat) . ‘ | ‘ . esc_html($log->category) . ‘ | ‘ . esc_html($log->level) . ‘ | ‘ . esc_html(substr($log->message, 0, 100)) . ‘ |
‘;
}
}
}
`
Performance Debugging
`php
// Profile function execution
function profilefunction($functionname, $callback) {
$start_time = microtime(true);
$startmemory = memoryget_usage();
$result = $callback();
$end_time = microtime(true);
$endmemory = memoryget_usage();
$duration = $endtime – $starttime;
$memoryused = $endmemory – $start_memory;
ShahiAssistLogger::logperformancemetric($functionname, $duration, [
‘memoryused’ => $memoryused,
‘memorypeak’ => memorygetpeakusage(true)
]);
return $result;
}
// Usage
$tickets = profilefunction(‘getuser_tickets’, function() {
return get_posts([
‘post_type’ => ‘ticket’,
‘author’ => getcurrentuser_id(),
‘postsperpage’ => -1
]);
});
`
Query Debugging
`php
// Log database queries
add_filter(‘query’, function($query) {
global $wpdb;
$start_time = microtime(true);
$caller = debugbacktrace(DEBUGBACKTRACEIGNOREARGS, 5);
// Execute query and measure time
$result = $wpdb->query($query);
$duration = microtime(true) – $start_time;
if ($duration > 0.01) { // Log slow queries
ShahiAssist_Debug::warning(‘Slow query detected’, [
‘query’ => $query,
‘duration’ => $duration,
‘caller’ => $caller[0][‘file’] . ‘:’ . $caller[0][‘line’]
]);
}
return $result;
});
// Debug specific queries
function debug_query($query, $context = ”) {
global $wpdb;
ShahiAssist_Debug::debug(“Executing query: $query”, [
‘context’ => $context,
‘backtrace’ => debugbacktrace(DEBUGBACKTRACEIGNOREARGS, 3)
]);
$start_time = microtime(true);
$result = $wpdb->query($query);
$duration = microtime(true) – $start_time;
ShahiAssist_Debug::debug(“Query completed in {$duration}s”, [
‘resultcount’ => isobject($result) ? $result->num_rows : $result,
‘context’ => $context
]);
return $result;
}
`
Admin Debug Interface
Debug Settings Page
`php
// Add debug settings to admin
addaction(‘adminmenu’, function() {
addsubmenupage(
‘shahi-assist-settings’,
‘Debug & Logs’,
‘Debug & Logs’,
‘manage_options’,
‘shahi-assist-debug’,
‘shahiassistdebug_page’
);
});
function shahiassistdebug_page() {
if (isset($POST[‘clearlogs’])) {
global $wpdb;
$wpdb->query(“TRUNCATE TABLE {$wpdb->prefix}shahiassistlogs”);
echo ‘
Logs cleared successfully.
‘;
}
if (isset($POST[‘rundiagnostics’])) {
$diagnostics = runsystemdiagnostics();
echo ‘
' . eschtml(printr($diagnostics, true)) . '
‘;
}
?>
ShahiAssist Debug & Logs
System Information
| PHP Version | |
| WordPress Version | |
| Plugin Version | option(‘shahiassist_version’); ?> |
| Debug Mode | |
| Memory Limit | get(‘memorylimit’); ?> |
Recent Logs
get_results(“
SELECT * FROM {$wpdb->prefix}shahiassistlogs
ORDER BY created_at DESC LIMIT 50
“);
if ($logs) {
echo ‘
| Time | Category | Level | Message |
|---|---|---|---|
| ‘ . eschtml($log->createdat) . ‘ | ‘ . esc_html($log->category) . ‘ | ‘ . esc_html($log->level) . ‘ |
‘ . eschtml(substr($log->message, 0, 50)) . ‘…' . eschtml($log->message) . ' |
‘;
} else {
echo ‘
No logs found.
‘;
}
?>
systemdiagnostics() {
global $wpdb;
return [
‘database’ => [
‘connection’ => $wpdb->check_connection() ? ‘OK’ : ‘FAILED’,
‘table_prefix’ => $wpdb->prefix,
‘charset’ => $wpdb->charset,
],
‘file_system’ => [
‘uploaddirwritable’ => wpiswritable(wpuploaddir()[‘basedir’]) ? ‘YES’ : ‘NO’,
‘plugindirwritable’ => wpiswritable(plugindirpath(FILE)) ? ‘YES’ : ‘NO’,
],
‘performance’ => [
‘memoryusage’ => sizeformat(memorygetusage(true)),
‘peakmemory’ => sizeformat(memorygetpeak_usage(true)),
‘executiontime’ => timerstop(0, 2) . ‘s’,
],
‘tickets’ => [
‘totalcount’ => wpcount_posts(‘ticket’)->publish,
‘opencount’ => getposts([‘posttype’ => ‘ticket’, ‘metakey’ => ‘ticketstatus’, ‘meta_value’ => ‘open’, ‘fields’ => ‘ids’]),
]
];
}
`
Resources
Share this article
Still need help?
Our support team is ready to assist you with personalized guidance for your workspace.