Skip to content

Commit a6ac733

Browse files
committed
initial commit
1 parent 00ec7f0 commit a6ac733

File tree

101 files changed

+4952
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+4952
-0
lines changed

.gitattributes

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.gitattributes export-ignore
2+
.gitignore export-ignore
3+
.travis.yml export-ignore
4+
phpcs.xml export-ignore
5+
phpstan.neon export-ignore
6+
phpunit.xml export-ignore
7+
tests export-ignore

.github/codecov.yml

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
codecov:
2+
require_ci_to_pass: yes
3+
4+
coverage:
5+
range: "90...100"
6+
7+
comment: false

.github/workflows/ci.yml

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- 'main'
7+
pull_request:
8+
branches:
9+
- '*'
10+
11+
permissions:
12+
contents: read # to fetch code (actions/checkout)
13+
14+
jobs:
15+
testsuite-linux:
16+
runs-on: ubuntu-22.04
17+
strategy:
18+
fail-fast: false
19+
matrix:
20+
php-version: ['7.4', '8.0', '8.1']
21+
dependencies: ['highest']
22+
include:
23+
- php-version: '7.4'
24+
dependencies: 'lowest'
25+
- php-version: '8.1'
26+
dependencies: 'highest'
27+
28+
steps:
29+
- uses: actions/checkout@v3
30+
31+
- name: Setup PHP
32+
uses: shivammathur/setup-php@v2
33+
with:
34+
php-version: ${{ matrix.php-version }}
35+
extensions: mbstring, intl
36+
ini-values: zend.assertions=1
37+
coverage: pcov
38+
39+
- name: Composer install
40+
uses: ramsey/composer-install@v2
41+
with:
42+
dependency-versions: ${{ matrix.dependencies }}
43+
composer-options: ${{ matrix.composer-options }}
44+
45+
- name: Run PHPUnit
46+
run: |
47+
if [[ ${{ matrix.php-version }} == '8.1' && ${{ matrix.dependencies }} == 'highest' ]]; then
48+
export CODECOVERAGE=1 && vendor/bin/phpunit --verbose --coverage-clover=coverage.xml
49+
else
50+
vendor/bin/phpunit
51+
fi
52+
- name: Code Coverage Report
53+
if: success() && matrix.php-version == '8.1' && matrix.dependencies == 'highest'
54+
uses: codecov/codecov-action@v3

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/vendor
2+
composer.lock
3+
.phpunit.result.cache
4+
/setup

README.md

+181
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# CakePHP Sentry Plugin
2+
CakePHP integration for Sentry.
3+
4+
ℹ️ This is a refactored version of https://github.com/Connehito/cake-sentry to remove deprecation warnings introduced in CakePHP 4.4 ℹ️
5+
6+
## Requirements
7+
- PHP 7.4+ / PHP 8.0+
8+
- CakePHP 4.4+
9+
- and a [Sentry](https://sentry.io) account
10+
11+
## Installation
12+
### With composer install.
13+
```
14+
composer require lordsimal/cakephp-sentry
15+
```
16+
17+
## Usage
18+
19+
### Set config files.
20+
```php
21+
// in `config/app.php`
22+
return [
23+
'Sentry' => [
24+
'dsn' => '<sentry-dsn-url>'
25+
]
26+
];
27+
```
28+
29+
### Loading plugin.
30+
In Application.php
31+
```php
32+
public function bootstrap()
33+
{
34+
parent::bootstrap();
35+
36+
$this->addPlugin(\CakeSentry\Plugin::class);
37+
}
38+
```
39+
40+
Or use the cake CLI.
41+
```
42+
bin/cake plugin load LordSimal/CakeSentry
43+
```
44+
45+
That's all! 🎉
46+
47+
⚠️️ If events (error/exception) are not captured in Sentry try changing the order in which the plugins are loaded.
48+
49+
### Advanced Usage
50+
51+
#### Ignore specific exceptions
52+
You can filter out noisy exceptions which should not be debugged further.
53+
54+
```php
55+
// in `config/app.php`
56+
'Error' => [
57+
'skipLog' => [
58+
NotFoundException::class,
59+
MissingRouteException::class,
60+
MissingControllerException::class,
61+
],
62+
]
63+
```
64+
65+
Also see [CakePHP Cookbook](https://book.cakephp.org/4/en/development/errors.html#error-exception-configuration)
66+
67+
### Set Options
68+
Everything inside the `'Sentry'` configuration key will be passed to `\Sentry\init()`.
69+
Please check Sentry's official documentation on [about configuration](https://docs.sentry.io/error-reporting/configuration/?platform=php) and [about php-sdk's configuraion](https://docs.sentry.io/platforms/php/#php-specific-options).
70+
71+
CakeSentry also provides custom event hooks to set dynamic values.
72+
73+
| Event Name | Description |
74+
|-----------------------------------|------------------------------------------------------|
75+
| `CakeSentry.Client.afterSetup` | General config for e.g. a release info |
76+
| `CakeSentry.Client.beforeCapture` | Before an error or exception is being sent to sentry |
77+
| `CakeSentry.Client.afterCapture` | After an error or exception has been sent to sentry |
78+
79+
### Example for `CakeSentry.Client.afterSetup`
80+
81+
```php
82+
use Cake\Event\Event;
83+
use Cake\Event\EventListenerInterface;
84+
85+
class SentryOptionsContext implements EventListenerInterface
86+
{
87+
public function implementedEvents(): array
88+
{
89+
return [
90+
'CakeSentry.Client.afterSetup' => 'setServerContext',
91+
];
92+
}
93+
94+
public function setServerContext(Event $event): void
95+
{
96+
/** @var Client $subject */
97+
$subject = $event->getSubject();
98+
$options = $subject->getHub()->getClient()->getOptions();
99+
100+
$options->setEnvironment('test_app');
101+
$options->setRelease('3.0.0@dev');
102+
}
103+
}
104+
```
105+
106+
And in `config/bootstrap.php`
107+
```php
108+
\Cake\Event\EventManager::instance()->on(new SentryOptionsContext());
109+
```
110+
111+
### Example for `CakeSentry.Client.beforeCapture`
112+
113+
```php
114+
use Cake\Event\Event;
115+
use Cake\Event\EventListenerInterface;
116+
use Cake\Http\ServerRequest;
117+
use Cake\Http\ServerRequestFactory;
118+
use Sentry\State\Scope;
119+
120+
use function Sentry\configureScope as sentryConfigureScope;
121+
122+
class SentryErrorContext implements EventListenerInterface
123+
{
124+
public function implementedEvents(): array
125+
{
126+
return [
127+
'CakeSentry.Client.beforeCapture' => 'setContext',
128+
];
129+
}
130+
131+
public function setContext(Event $event): void
132+
{
133+
if (PHP_SAPI !== 'cli') {
134+
/** @var ServerRequest $request */
135+
$request = $event->getData('request') ?? ServerRequestFactory::fromGlobals();
136+
$request->trustProxy = true;
137+
138+
sentryConfigureScope(function (Scope $scope) use ($request, $event) {
139+
$scope->setTag('app_version', $request->getHeaderLine('App-Version') ?: 1.0);
140+
$exception = $event->getData('exception');
141+
if ($exception) {
142+
assert($exception instanceof \Exception);
143+
$scope->setTag('status', $exception->getCode());
144+
}
145+
$scope->setUser(['ip_address' => $request->clientIp()]);
146+
$scope->setExtras([
147+
'foo' => 'bar',
148+
'request attributes' => $request->getAttributes(),
149+
]);
150+
});
151+
}
152+
}
153+
}
154+
```
155+
156+
And in `config/bootstrap.php`
157+
```php
158+
\Cake\Event\EventManager::instance()->on(new SentryErrorContext());
159+
```
160+
161+
### Example for `CakeSentry.Client.afterCapture`
162+
163+
```php
164+
class SentryErrorContext implements EventListenerInterface
165+
{
166+
public function implementedEvents(): array
167+
{
168+
return [
169+
'CakeSentry.Client.afterCapture' => 'callbackAfterCapture',
170+
];
171+
}
172+
173+
public function callbackAfterCapture(Event $event): void
174+
{
175+
$lastEventId = $event->getData('lastEventId');
176+
}
177+
}
178+
```
179+
180+
## License
181+
The plugin is available as open source under the terms of the [MIT License](https://github.com/lordsimal/cakephp-sentry/blob/master/LICENSE).

composer.json

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"name": "lordsimal/cakephp-sentry",
3+
"description": "Sentry plugin for CakePHP",
4+
"type": "cakephp-plugin",
5+
"require": {
6+
"php": "^7.4 || ^8.0",
7+
"cakephp/cakephp": "^4.4",
8+
"sentry/sdk": "^3.2"
9+
},
10+
"require-dev": {
11+
"cakephp/cakephp-codesniffer": "@stable",
12+
"jangregor/phpstan-prophecy": "@stable",
13+
"phpspec/prophecy-phpunit": "^2.0",
14+
"phpstan/phpstan": "@stable",
15+
"phpunit/phpunit": "^9.3",
16+
"symfony/http-client": "^5.2"
17+
},
18+
"license": "MIT",
19+
"autoload": {
20+
"psr-4": {
21+
"CakeSentry\\": "src/"
22+
}
23+
},
24+
"autoload-dev": {
25+
"psr-4": {
26+
"CakeSentry\\Test\\": "tests/"
27+
}
28+
},
29+
"scripts": {
30+
"test": "phpunit",
31+
"cs-check": "phpcs --colors -p ./src ./tests/TestCase",
32+
"cs-fix": "phpcbf --colors -p ./src ./tests/TestCase"
33+
},
34+
"config": {
35+
"sort-packages": true,
36+
"allow-plugins": {
37+
"dealerdirect/phpcodesniffer-composer-installer": true
38+
}
39+
},
40+
"authors": [
41+
{
42+
"name": "Kevin Pfeifer",
43+
"email": "[email protected]",
44+
"role": "Maintainer"
45+
}
46+
]
47+
}

config/bootstrap.php

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
namespace CakeSentry;
3+
4+
use Cake\Core\Configure;
5+
use Cake\Error\ErrorTrap;
6+
use Cake\Error\ExceptionTrap;
7+
use CakeSentry\Error\SentryErrorLogger;
8+
9+
Configure::write('Error.logger', SentryErrorLogger::class);
10+
11+
(new ErrorTrap(Configure::read('Error')))->register();
12+
(new ExceptionTrap(Configure::read('Error')))->register();

phpcs.xml

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0"?>
2+
<ruleset name="CakePHP Sentry">
3+
<config name="installed_paths" value="../../cakephp/cakephp-codesniffer" />
4+
5+
<rule ref="CakePHP" />
6+
</ruleset>

phpstan.neon

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
includes:
2+
- vendor/jangregor/phpstan-prophecy/extension.neon
3+
parameters:
4+
paths:
5+
- src
6+
- tests/TestCase
7+
level: 5
8+
bootstrapFiles:
9+
- tests/bootstrap.php

phpunit.xml

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<phpunit
4+
colors="true"
5+
processIsolation="false"
6+
stopOnFailure="false"
7+
bootstrap="./tests/bootstrap.php"
8+
backupGlobals="true"
9+
>
10+
11+
<testsuites>
12+
<testsuite name="cakephp">
13+
<directory>./tests/TestCase/</directory>
14+
</testsuite>
15+
</testsuites>
16+
17+
<!-- Prevent coverage reports from looking in tests, vendors, config folders -->
18+
<filter>
19+
<whitelist>
20+
<directory suffix=".php">./src/</directory>
21+
</whitelist>
22+
</filter>
23+
</phpunit>

0 commit comments

Comments
 (0)