From 6c9165ca033448654b5607771e3b43743916538c Mon Sep 17 00:00:00 2001 From: Eric Harris Date: Tue, 29 Oct 2024 08:33:07 -0500 Subject: [PATCH 1/4] Made changes to add new JSON format figure for status call. --- .gitignore | 3 +- src/Worker.php | 130 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 129 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index b328cb6f4..97ec859e1 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ composer.lock phpunit.xml /phpstan.neon /*.pid -/*.pid.lock \ No newline at end of file +/*.pid.lock +nbproject/ diff --git a/src/Worker.php b/src/Worker.php index c3f0351fa..485ede005 100644 --- a/src/Worker.php +++ b/src/Worker.php @@ -305,6 +305,13 @@ class Worker */ public static string $logFile; + /** + * Log in JSON. + * + * @var bool + */ + public static bool $jsonLog = false; + /** * Global event loop. * @@ -972,7 +979,7 @@ protected static function parseCommand(): void // Check argv; $startFile = basename(static::$startFile); - $usage = "Usage: php yourfile [mode]\nCommands: \nstart\t\tStart worker in USER mode.\n\t\tUse mode -d to start in DAEMON mode.\nstop\t\tStop worker.\n\t\tUse mode -g to stop gracefully.\nrestart\t\tRestart workers.\n\t\tUse mode -d to start in DAEMON mode.\n\t\tUse mode -g to stop gracefully.\nreload\t\tReload codes.\n\t\tUse mode -g to reload gracefully.\nstatus\t\tGet worker status.\n\t\tUse mode -d to show live status.\nconnections\tGet worker connections.\n"; + $usage = "Usage: php yourfile [mode]\nCommands: \nstart\t\tStart worker in USER mode.\n\t\tUse mode -d to start in DAEMON mode.\nstop\t\tStop worker.\n\t\tUse mode -g to stop gracefully.\nrestart\t\tRestart workers.\n\t\tUse mode -d to start in DAEMON mode.\n\t\tUse mode -g to stop gracefully.\nreload\t\tReload codes.\n\t\tUse mode -g to reload gracefully.\nstatus\t\tGet worker status.\n\t\tUse switch -d to show live status.\n\t\tUse flag -jl to print log in JSON.\\nconnections\tGet worker connections.\n"; $availableCommands = [ 'start', 'stop', @@ -985,6 +992,8 @@ protected static function parseCommand(): void '-d', '-g' ]; + $availableLog = ['-jl']; + $command = $mode = ''; foreach (static::getArgv() as $value) { if (!$command && in_array($value, $availableCommands)) { @@ -992,6 +1001,9 @@ protected static function parseCommand(): void } if (!$mode && in_array($value, $availableMode)) { $mode = $value; + } + if (in_array($value, $availableLog)) { + static::$jsonLog = true; } } @@ -1211,9 +1223,121 @@ protected static function formatProcessStatusData(): string . str_pad((string)$totalConnections, 11) . " " . str_pad((string)$totalFails, 9) . " " . str_pad((string)$totalTimers, 7) . " " . str_pad((string)$totalRequests, 13) . " " . str_pad((string)$totalQps, 6) . " [Summary] \n"; - return $statusStr; - } + return ( static::$jsonLog === true ? self::formatConnectionStatusDataJson($statusStr) : $statusStr ); + } + + protected static function formatConnectionStatusDataJson( string $statusStr ): string + { + $gsKey = 'Global Status'; + $pKey = 'Processes'; + $arr = [ $gsKey => [], $pKey => ['Records' => []] ]; + $currStatus = null; + $processKeys = []; + + $lines = explode("\n", $statusStr ); + + foreach($lines as $line){ + $matches = []; + + if(preg_match('/GLOBAL STATUS/', $line)){ + $currStatus = 'GLOBAL'; + continue; + } elseif(preg_match('/^worker_name\s+exit_status\s+exit_count/', $line) && $currStatus === 'GLOBAL') { + $currStatus = 'WORKER'; + continue; + } elseif(preg_match('/PROCESS STATUS/', $line) && $currStatus === 'WORKER') { + $currStatus = 'PROCESS'; + continue; + } elseif(preg_match('/PROCESS STATUS/', $line) && $currStatus === 'PROCESS') { + $currStatus = 'SUMMARY'; + continue; + } + + if( $currStatus === 'GLOBAL' ){ + if( preg_match('/^Workerman version:(\S+)\s+PHP version:(\S+)/', $line, $matches ) && + array_key_exists(1,$matches) && array_key_exists(2,$matches) ){ + $arr[$gsKey]['Versions'] = ['Workerman' => $matches[1], 'PHP' => $matches[2]]; + } elseif( preg_match('/^start time:(.*?)\s+run(.*)/', $line, $matches ) && + array_key_exists(1,$matches) && array_key_exists(2,$matches) ){ + $arr[$gsKey]['Run Stats'] = [ 'Start Time' => rtrim($matches[1]), + 'Uptime' => trim($matches[2]) ]; + } elseif( preg_match('/^load average:\s(\S+,\s\S+,\s\S+)\s+event-loop:(\S+)/', $line, $matches ) && + array_key_exists(1,$matches) && array_key_exists(2,$matches) ){ + $arr[$gsKey]['Load Average'] = $matches[1]; + $arr[$gsKey]['Event'] = $matches[2]; + } elseif( preg_match('/^(\d+) workers\s+(\d+) processes/', $line, $matches ) && + array_key_exists(1,$matches) && array_key_exists(2,$matches) ){ + $arr[$gsKey]['Workers'] = [ 'Count' => $matches[1], 'Processes' => $matches[2], + 'Records' => [] ]; + $arr[$pKey]['Count'] = $matches[2]; + } + } elseif( $currStatus === 'WORKER' ){ + + if( preg_match('/^(.*?)\s(\d)\s+(\d)/', $line, $matches ) && + array_key_exists(1,$matches) && array_key_exists(2,$matches) && array_key_exists(3,$matches) ){ + + $arr[$gsKey]['Workers']['Records'][] = ['Name' => rtrim($matches[1]), + 'Exit Status' => intval($matches[2]), + 'Exit Count' => intval($matches[3])]; + } + } elseif( $currStatus === 'PROCESS' ){ + if(preg_match('/^pid\s+memory\s+listening/', $line)) { + preg_match('/^(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*)/', + $line, + $matches ); + + if( count($matches) < 3 ){ + continue; + } + + for($i = 1; $i < count($matches); $i++ ){ + $processKeys[$i] = $matches[$i]; + } + + } elseif( preg_match('/^(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(.*)/', + $line, + $matches ) ){ + + if( count($processKeys) !== count($matches) - 1 || count($processKeys) < 3 ){ + //header row column count did not match row count + continue; + } + $pArr = []; + + for( $i = 1; $i <= count($processKeys); $i++ ){ + $pArr[$processKeys[$i]] = ( is_numeric($matches[$i]) ? intval($matches[$i]) : $matches[$i] ); + } + $arr[$pKey]['Records'][] = $pArr; + } + + } elseif( $currStatus === 'SUMMARY') { + if( preg_match('/^(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(.*)/', + $line, + $matches ) ){ + + if( count($processKeys) !== count($matches) - 1 || count($processKeys) < 3 ){ + //header row column count did not match row count + continue; + } + + $pArr = []; + + for( $i = 2; $i < count($processKeys); $i++ ){ + if( $matches[$i] === '-' ){ + continue; + } + $pArr[$processKeys[$i]] = ( is_numeric($matches[$i]) ? intval($matches[$i]) : $matches[$i] ); + } + + $arr[$pKey]['Summary'] = $pArr; + } + } + } + return json_encode($arr, JSON_PRETTY_PRINT); + + } + protected static function formatConnectionStatusData(): string { return file_get_contents(static::$connectionsFile); From 916d59b7859c7f3d6a0c76a1ece46ccd2851f1dd Mon Sep 17 00:00:00 2001 From: Eric Harris Date: Tue, 29 Oct 2024 09:01:54 -0500 Subject: [PATCH 2/4] Code Cleanup of spaces. --- src/Worker.php | 56 +++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/Worker.php b/src/Worker.php index 485ede005..ed83cbb84 100644 --- a/src/Worker.php +++ b/src/Worker.php @@ -310,8 +310,8 @@ class Worker * * @var bool */ - public static bool $jsonLog = false; - + public static bool $jsonLog = false; + /** * Global event loop. * @@ -993,7 +993,7 @@ protected static function parseCommand(): void '-g' ]; $availableLog = ['-jl']; - + $command = $mode = ''; foreach (static::getArgv() as $value) { if (!$command && in_array($value, $availableCommands)) { @@ -1001,7 +1001,7 @@ protected static function parseCommand(): void } if (!$mode && in_array($value, $availableMode)) { $mode = $value; - } + } if (in_array($value, $availableLog)) { static::$jsonLog = true; } @@ -1233,12 +1233,12 @@ protected static function formatConnectionStatusDataJson( string $statusStr ): s $arr = [ $gsKey => [], $pKey => ['Records' => []] ]; $currStatus = null; $processKeys = []; - + $lines = explode("\n", $statusStr ); - + foreach($lines as $line){ $matches = []; - + if(preg_match('/GLOBAL STATUS/', $line)){ $currStatus = 'GLOBAL'; continue; @@ -1252,7 +1252,7 @@ protected static function formatConnectionStatusDataJson( string $statusStr ): s $currStatus = 'SUMMARY'; continue; } - + if( $currStatus === 'GLOBAL' ){ if( preg_match('/^Workerman version:(\S+)\s+PHP version:(\S+)/', $line, $matches ) && array_key_exists(1,$matches) && array_key_exists(2,$matches) ){ @@ -1272,72 +1272,72 @@ protected static function formatConnectionStatusDataJson( string $statusStr ): s $arr[$pKey]['Count'] = $matches[2]; } } elseif( $currStatus === 'WORKER' ){ - + if( preg_match('/^(.*?)\s(\d)\s+(\d)/', $line, $matches ) && array_key_exists(1,$matches) && array_key_exists(2,$matches) && array_key_exists(3,$matches) ){ - $arr[$gsKey]['Workers']['Records'][] = ['Name' => rtrim($matches[1]), + $arr[$gsKey]['Workers']['Records'][] = ['Name' => rtrim($matches[1]), 'Exit Status' => intval($matches[2]), 'Exit Count' => intval($matches[3])]; } } elseif( $currStatus === 'PROCESS' ){ if(preg_match('/^pid\s+memory\s+listening/', $line)) { - preg_match('/^(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*)/', - $line, + preg_match('/^(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(.*)/', + $line, $matches ); - + if( count($matches) < 3 ){ continue; } - + for($i = 1; $i < count($matches); $i++ ){ $processKeys[$i] = $matches[$i]; } - - } elseif( preg_match('/^(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(.*)/', + + } elseif( preg_match('/^(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(.*)/', $line, $matches ) ){ - + if( count($processKeys) !== count($matches) - 1 || count($processKeys) < 3 ){ //header row column count did not match row count continue; } $pArr = []; - + for( $i = 1; $i <= count($processKeys); $i++ ){ $pArr[$processKeys[$i]] = ( is_numeric($matches[$i]) ? intval($matches[$i]) : $matches[$i] ); } - $arr[$pKey]['Records'][] = $pArr; + $arr[$pKey]['Records'][] = $pArr; } } elseif( $currStatus === 'SUMMARY') { - if( preg_match('/^(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(.*)/', - $line, + if( preg_match('/^(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(.*)/', + $line, $matches ) ){ - + if( count($processKeys) !== count($matches) - 1 || count($processKeys) < 3 ){ //header row column count did not match row count continue; } - + $pArr = []; - + for( $i = 2; $i < count($processKeys); $i++ ){ if( $matches[$i] === '-' ){ continue; } $pArr[$processKeys[$i]] = ( is_numeric($matches[$i]) ? intval($matches[$i]) : $matches[$i] ); } - + $arr[$pKey]['Summary'] = $pArr; } } } return json_encode($arr, JSON_PRETTY_PRINT); - - } - + + } + protected static function formatConnectionStatusData(): string { return file_get_contents(static::$connectionsFile); From 8b1810d9911cf8860841635afe4939ca9d362854 Mon Sep 17 00:00:00 2001 From: Eric Harris Date: Tue, 29 Oct 2024 09:02:31 -0500 Subject: [PATCH 3/4] Code Cleanup of spaces again. --- src/Worker.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Worker.php b/src/Worker.php index ed83cbb84..035354063 100644 --- a/src/Worker.php +++ b/src/Worker.php @@ -1295,7 +1295,7 @@ protected static function formatConnectionStatusDataJson( string $statusStr ): s } } elseif( preg_match('/^(.*?)\s+(.*?)\s+(.*?)\s+(.*?)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(.*)/', - $line, + $line, $matches ) ){ if( count($processKeys) !== count($matches) - 1 || count($processKeys) < 3 ){ @@ -1329,7 +1329,7 @@ protected static function formatConnectionStatusDataJson( string $statusStr ): s $pArr[$processKeys[$i]] = ( is_numeric($matches[$i]) ? intval($matches[$i]) : $matches[$i] ); } - $arr[$pKey]['Summary'] = $pArr; + $arr[$pKey]['Summary'] = $pArr; } } } From 4b7be16e3ee4f5b4412c1973b8ddb45a109c76f9 Mon Sep 17 00:00:00 2001 From: Eric Harris Date: Tue, 29 Oct 2024 09:23:09 -0500 Subject: [PATCH 4/4] Made Count and Processes ints. --- src/Worker.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Worker.php b/src/Worker.php index 035354063..cf423a424 100644 --- a/src/Worker.php +++ b/src/Worker.php @@ -1267,9 +1267,9 @@ protected static function formatConnectionStatusDataJson( string $statusStr ): s $arr[$gsKey]['Event'] = $matches[2]; } elseif( preg_match('/^(\d+) workers\s+(\d+) processes/', $line, $matches ) && array_key_exists(1,$matches) && array_key_exists(2,$matches) ){ - $arr[$gsKey]['Workers'] = [ 'Count' => $matches[1], 'Processes' => $matches[2], + $arr[$gsKey]['Workers'] = [ 'Count' => intval($matches[1]), 'Processes' => intval($matches[2]), 'Records' => [] ]; - $arr[$pKey]['Count'] = $matches[2]; + $arr[$pKey]['Count'] = intval($matches[2]); } } elseif( $currStatus === 'WORKER' ){