From 0d3ee119424e7321f263fb2810b97bba92258000 Mon Sep 17 00:00:00 2001 From: Tim Weisenberger Date: Mon, 26 Sep 2022 10:06:34 +0200 Subject: [PATCH 1/6] BUGFIX: Correct typo in file name --- Configuration/{Settings.Dns.yaml => Settings.Dsn.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Configuration/{Settings.Dns.yaml => Settings.Dsn.yaml} (100%) diff --git a/Configuration/Settings.Dns.yaml b/Configuration/Settings.Dsn.yaml similarity index 100% rename from Configuration/Settings.Dns.yaml rename to Configuration/Settings.Dsn.yaml From efd7c519b3654ef0fe23f4812bde3f831eefcb16 Mon Sep 17 00:00:00 2001 From: Tim Weisenberger Date: Mon, 26 Sep 2022 17:39:33 +0200 Subject: [PATCH 2/6] FEATURE: Add configuration to exclude framework code and libraries --- Configuration/Settings.InAppExclude.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 Configuration/Settings.InAppExclude.yaml diff --git a/Configuration/Settings.InAppExclude.yaml b/Configuration/Settings.InAppExclude.yaml new file mode 100644 index 0000000..6216132 --- /dev/null +++ b/Configuration/Settings.InAppExclude.yaml @@ -0,0 +1,5 @@ +Netlogix: + Sentry: + inAppExclude: + - 'Packages/Framework/' + - 'Packages/Libraries/' From a52d1359c9dfc3b73b9af21711ca94679aaab727 Mon Sep 17 00:00:00 2001 From: Tim Weisenberger Date: Mon, 26 Sep 2022 17:41:13 +0200 Subject: [PATCH 3/6] FEATURE: Exclude non app code and rewrite Flow proxy classes in stack trace --- Classes/Integration/NetlogixIntegration.php | 77 +++++++++++++++++++++ Classes/Package.php | 13 +++- 2 files changed, 87 insertions(+), 3 deletions(-) diff --git a/Classes/Integration/NetlogixIntegration.php b/Classes/Integration/NetlogixIntegration.php index 7a928f1..d3fc125 100644 --- a/Classes/Integration/NetlogixIntegration.php +++ b/Classes/Integration/NetlogixIntegration.php @@ -6,12 +6,15 @@ use Neos\Flow\Annotations as Flow; use Neos\Flow\Core\Bootstrap; use Neos\Flow\ObjectManagement\CompileTimeObjectManager; +use Neos\Utility\Files; use Netlogix\Sentry\ExceptionHandler\ExceptionRenderingOptionsResolver; use Netlogix\Sentry\Scope\ScopeProvider; use Sentry\Event; use Sentry\EventHint; +use Sentry\Frame; use Sentry\Integration\IntegrationInterface; use Sentry\SentrySdk; +use Sentry\Stacktrace; use Sentry\State\Scope; use Sentry\UserDataBag; use Throwable; @@ -23,6 +26,13 @@ final class NetlogixIntegration implements IntegrationInterface { + protected static array $inAppExclude; + + public function __construct(array $inAppExclude) + { + self::$inAppExclude = $inAppExclude; + } + public function setupOnce(): void { Scope::addGlobalEventProcessor(static function (Event $event, EventHint $hint): ?Event { @@ -49,11 +59,78 @@ public static function handleEvent(Event $event, EventHint $hint): ?Event } } + $rewrittenExceptions = array_map( + function ($exception) { + $stacktrace = $exception->getStacktrace(); + $exception->setStacktrace(self::rewriteStacktraceAndFlagInApp($stacktrace)); + return $exception; + }, + $event->getExceptions() + ); + + $event->setExceptions($rewrittenExceptions); + self::configureScopeForEvent($event, $hint); return $event; } + private static function rewriteStacktraceAndFlagInApp(Stacktrace $stacktrace): Stacktrace + { + $frames = array_map(function ($frame) { + $classPathAndFilename = self::getOriginalClassPathAndFilename($frame->getFile()); + return new Frame( + self::replaceProxyClassName($frame->getFunctionName()), + $classPathAndFilename, + $frame->getLine(), + self::replaceProxyClassName($frame->getRawFunctionName()), + $frame->getAbsoluteFilePath() + ? Files::concatenatePaths([FLOW_PATH_ROOT, trim($classPathAndFilename, '/')]) + : null, + $frame->getVars(), + self::isInApp($classPathAndFilename) + ); + }, $stacktrace->getFrames()); + + return new Stacktrace($frames); + } + + private static function getOriginalClassPathAndFilename(string $proxyClassPathAndFilename): string + { + if (!preg_match('#Flow_Object_Classes/[A-Za-z0-9_]+.php$#', $proxyClassPathAndFilename)) { + return $proxyClassPathAndFilename; + } + + $absolutePathAndFilename = Files::concatenatePaths([FLOW_PATH_ROOT, trim($proxyClassPathAndFilename, '/')]); + if ( + !file_exists($absolutePathAndFilename) || + !($proxyClassFile = file_get_contents($absolutePathAndFilename)) + ) { + return $proxyClassPathAndFilename; + } + + if (!preg_match('@# PathAndFilename: ([/A-Za-z0-9_.]+\.php)@', $proxyClassFile, $matches)) { + return $proxyClassPathAndFilename; + } + + return str_replace(FLOW_PATH_ROOT, '/', str_replace('_', '/', $matches[1])); + } + + private static function replaceProxyClassName(?string $className): ?string + { + return $className ? str_replace('_Original', '', $className) : null; + } + + private static function isInApp(string $path) + { + foreach (self::$inAppExclude as $excludePath) { + if (strpos($path, $excludePath) !== false) { + return false; + } + } + return true; + } + private static function configureScopeForEvent(Event $event, EventHint $hint): void { try { diff --git a/Classes/Package.php b/Classes/Package.php index 1f74683..23f21c3 100644 --- a/Classes/Package.php +++ b/Classes/Package.php @@ -19,13 +19,20 @@ public function boot(Bootstrap $bootstrap) ConfigurationManager::class, 'configurationManagerReady', static function (ConfigurationManager $configurationManager) { - $dsn = $configurationManager->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, - 'Netlogix.Sentry.dsn'); + $dsn = $configurationManager->getConfiguration( + ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, + 'Netlogix.Sentry.dsn' + ); + $inAppExclude = $configurationManager->getConfiguration( + ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, + 'Netlogix.Sentry.inAppExclude' + ); + init([ 'dsn' => $dsn, 'integrations' => [ - new NetlogixIntegration(), + new NetlogixIntegration($inAppExclude ?? []), ] ]); } From 69bcb6029261d92d0a775b024803be44b7e5b1a3 Mon Sep 17 00:00:00 2001 From: Tim Weisenberger Date: Tue, 27 Sep 2022 12:58:30 +0200 Subject: [PATCH 4/6] TASK: Allow neos composer-plugin in GitHub Actions --- .github/workflows/functionaltests.yml | 12 ++++++++---- .github/workflows/unittests.yml | 12 ++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/.github/workflows/functionaltests.yml b/.github/workflows/functionaltests.yml index e955590..bbf9341 100644 --- a/.github/workflows/functionaltests.yml +++ b/.github/workflows/functionaltests.yml @@ -31,7 +31,7 @@ jobs: extensions: mbstring, xml, json, zlib, iconv, intl, pdo_sqlite ini-values: opcache.fast_shutdown=0 - - name: "[1/4] Create composer project - Cache composer dependencies" + - name: "[1/5] Create composer project - Cache composer dependencies" uses: actions/cache@v1 with: path: ~/.composer/cache @@ -40,14 +40,18 @@ jobs: php-${{ matrix.php-version }}-flow-${{ matrix.flow-version }}-composer- php-${{ matrix.php-version }}-flow- - - name: "[2/4] Create composer project - No install" + - name: "[2/5] Create composer project - No install" run: composer create-project neos/flow-base-distribution ${{ env.FLOW_DIST_FOLDER }} --prefer-dist --no-progress --no-install "^${{ matrix.flow-version }}" - - name: "[3/4] Create composer project - Require behat in compatible version" + - name: "[3/5] Allow neos composer plugin" + run: composer config --no-plugins allow-plugins.neos/composer-plugin true + working-directory: ${{ env.FLOW_DIST_FOLDER }} + + - name: "[4/5] Create composer project - Require behat in compatible version" run: composer require --dev --no-update "neos/behat:@dev" working-directory: ${{ env.FLOW_DIST_FOLDER }} - - name: "[4/4] Create composer project - Install project" + - name: "[5/5] Create composer project - Install project" run: composer install working-directory: ${{ env.FLOW_DIST_FOLDER }} diff --git a/.github/workflows/unittests.yml b/.github/workflows/unittests.yml index c9c0932..c840ccb 100644 --- a/.github/workflows/unittests.yml +++ b/.github/workflows/unittests.yml @@ -31,7 +31,7 @@ jobs: extensions: mbstring, xml, json, zlib, iconv, intl, pdo_sqlite ini-values: opcache.fast_shutdown=0 - - name: "[1/4] Create composer project - Cache composer dependencies" + - name: "[1/5] Create composer project - Cache composer dependencies" uses: actions/cache@v1 with: path: ~/.composer/cache @@ -40,14 +40,18 @@ jobs: php-${{ matrix.php-version }}-flow-${{ matrix.flow-version }}-composer- php-${{ matrix.php-version }}-flow- - - name: "[2/4] Create composer project - No install" + - name: "[2/5] Create composer project - No install" run: composer create-project neos/flow-base-distribution ${{ env.FLOW_DIST_FOLDER }} --prefer-dist --no-progress --no-install "^${{ matrix.flow-version }}" - - name: "[3/4] Create composer project - Require behat in compatible version" + - name: "[3/5] Allow neos composer plugin" + run: composer config --no-plugins allow-plugins.neos/composer-plugin true + working-directory: ${{ env.FLOW_DIST_FOLDER }} + + - name: "[4/5] Create composer project - Require behat in compatible version" run: composer require --dev --no-update "neos/behat:@dev" working-directory: ${{ env.FLOW_DIST_FOLDER }} - - name: "[4/4] Create composer project - Install project" + - name: "[5/5] Create composer project - Install project" run: composer install working-directory: ${{ env.FLOW_DIST_FOLDER }} From c34cc27812849aadd9de46acf74fcf05c6f532db Mon Sep 17 00:00:00 2001 From: Tim Weisenberger Date: Tue, 27 Sep 2022 13:09:28 +0200 Subject: [PATCH 5/6] BUGFIX: Remove type definition for class property to ensure PHP 7.3 compatibility --- Classes/Integration/NetlogixIntegration.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Classes/Integration/NetlogixIntegration.php b/Classes/Integration/NetlogixIntegration.php index d3fc125..a535d95 100644 --- a/Classes/Integration/NetlogixIntegration.php +++ b/Classes/Integration/NetlogixIntegration.php @@ -26,7 +26,10 @@ final class NetlogixIntegration implements IntegrationInterface { - protected static array $inAppExclude; + /** + * @var array + */ + protected static $inAppExclude; public function __construct(array $inAppExclude) { From f730213696d106b4ecbe489969e09dad7ec4281b Mon Sep 17 00:00:00 2001 From: Tim Weisenberger Date: Tue, 27 Sep 2022 13:09:35 +0200 Subject: [PATCH 6/6] FEATURE: Add return type definition for isInApp method --- Classes/Integration/NetlogixIntegration.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/Integration/NetlogixIntegration.php b/Classes/Integration/NetlogixIntegration.php index a535d95..1460752 100644 --- a/Classes/Integration/NetlogixIntegration.php +++ b/Classes/Integration/NetlogixIntegration.php @@ -124,7 +124,7 @@ private static function replaceProxyClassName(?string $className): ?string return $className ? str_replace('_Original', '', $className) : null; } - private static function isInApp(string $path) + private static function isInApp(string $path): bool { foreach (self::$inAppExclude as $excludePath) { if (strpos($path, $excludePath) !== false) {