From c6c555b76345daed178ff36556b872610de66149 Mon Sep 17 00:00:00 2001 From: Matej Baco Date: Sun, 5 Dec 2021 14:07:45 +0100 Subject: [PATCH] Implemented worker error logging in a better way --- app/controllers/general.php | 1 + app/workers.php | 43 +++++++++++ composer.lock | 135 +++++++++++++++++---------------- docker-compose.yml | 3 +- src/Appwrite/Resque/Worker.php | 64 +++++----------- 5 files changed, 137 insertions(+), 109 deletions(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index e70a80058..58331c3af 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -300,6 +300,7 @@ App::error(function ($error, $utopia, $request, $response, $layout, $project, $l /** @var Appwrite\Database\Document $project */ /** @var Utopia\Logger\Logger $logger */ /** @var Appwrite\Database\Document $user */ + /** @var Utopia\Logger\Log\Breadcrumb[] $loggerBreadcrumbs */ $version = App::getEnv('_APP_VERSION', 'UNKNOWN'); $route = $utopia->match($request); diff --git a/app/workers.php b/app/workers.php index ff5ba1dbd..bfd03a6a6 100644 --- a/app/workers.php +++ b/app/workers.php @@ -2,6 +2,7 @@ use Appwrite\Extend\PDO; use Utopia\App; +use Appwrite\Resque\Worker; /** @var Utopia\Registry\Registry $register */ @@ -23,10 +24,52 @@ $register->set('db', function () { return $pdo; }); + $register->set('cache', function () { // Register cache connection $redis = new Redis(); $redis->pconnect(App::getEnv('_APP_REDIS_HOST', ''), App::getEnv('_APP_REDIS_PORT', '')); $redis->setOption(Redis::OPT_READ_TIMEOUT, -1); return $redis; +}); + +Worker::error(function ($error, $action) use ($register) { + /** @var Throwable|Exception $error */ + /** @var string $action */ + + $logger = $register->get('logger'); + + if($logger) { + $version = App::getEnv('_APP_VERSION', 'UNKNOWN'); + + $className = \get_called_class(); + $workerType = $className; + + $log = new Log(); + + $log->setNamespace("worker-" . $workerType); + $log->setServer(\gethostname()); + $log->setVersion($version); + $log->setType(Log::TYPE_ERROR); + $log->setMessage($error->getMessage()); + + $log->addTag('workerType', $workerType); + $log->addTag('code', $error->getCode()); + $log->addTag('verboseType', \get_class($error)); + + $log->addExtra('file', $error->getFile()); + $log->addExtra('line', $error->getLine()); + $log->addExtra('trace', $error->getTraceAsString()); + // $log->addExtra('args', $this->args); + // TODO: Test worker error for get_called_class and if args are in trace. What about JWT in args? Other secrets? What about realtime/API? + + $action = 'worker.' . $workerType . '.' . $action; + $log->setAction($action); + + $isProduction = App::getEnv('_APP_ENV', 'development') === 'production'; + $log->setEnvironment($isProduction ? Log::ENVIRONMENT_PRODUCTION : Log::ENVIRONMENT_STAGING); + + $responseCode = $logger->addLog($log); + Console::info('Setup log pushed with status code: ' . $responseCode); + } }); \ No newline at end of file diff --git a/composer.lock b/composer.lock index 39abde66d..d4677b5da 100644 --- a/composer.lock +++ b/composer.lock @@ -2066,7 +2066,7 @@ "source": { "type": "git", "url": "https://github.com/utopia-php/logger", - "reference": "572ada8fd774cb8c6c09aab9fe2d36cd807eee13" + "reference": "c50b16a864857cfad381917b2e6f4991f1bccc3e" }, "require": { "php": ">=7.4" @@ -2113,7 +2113,7 @@ "utopia", "warnings" ], - "time": "2021-11-29T08:40:52+00:00" + "time": "2021-11-29T11:40:17+00:00" }, { "name": "utopia-php/orchestration", @@ -3438,16 +3438,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.13.1", + "version": "v4.13.2", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "63a79e8daa781cac14e5195e63ed8ae231dd10fd" + "reference": "210577fe3cf7badcc5814d99455df46564f3c077" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/63a79e8daa781cac14e5195e63ed8ae231dd10fd", - "reference": "63a79e8daa781cac14e5195e63ed8ae231dd10fd", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077", + "reference": "210577fe3cf7badcc5814d99455df46564f3c077", "shasum": "" }, "require": { @@ -3488,9 +3488,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.2" }, - "time": "2021-11-03T20:52:16+00:00" + "time": "2021-11-30T19:35:32+00:00" }, { "name": "openlss/lib-array2xml", @@ -3885,16 +3885,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.9", + "version": "9.2.10", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "f301eb1453c9e7a1bc912ee8b0ea9db22c60223b" + "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f301eb1453c9e7a1bc912ee8b0ea9db22c60223b", - "reference": "f301eb1453c9e7a1bc912ee8b0ea9db22c60223b", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d5850aaf931743067f4bfc1ae4cbd06468400687", + "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687", "shasum": "" }, "require": { @@ -3950,7 +3950,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.9" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.10" }, "funding": [ { @@ -3958,20 +3958,20 @@ "type": "github" } ], - "time": "2021-11-19T15:21:02+00:00" + "time": "2021-12-05T09:12:13+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "3.0.5", + "version": "3.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8" + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/aa4be8575f26070b100fccb67faabb28f21f66f8", - "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", "shasum": "" }, "require": { @@ -4010,7 +4010,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.5" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" }, "funding": [ { @@ -4018,7 +4018,7 @@ "type": "github" } ], - "time": "2020-09-28T05:57:25+00:00" + "time": "2021-12-02T12:48:52+00:00" }, { "name": "phpunit/php-invoker", @@ -4306,22 +4306,27 @@ }, { "name": "psr/container", - "version": "1.1.2", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", "shasum": "" }, "require": { "php": ">=7.4.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, "autoload": { "psr-4": { "Psr\\Container\\": "src/" @@ -4348,9 +4353,9 @@ ], "support": { "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/1.1.2" + "source": "https://github.com/php-fig/container/tree/2.0.2" }, - "time": "2021-11-05T16:50:12+00:00" + "time": "2021-11-05T16:47:00+00:00" }, { "name": "sebastian/cli-parser", @@ -5370,28 +5375,29 @@ }, { "name": "symfony/console", - "version": "v5.3.11", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "3e7ab8f5905058984899b05a4648096f558bfeba" + "reference": "ec3661faca1d110d6c307e124b44f99ac54179e3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/3e7ab8f5905058984899b05a4648096f558bfeba", - "reference": "3e7ab8f5905058984899b05a4648096f558bfeba", + "url": "https://api.github.com/repos/symfony/console/zipball/ec3661faca1d110d6c307e124b44f99ac54179e3", + "reference": "ec3661faca1d110d6c307e124b44f99ac54179e3", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php73": "^1.8", "symfony/polyfill-php80": "^1.16", - "symfony/service-contracts": "^1.1|^2", - "symfony/string": "^5.1" + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/string": "^5.1|^6.0" }, "conflict": { + "psr/log": ">=3", "symfony/dependency-injection": "<4.4", "symfony/dotenv": "<5.1", "symfony/event-dispatcher": "<4.4", @@ -5403,12 +5409,12 @@ }, "require-dev": { "psr/log": "^1|^2", - "symfony/config": "^4.4|^5.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/event-dispatcher": "^4.4|^5.0", - "symfony/lock": "^4.4|^5.0", - "symfony/process": "^4.4|^5.0", - "symfony/var-dumper": "^4.4|^5.0" + "symfony/config": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/event-dispatcher": "^4.4|^5.0|^6.0", + "symfony/lock": "^4.4|^5.0|^6.0", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/var-dumper": "^4.4|^5.0|^6.0" }, "suggest": { "psr/log": "For using the console logger", @@ -5448,7 +5454,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.3.11" + "source": "https://github.com/symfony/console/tree/v5.4.0" }, "funding": [ { @@ -5464,7 +5470,7 @@ "type": "tidelift" } ], - "time": "2021-11-21T19:41:05+00:00" + "time": "2021-11-29T15:30:56+00:00" }, { "name": "symfony/polyfill-intl-grapheme", @@ -5875,22 +5881,21 @@ }, { "name": "symfony/service-contracts", - "version": "v2.5.0", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc" + "reference": "36715ebf9fb9db73db0cb24263c79077c6fe8603" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", - "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/36715ebf9fb9db73db0cb24263c79077c6fe8603", + "reference": "36715ebf9fb9db73db0cb24263c79077c6fe8603", "shasum": "" }, "require": { - "php": ">=7.2.5", - "psr/container": "^1.1", - "symfony/deprecation-contracts": "^2.1" + "php": ">=8.0.2", + "psr/container": "^2.0" }, "conflict": { "ext-psr": "<1.1|>=2" @@ -5901,7 +5906,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.0-dev" }, "thanks": { "name": "symfony/contracts", @@ -5938,7 +5943,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.5.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.0.0" }, "funding": [ { @@ -5954,35 +5959,37 @@ "type": "tidelift" } ], - "time": "2021-11-04T16:48:04+00:00" + "time": "2021-11-04T17:53:12+00:00" }, { "name": "symfony/string", - "version": "v5.3.10", + "version": "v6.0.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "d70c35bb20bbca71fc4ab7921e3c6bda1a82a60c" + "reference": "ba727797426af0f587f4800566300bdc0cda0777" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/d70c35bb20bbca71fc4ab7921e3c6bda1a82a60c", - "reference": "d70c35bb20bbca71fc4ab7921e3c6bda1a82a60c", + "url": "https://api.github.com/repos/symfony/string/zipball/ba727797426af0f587f4800566300bdc0cda0777", + "reference": "ba727797426af0f587f4800566300bdc0cda0777", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.0.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "~1.15" + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.0" }, "require-dev": { - "symfony/error-handler": "^4.4|^5.0", - "symfony/http-client": "^4.4|^5.0", - "symfony/translation-contracts": "^1.1|^2", - "symfony/var-exporter": "^4.4|^5.0" + "symfony/error-handler": "^5.4|^6.0", + "symfony/http-client": "^5.4|^6.0", + "symfony/translation-contracts": "^2.0|^3.0", + "symfony/var-exporter": "^5.4|^6.0" }, "type": "library", "autoload": { @@ -6021,7 +6028,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.3.10" + "source": "https://github.com/symfony/string/tree/v6.0.0" }, "funding": [ { @@ -6037,7 +6044,7 @@ "type": "tidelift" } ], - "time": "2021-10-27T18:21:46+00:00" + "time": "2021-10-29T07:35:21+00:00" }, { "name": "textalk/websocket", diff --git a/docker-compose.yml b/docker-compose.yml index f01d6c0b1..d6aba1a22 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -71,7 +71,7 @@ services: - ./psalm.xml:/usr/src/code/psalm.xml - ./tests:/usr/src/code/tests - ./app:/usr/src/code/app - # - ./vendor:/usr/src/code/vendor + - ./vendor:/usr/src/code/vendor - ./docs:/usr/src/code/docs - ./public:/usr/src/code/public - ./src:/usr/src/code/src @@ -160,6 +160,7 @@ services: volumes: - ./app:/usr/src/code/app - ./src:/usr/src/code/src + - ./vendor:/usr/src/code/vendor depends_on: - redis environment: diff --git a/src/Appwrite/Resque/Worker.php b/src/Appwrite/Resque/Worker.php index d2979fd25..b9972ed24 100644 --- a/src/Appwrite/Resque/Worker.php +++ b/src/Appwrite/Resque/Worker.php @@ -2,14 +2,16 @@ namespace Appwrite\Resque; -abstract class Worker +use Exception; + +class Worker { /** * Callbacks that will be executed when an error occurs * * @var array */ - protected $errorCallbacks = []; + static protected array $errorCallbacks = []; /** * Associative array holding all information passed into the worker @@ -22,8 +24,12 @@ abstract class Worker * Function for identifying the worker needs to be set to unique name * * @return string + * @throws Exception */ - abstract public function getName(): string; + public function getName(): string + { + throw new Exception("Please implement getName method in worker"); + } /** * Function executed before running first task. @@ -32,7 +38,9 @@ abstract class Worker * @return void * @throws \Exception|\Throwable */ - abstract public function init(): void; + public function init() { + throw new Exception("Please implement getName method in worker"); + } /** * Function executed when new task requests is received. @@ -41,7 +49,9 @@ abstract class Worker * @return void * @throws \Exception|\Throwable */ - abstract public function run(): void; + public function run() { + throw new Exception("Please implement getName method in worker"); + } /** * Function executed just before shutting down the worker. @@ -50,7 +60,9 @@ abstract class Worker * @return void * @throws \Exception|\Throwable */ - abstract public function shutdown(): void; + public function shutdown() { + throw new Exception("Please implement getName method in worker"); + } /** * A wrapper around 'init' function with non-worker-specific code @@ -116,44 +128,8 @@ abstract class Worker * @param Throwable $error * @return self */ - public function error(callable $callback): self + public static function error(callable $callback): void { - \array_push($this->errorCallbacks, $callback); - return $this; + \array_push(self::$errorCallbacks, $callback); } - - // TODO: Implement this on init file using Worker->error(function() { HERE }) - //global $register; - //$logger = $register->get('logger'); - // - //if($logger) { - //$version = App::getEnv('_APP_VERSION', 'UNKNOWN'); - //$workerType = $this->getName(); - // - //$log = new Log(); - // - //$log->setNamespace("worker-" . $workerType); - //$log->setServer(\gethostname()); - //$log->setVersion($version); - //$log->setType(Log::TYPE_ERROR); - //$log->setMessage($error->getMessage()); - // - //$log->addTag('workerType', $workerType); - //$log->addTag('code', $error->getCode()); - //$log->addTag('verboseType', \get_class($error)); - // - //$log->addExtra('file', $error->getFile()); - //$log->addExtra('line', $error->getLine()); - //$log->addExtra('trace', $error->getTraceAsString()); - //$log->addExtra('args', $this->args); - // - //$action = 'worker.' . $workerType . '.setUp'; - //$log->setAction($action); - // - //$isProduction = App::getEnv('_APP_ENV', 'development') === 'production'; - //$log->setEnvironment($isProduction ? Log::ENVIRONMENT_PRODUCTION : Log::ENVIRONMENT_STAGING); - // - //$responseCode = $logger->addLog($log); - //Console::info('Setup log pushed with status code: '.$responseCode); - //} }