ShahiAssist

Debugging and Logging

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 ‘

‘;
echo ‘

‘;
echo ‘

‘;
foreach ($logs as $log) {
echo ‘

‘;
echo ‘

‘;
echo ‘

‘;
echo ‘

‘;
echo ‘

‘;
echo ‘

‘;
}
echo ‘

TimeCategoryLevelMessage
‘ . 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 Versionoption(‘shahiassist_version’); ?>
Debug Mode
Memory Limitget(‘memorylimit’); ?>

Recent Logs

button(‘Clear Logs’, ‘delete’, ‘clearlogs’); ?>
button(‘Run Diagnostics’, ‘secondary’, ‘rundiagnostics’); ?>

get_results(“
SELECT * FROM {$wpdb->prefix}shahiassistlogs
ORDER BY created_at DESC LIMIT 50
“);

if ($logs) {
echo ‘

‘;
echo ‘

‘;
echo ‘

‘;
foreach ($logs as $log) {
echo ‘

‘;
echo ‘

‘;
echo ‘

‘;
echo ‘

‘;
echo ‘

‘;
echo ‘

‘;
}
echo ‘

TimeCategoryLevelMessage
‘ . 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

Was this article helpful?

Help us improve our documentation

Still need help?

Our support team is ready to assist you with personalized guidance for your workspace.

Submit a support ticket