From 6aadd9d3681dc95411edd9284f93258b35abc390 Mon Sep 17 00:00:00 2001 From: Roel van Hintum Date: Tue, 26 Nov 2019 10:24:44 +0100 Subject: [PATCH] Initial commit --- .gitignore | 2 + CHANGELOG.md | 5 +++ LICENSE.md | 21 ++++++++++ README.md | 43 ++++++++++++++++++++ composer.json | 41 +++++++++++++++++++ src/Plugin.php | 52 ++++++++++++++++++++++++ src/icon.svg | 11 +++++ src/models/Settings.php | 23 +++++++++++ src/services/SentryService.php | 73 ++++++++++++++++++++++++++++++++++ 9 files changed, 271 insertions(+) create mode 100644 .gitignore create mode 100644 CHANGELOG.md create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 composer.json create mode 100644 src/Plugin.php create mode 100644 src/icon.svg create mode 100644 src/models/Settings.php create mode 100644 src/services/SentryService.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d8b2ded --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +/vendor \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..2a50a77 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Craft Sentry Changelog + +## 1.0.0-beta.1 - 2019-11-25 +### Added +- Initial Release diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..f33a49b --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Born05 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..7dda0b7 --- /dev/null +++ b/README.md @@ -0,0 +1,43 @@ +# Sentry plugin for Craft CMS 3 + +Pushes Craft CMS errors to [Sentry](https://sentry.io/). +Does not log exceptions in devMode. + +## Installation + +### Plugin Store +1. Search for 'Sentry SDK'. +2. Hit install +3. Create a config file as explained below. + +### Composer +1. Run: `composer require born05/craft-sentry` +2. Hit install in Admin > Settings > Plugins +3. Create a config file as explained below. + +## Requirements +- Craft 3.1 or later +- PHP 7.1 at least + +## Configuring Sentry +Create a `config/sentry-sdk.php` config file with the following contents: + +```php + true, + 'anonymous' => false, // Determines to log user info or not + 'clientDsn' => getenv('SENTRY_DSN') ?: 'https://example@sentry.io/123456789', // Set as string or use environment variable. + 'excludedCodes' => ['400', '404', '429'], + 'release' => getenv('SENTRY_RELEASE') ?: null, // Release number/name used by sentry. +]; +``` + +## Credits +Based upon the sentry plugin by [Luke Youell](https://github.com/lukeyouell). + +## License +Copyright © 2019 [Born05](https://www.born05.com/) + +See [license](https://github.com/born05/craft-sentry/blob/master/LICENSE.md) diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..42a0100 --- /dev/null +++ b/composer.json @@ -0,0 +1,41 @@ +{ + "name": "born05/craft-sentry", + "description": "Pushes Craft CMS errors to Sentry.", + "type": "craft-plugin", + "version": "1.0.0-beta.1", + "keywords": [ + "craft", + "cms", + "craftcms", + "craft-plugin", + "sentry", + "sentry sdk" + ], + "support": { + "docs": "https://github.com/born05/craft-sentry/blob/master/README.md", + "issues": "https://github.com/born05/craft-sentry/issues" + }, + "license": "MIT", + "authors": [ + { + "name": "Born05", + "homepage": "https://www.born05.com/" + } + ], + "require": { + "craftcms/cms": "^3.1", + "sentry/sdk": "^2.0.4" + }, + "autoload": { + "psr-4": { + "born05\\sentry\\": "src/" + } + }, + "extra": { + "name": "Sentry SDK", + "handle": "sentry-sdk", + "hasCpSettings": false, + "hasCpSection": false, + "changelogUrl": "https://raw.githubusercontent.com/born05/craft-sentry/master/CHANGELOG.md" + } +} diff --git a/src/Plugin.php b/src/Plugin.php new file mode 100644 index 0000000..a2f5879 --- /dev/null +++ b/src/Plugin.php @@ -0,0 +1,52 @@ +setComponents([ + 'sentry' => SentryService::class, + ]); + + Event::on( + ErrorHandler::className(), + ErrorHandler::EVENT_BEFORE_HANDLE_EXCEPTION, + function(ExceptionEvent $event) { + $this->sentry->handleException($event->exception); + } + ); + } + + /** + * @inheritdoc + */ + protected function createSettingsModel() + { + return new Settings(); + } +} diff --git a/src/icon.svg b/src/icon.svg new file mode 100644 index 0000000..6bfe2ef --- /dev/null +++ b/src/icon.svg @@ -0,0 +1,11 @@ + + + + + + + + icon + + + diff --git a/src/models/Settings.php b/src/models/Settings.php new file mode 100644 index 0000000..225290b --- /dev/null +++ b/src/models/Settings.php @@ -0,0 +1,23 @@ +getInfo(); + $plugin = SentryPlugin::$plugin; + $settings = $plugin->getSettings(); + + if (!$settings->enabled || $app->getConfig()->getGeneral()->devMode) return; + + if (!$settings->clientDsn) { + Craft::error('Failed to report exception due to missing client key (DSN)', $plugin->handle); + return; + } + + // If this is a Twig Runtime exception, use the previous one instead + if ($exception instanceof \Twig_Error_Runtime && ($previousException = $exception->getPrevious()) !== null) { + $exception = $previousException; + } + + $statusCode = $exception->statusCode ?? null; + + if (in_array($statusCode, $settings->excludedCodes)) { + Craft::info('Exception status code excluded from being reported to Sentry.', $plugin->handle); + return; + } + + Sentry\init([ + 'dsn' => $settings->clientDsn, + 'environment' => CRAFT_ENVIRONMENT, + 'release' => $settings->release, + ]); + + $user = $app->getUser()->getIdentity(); + + Sentry\configureScope(function (Scope $scope) use ($app, $info, $plugin, $settings, $user, $statusCode) { + if ($user && !$settings->anonymous) { + $scope->setUser([ + 'ID' => $user->id, + 'Username' => $user->username, + 'Email' => $user->email, + 'Admin' => $user->admin ? 'Yes' : 'No', + ]); + } + + $scope->setExtra('App Type', 'Craft CMS'); + $scope->setExtra('App Name', $info->name); + $scope->setExtra('App Edition (licensed)', $app->getLicensedEditionName()); + $scope->setExtra('App Edition (running)', $app->getEditionName()); + $scope->setExtra('App Version', $info->version); + $scope->setExtra('App Version (schema)', $info->schemaVersion); + $scope->setExtra('PHP Version', phpversion()); + $scope->setExtra('Status Code', $statusCode); + }); + + Sentry\captureException($exception); + } +}