From 0043cfdccfc7a6933a44d8ff18e361231e822525 Mon Sep 17 00:00:00 2001 From: guandeng Date: Sun, 23 Jun 2024 22:00:59 +0800 Subject: [PATCH] Added Telescope recording and pause functions (#678) * Support telescope ability * Support recording * Optimizing the code * feat: Refactor telescope recording and caching logic * chore: Update Psr\Container\ContainerInterface::get() override in .phpstorm.meta.php * feat: Update EntriesController to use ApplicationInterface for clearing Telescope entries * feat: Update Psr\Container\ContainerInterface::get() override in .phpstorm.meta.php * chore: Update Psr\Container\ContainerInterface::get() override in .phpstorm.meta.php * feat: Update EntriesController to use ApplicationInterface for clearing Telescope entries * Update Telescope::getCache() to return PsrCacheInterface instead of CacheInterface * Added `Telescope::isRecording()` function * Moved `Telescope::isRecording()` condition to `TelescopeConfig isEnable()` * Optimized * Optimized * Update tests * Remove unused codes * Optimize Telescope::isRecording() condition * Optimize Telescope::isRecording() condition * Optimize Telescope::isRecording() condition * Optimize Telescope::isRecording() condition and update caching logic * Optimize Telescope::isRecording() condition and caching logic * Optimize Telescope::isRecording() condition and caching logic * Optimize Telescope::isRecording() condition and update caching logic * chore: Optimize Telescope::isRecording() condition and caching logic * Optimize Telescope::isRecording() condition and caching logic * chore: Optimize Telescope::isRecording() condition and caching logic * Refactor parse recording * Optimize Telescope::isRecording() condition and caching logic * chore: Disable Telescope filter for cache entries with 'telescope:' prefix * Optimized * chore: Optimize caching logic in Telescope::getCache() method * Optimize caching logic in CacheAspect.php * Optimize caching logic in TelescopeConfig.php * chore: Remove SetupTelescopeFilterListener and optimize caching logic in TelescopeConfig.php and CacheAspect.php * Optimize caching logic in CacheAspect.php * Optimize caching logic in CacheAspect.php * Optimize caching logic in CacheAspect.php * Optimize caching logic in CacheAspect.php * chore: Optimize caching logic in TelescopeConfig.php and CacheAspect.php * chore: Optimize caching logic in TelescopeConfig.php and CacheAspect.php * optimize code * optimize code * optimize code --------- Co-authored-by: 10951 Co-authored-by: Deeka Wong <8337659+huangdijia@users.noreply.github.com> --- src/Aspect/CacheAspect.php | 3 +- src/ConfigProvider.php | 36 +++++++++--------- src/Contract/CacheInterface.php | 18 +++++++++ src/Controller/EntriesController.php | 35 +++++++++++++++++ src/Controller/EntryController.php | 10 +++-- src/Controller/RecordingController.php | 33 ++++++++++++++++ src/Controller/ViewController.php | 10 ++++- src/Listener/CommandListener.php | 2 +- src/Listener/DbQueryListener.php | 2 +- src/Listener/ExceptionHandlerListener.php | 2 +- src/Listener/RequestHandledListener.php | 1 + src/Telescope.php | 29 +++++++------- src/TelescopeConfig.php | 46 ++++++++++++++++++++++- storage/view/index.blade.php | 34 ++++++++++++++--- 14 files changed, 214 insertions(+), 47 deletions(-) create mode 100644 src/Contract/CacheInterface.php create mode 100644 src/Controller/EntriesController.php create mode 100644 src/Controller/RecordingController.php diff --git a/src/Aspect/CacheAspect.php b/src/Aspect/CacheAspect.php index c72c1a4..25ba4b1 100644 --- a/src/Aspect/CacheAspect.php +++ b/src/Aspect/CacheAspect.php @@ -15,7 +15,6 @@ use FriendsOfHyperf\Telescope\Telescope; use FriendsOfHyperf\Telescope\TelescopeConfig; use FriendsOfHyperf\Telescope\TelescopeContext; -use Hyperf\Cache\CacheManager; use Hyperf\Contract\ConfigInterface; use Hyperf\Contract\PackerInterface; use Hyperf\Di\Aop\AbstractAspect; @@ -30,7 +29,7 @@ class CacheAspect extends AbstractAspect { public array $classes = [ - CacheManager::class . '::getDriver', + 'Hyperf\Cache\CacheManager::getDriver', 'Hyperf\Cache\Driver\*Driver::fetch', 'Hyperf\Cache\Driver\*Driver::get', 'Hyperf\Cache\Driver\*Driver::set', diff --git a/src/ConfigProvider.php b/src/ConfigProvider.php index 501e6d5..8536987 100644 --- a/src/ConfigProvider.php +++ b/src/ConfigProvider.php @@ -18,17 +18,12 @@ public function __invoke(): array defined('BASE_PATH') or define('BASE_PATH', ''); return [ - 'commands' => [ - Command\ClearCommand::class, - Command\InstallCommand::class, - Command\PruneCommand::class, - ], - 'listeners' => [ - Listener\SetRequestLifecycleListener::class, - Listener\CommandListener::class, - Listener\DbQueryListener::class, - Listener\ExceptionHandlerListener::class, - Listener\SetupTelescopeServerListener::class, + 'annotations' => [ + 'scan' => [ + 'paths' => [ + __DIR__, + ], + ], ], 'aspects' => [ Aspect\CoroutineAspect::class, @@ -42,12 +37,19 @@ public function __invoke(): array Aspect\RequestDispatcherAspect::class, Aspect\GrpcCoreMiddlewareAspect::class, ], - 'annotations' => [ - 'scan' => [ - 'paths' => [ - __DIR__, - ], - ], + 'commands' => [ + Command\ClearCommand::class, + Command\InstallCommand::class, + Command\PruneCommand::class, + ], + 'dependencies' => [ + ], + 'listeners' => [ + Listener\SetRequestLifecycleListener::class, + Listener\CommandListener::class, + Listener\DbQueryListener::class, + Listener\ExceptionHandlerListener::class, + Listener\SetupTelescopeServerListener::class, ], 'publish' => [ [ diff --git a/src/Contract/CacheInterface.php b/src/Contract/CacheInterface.php new file mode 100644 index 0000000..462d14d --- /dev/null +++ b/src/Contract/CacheInterface.php @@ -0,0 +1,18 @@ +get(ApplicationInterface::class); + $application->setAutoExit(false); + $application->run( + new ArrayInput(['command' => 'telescope:clear']) + ); + } +} diff --git a/src/Controller/EntryController.php b/src/Controller/EntryController.php index 6cfcf2b..3e6c363 100644 --- a/src/Controller/EntryController.php +++ b/src/Controller/EntryController.php @@ -14,6 +14,7 @@ use FriendsOfHyperf\Telescope\EntryType; use FriendsOfHyperf\Telescope\Model\TelescopeEntryModel; use FriendsOfHyperf\Telescope\Model\TelescopeEntryTagModel; +use FriendsOfHyperf\Telescope\TelescopeConfig; use Hyperf\Di\Annotation\Inject; use Hyperf\HttpServer\Contract\RequestInterface; use Hyperf\HttpServer\Contract\ResponseInterface; @@ -31,6 +32,9 @@ abstract class EntryController #[Inject] protected ResponseInterface $response; + #[Inject] + protected TelescopeConfig $telescopeConfig; + public function index() { $before = $this->request->input('before'); @@ -114,11 +118,9 @@ abstract protected function watcher(); /** * Determine the watcher recording status. - * - * @return string */ - protected function status() + protected function status(): string { - return 'enabled'; + return $this->telescopeConfig->isRecording() ? 'enabled' : 'paused'; } } diff --git a/src/Controller/RecordingController.php b/src/Controller/RecordingController.php new file mode 100644 index 0000000..122cceb --- /dev/null +++ b/src/Controller/RecordingController.php @@ -0,0 +1,33 @@ +telescopeConfig->isRecording() ? $this->telescopeConfig->pauseRecording() : $this->telescopeConfig->continueRecording(); + } +} diff --git a/src/Controller/ViewController.php b/src/Controller/ViewController.php index fe59d38..aeaeb0f 100644 --- a/src/Controller/ViewController.php +++ b/src/Controller/ViewController.php @@ -11,6 +11,7 @@ namespace FriendsOfHyperf\Telescope\Controller; +use FriendsOfHyperf\Telescope\Telescope; use Hyperf\Di\Annotation\Inject; use Hyperf\HttpServer\Annotation\Controller; use Hyperf\HttpServer\Annotation\GetMapping; @@ -40,8 +41,15 @@ public function index() if (! isset($this->caches[$blade])) { $this->caches[$blade] = file_get_contents($blade); } + $templateContent = $this->caches[$blade]; + $params = [ + '$telescopeScriptVariables' => json_encode(Telescope::scriptVariables()), + ]; + foreach ($params as $key => $value) { + $templateContent = str_replace($key, $value, $templateContent); + } - return $this->response->html($this->caches[$blade]); + return $this->response->html($templateContent); } #[GetMapping(path: '/telescope/{view}/{id}')] diff --git a/src/Listener/CommandListener.php b/src/Listener/CommandListener.php index cd3bd00..9f76229 100644 --- a/src/Listener/CommandListener.php +++ b/src/Listener/CommandListener.php @@ -40,7 +40,7 @@ public function listen(): array */ public function process(object $event): void { - if ($this->telescopeConfig->isEnable('command') === false) { + if (! $this->telescopeConfig->isEnable('command')) { return; } diff --git a/src/Listener/DbQueryListener.php b/src/Listener/DbQueryListener.php index 07d6830..2e88d23 100644 --- a/src/Listener/DbQueryListener.php +++ b/src/Listener/DbQueryListener.php @@ -37,7 +37,7 @@ public function listen(): array */ public function process(object $event): void { - if ($this->telescopeConfig->isEnable('db') === false) { + if (! $this->telescopeConfig->isEnable('db')) { return; } if ($event instanceof QueryExecuted) { diff --git a/src/Listener/ExceptionHandlerListener.php b/src/Listener/ExceptionHandlerListener.php index f760d7b..8e1d825 100644 --- a/src/Listener/ExceptionHandlerListener.php +++ b/src/Listener/ExceptionHandlerListener.php @@ -39,7 +39,7 @@ public function listen(): array */ public function process(object $event): void { - if ($this->telescopeConfig->isEnable('exception') === false) { + if (! $this->telescopeConfig->isEnable('exception')) { return; } diff --git a/src/Listener/RequestHandledListener.php b/src/Listener/RequestHandledListener.php index 53141dd..edeefa5 100644 --- a/src/Listener/RequestHandledListener.php +++ b/src/Listener/RequestHandledListener.php @@ -57,6 +57,7 @@ public function process(object $event): void if (! $this->telescopeConfig->isEnable('request')) { return; } + match ($event::class) { RequestReceived::class, RpcRequestReceived::class => $this->requestReceived($event), RequestTerminated::class, RpcRequestTerminated::class => $this->requestHandled($event), diff --git a/src/Telescope.php b/src/Telescope.php index 230fd31..253eb10 100644 --- a/src/Telescope.php +++ b/src/Telescope.php @@ -15,8 +15,6 @@ use Hyperf\Collection\Arr; use Hyperf\Context\ApplicationContext; -use function Hyperf\Config\config; - class Telescope { public const SYNC = 0; @@ -54,11 +52,6 @@ class Telescope */ public static bool $useDarkTheme = false; - /** - * Indicates if Telescope should record entries. - */ - public static bool $shouldRecord = false; - /** * Indicates if Telescope migrations will be run. */ @@ -145,10 +138,8 @@ public static function getPath(): string /** * Add a callback that adds tags to the record. - * - * @return static */ - public static function tag(Closure $callback) + public static function tag(Closure $callback): static { static::$tagUsing[] = $callback; @@ -157,10 +148,8 @@ public static function tag(Closure $callback) /** * Set the callback that filters the entries that should be recorded. - * - * @return static */ - public static function filter(Closure $callback) + public static function filter(Closure $callback): static { static::$filterUsing[] = $callback; @@ -172,6 +161,18 @@ public static function getConfig(): TelescopeConfig return ApplicationContext::getContainer()->get(TelescopeConfig::class); } + /** + * Get the default JavaScript variables for Telescope. + */ + public static function scriptVariables(): array + { + return [ + 'path' => static::getConfig()->getPath(), + 'timezone' => static::getConfig()->getTimezone(), + 'recording' => static::getConfig()->isRecording(), + ]; + } + /** * Determine if the given entry should be recorded. */ @@ -199,7 +200,7 @@ protected static function record(string $type, IncomingEntry $entry): void return $tagCallback($entry); }, static::$tagUsing))); - match (config('telescope.save_mode', 0)) { + match (static::getConfig()->getSaveMode()) { self::ASYNC => TelescopeContext::addEntry($entry), self::SYNC => $entry->create(), default => $entry->create(), diff --git a/src/TelescopeConfig.php b/src/TelescopeConfig.php index cfe5780..052b214 100644 --- a/src/TelescopeConfig.php +++ b/src/TelescopeConfig.php @@ -11,12 +11,16 @@ namespace FriendsOfHyperf\Telescope; +use FriendsOfHyperf\Telescope\Contract\CacheInterface; use FriendsOfHyperf\Telescope\Server\Server; +use Hyperf\Context\ApplicationContext; +use Hyperf\Context\Context; use Hyperf\Contract\ConfigInterface; use Hyperf\Server\Event; use Hyperf\Server\ServerInterface; use Hyperf\Stringable\Str; use Psr\Http\Message\ServerRequestInterface; +use Psr\SimpleCache\CacheInterface as PsrCacheInterface; class TelescopeConfig { @@ -91,7 +95,7 @@ public function getDatabaseQuerySlow(): int public function isEnable(string $key): bool { - return (bool) $this->get('enable.' . $key, false); + return ((bool) $this->get('enable.' . $key, false)) && $this->isRecording(); } public function getAppName(): string @@ -186,4 +190,44 @@ public function getIgnoreCommands(): array { return $this->get('ignore_commands', []); } + + public function pauseRecording(): void + { + $this->getCache()?->set($this->getPauseRecordingCacheKey(), 1); + } + + public function continueRecording(): void + { + $this->getCache()?->delete($this->getPauseRecordingCacheKey()); + } + + public function isRecording(): bool + { + if (Context::has($key = $this->getPauseRecordingCacheKey())) { + return false; + } + + try { + Context::set($key, true); + return ((bool) $this->getCache()?->get($key)) === false; + } finally { + Context::destroy($key); + } + } + + private function getPauseRecordingCacheKey(): string + { + return sprintf('telescope:%s:recording:pause', $this->getAppName()); + } + + private function getCache(): ?PsrCacheInterface + { + $container = ApplicationContext::getContainer(); + + return match (true) { + $container->has(CacheInterface::class) => $container->get(CacheInterface::class), + $container->has(PsrCacheInterface::class) => $container->get(PsrCacheInterface::class), + default => null, + }; + } } diff --git a/storage/view/index.blade.php b/storage/view/index.blade.php index 9c44c8c..98ae28f 100644 --- a/storage/view/index.blade.php +++ b/storage/view/index.blade.php @@ -22,10 +22,34 @@
- + + + + + + +
@@ -111,7 +135,7 @@