Skip to content

Commit 84f8368

Browse files
authored
Merge pull request #44 from dotkernel/issue-43
Issue #43: Control the contents of `extra` in error log.
2 parents c0dcf58 + 51786fc commit 84f8368

Some content is hidden

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

43 files changed

+2719
-69
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ clover.xml
22
coveralls-upload.json
33
.phpunit.result.cache
44
.phpcs-cache
5+
config/log.global.php
6+
config/error-handling.global.php
57

68
# Created by .ignore support plugin (hsz.mobi)
79
### JetBrains template

README.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
11
# dot-errorhandler
22

3-
Error Logging Handler for Dotkernel
3+
dot-errorhandler is Dotkernel's PSR-15 compliant error handler.
4+
5+
## Documentation
6+
7+
Documentation is available at: https://docs.dotkernel.org/dot-errorhandler/
8+
9+
## Badges
410

511
![OSS Lifecycle](https://img.shields.io/osslifecycle/dotkernel/dot-errorhandler)
612
![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-errorhandler/4.1.1)
713

814
[![GitHub issues](https://img.shields.io/github/issues/dotkernel/dot-errorhandler)](https://github.com/dotkernel/dot-errorhandler/issues)
915
[![GitHub forks](https://img.shields.io/github/forks/dotkernel/dot-errorhandler)](https://github.com/dotkernel/dot-errorhandler/network)
1016
[![GitHub stars](https://img.shields.io/github/stars/dotkernel/dot-errorhandler)](https://github.com/dotkernel/dot-errorhandler/stargazers)
11-
[![GitHub license](https://img.shields.io/github/license/dotkernel/dot-errorhandler)](https://github.com/dotkernel/dot-errorhandler/blob/4.0/LICENSE)
17+
[![GitHub license](https://img.shields.io/github/license/dotkernel/dot-errorhandler)](https://github.com/dotkernel/dot-errorhandler/blob/4.1/LICENSE)
1218

13-
[![Build Static](https://github.com/dotkernel/dot-errorhandler/actions/workflows/continuous-integration.yml/badge.svg?branch=4.0)](https://github.com/dotkernel/dot-errorhandler/actions/workflows/continuous-integration.yml)
19+
[![Build Static](https://github.com/dotkernel/dot-errorhandler/actions/workflows/continuous-integration.yml/badge.svg?branch=4.1)](https://github.com/dotkernel/dot-errorhandler/actions/workflows/continuous-integration.yml)
1420
[![codecov](https://codecov.io/gh/dotkernel/dot-errorhandler/branch/4.0/graph/badge.svg?token=0KIJARS5RS)](https://codecov.io/gh/dotkernel/dot-errorhandler)
1521

1622
## Adding the error handler

composer.json

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,14 @@
66
"homepage": "https://github.com/dotkernel/dot-errorhandler",
77
"authors": [
88
{
9-
"name": "DotKernel Team",
9+
"name": "Dotkernel Team",
1010
"email": "team@dotkernel.com"
1111
}
1212
],
1313
"keywords": [
1414
"error",
1515
"errorhandler",
16-
"factories",
17-
"container",
18-
"laminas",
19-
"mezzio",
20-
"service-manager"
16+
"error_log"
2117
],
2218
"config": {
2319
"sort-packages": true,
@@ -27,18 +23,19 @@
2723
},
2824
"require": {
2925
"php": "~8.2.0 || ~8.3.0 || ~8.4.0",
30-
"dotkernel/dot-log": "^4.1.0",
31-
"laminas/laminas-diactoros": "^3.3",
32-
"laminas/laminas-stratigility": "^3.11",
33-
"mezzio/mezzio": "^3.19",
26+
"dotkernel/dot-log": "^5.0",
27+
"laminas/laminas-diactoros": "^3.5",
28+
"laminas/laminas-stdlib": "^3.20",
29+
"laminas/laminas-stratigility": "^3.13",
30+
"mezzio/mezzio": "^3.20.1",
3431
"psr/http-message": "^1.0 || ^2.0",
35-
"psr/http-server-middleware": "^1.0"
32+
"psr/http-server-middleware": "^1.0.2"
3633
},
3734
"require-dev": {
38-
"laminas/laminas-coding-standard": "^3.0",
39-
"mikey179/vfsstream": "^1.6.7",
40-
"phpunit/phpunit": "^10.5",
41-
"vimeo/psalm": "^6.0"
35+
"laminas/laminas-coding-standard": "^3.0.1",
36+
"mikey179/vfsstream": "^1.6.12",
37+
"phpunit/phpunit": "^10.5.45",
38+
"vimeo/psalm": "6.6.2"
4239
},
4340
"autoload": {
4441
"psr-4": {
@@ -60,7 +57,6 @@
6057
"cs-check": "phpcs",
6158
"cs-fix": "phpcbf",
6259
"test": "phpunit --colors=always",
63-
"test-coverage": "phpunit --colors=always --coverage-clover clover.xml",
6460
"static-analysis": "psalm --shepherd --stats"
6561
}
6662
}
Lines changed: 73 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,84 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
use Dot\ErrorHandler\ErrorHandlerInterface;
6+
use Dot\ErrorHandler\Extra\ExtraProvider;
7+
use Dot\ErrorHandler\Extra\Processor\CookieProcessor;
8+
use Dot\ErrorHandler\Extra\Processor\HeaderProcessor;
9+
use Dot\ErrorHandler\Extra\Processor\ProcessorInterface;
10+
use Dot\ErrorHandler\Extra\Processor\RequestProcessor;
11+
use Dot\ErrorHandler\Extra\Processor\ServerProcessor;
12+
use Dot\ErrorHandler\Extra\Processor\SessionProcessor;
13+
use Dot\ErrorHandler\Extra\Processor\TraceProcessor;
14+
use Dot\ErrorHandler\Extra\Provider\CookieProvider;
15+
use Dot\ErrorHandler\Extra\Provider\HeaderProvider;
16+
use Dot\ErrorHandler\Extra\Provider\RequestProvider;
17+
use Dot\ErrorHandler\Extra\Provider\ServerProvider;
18+
use Dot\ErrorHandler\Extra\Provider\SessionProvider;
19+
use Dot\ErrorHandler\Extra\Provider\TraceProvider;
20+
use Dot\ErrorHandler\Extra\ReplacementStrategy;
421
use Dot\ErrorHandler\LogErrorHandler;
522

623
return [
7-
'dependencies' => [
24+
'dependencies' => [
825
'aliases' => [
926
ErrorHandlerInterface::class => LogErrorHandler::class,
10-
]
27+
],
1128
],
1229
'dot-errorhandler' => [
13-
'loggerEnabled' => true,
14-
'logger' => 'dot-log.default_logger'
15-
]
30+
'loggerEnabled' => true,
31+
'logger' => 'dot-log.default_logger',
32+
ExtraProvider::CONFIG_KEY => [
33+
CookieProvider::class => [
34+
'enabled' => false,
35+
'processor' => [
36+
'class' => CookieProcessor::class,
37+
'replacementStrategy' => ReplacementStrategy::Full,
38+
'sensitiveParameters' => [
39+
ProcessorInterface::ALL,
40+
],
41+
],
42+
],
43+
HeaderProvider::class => [
44+
'enabled' => false,
45+
'processor' => [
46+
'class' => HeaderProcessor::class,
47+
'replacementStrategy' => ReplacementStrategy::Full,
48+
],
49+
],
50+
RequestProvider::class => [
51+
'enabled' => false,
52+
'processor' => [
53+
'class' => RequestProcessor::class,
54+
'replacementStrategy' => ReplacementStrategy::Full,
55+
'sensitiveParameters' => [
56+
'password',
57+
],
58+
],
59+
],
60+
ServerProvider::class => [
61+
'enabled' => false,
62+
'processor' => [
63+
'class' => ServerProcessor::class,
64+
'replacementStrategy' => ReplacementStrategy::Full,
65+
'sensitiveParameters' => [
66+
ProcessorInterface::ALL,
67+
],
68+
],
69+
],
70+
SessionProvider::class => [
71+
'enabled' => false,
72+
'processor' => [
73+
'class' => SessionProcessor::class,
74+
],
75+
],
76+
TraceProvider::class => [
77+
'enabled' => true,
78+
'processor' => [
79+
'class' => TraceProcessor::class,
80+
],
81+
],
82+
],
83+
],
1684
];

config/log.global.php.dist

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,32 @@
11
<?php
22

3+
declare(strict_types=1);
4+
5+
use Dot\Log\Formatter\Json;
6+
use Dot\Log\Logger;
7+
38
return [
49
'dot_log' => [
510
'loggers' => [
611
'default_logger' => [
712
'writers' => [
813
'FileWriter' => [
9-
'name' => 'stream',
10-
'priority' => \Dot\Log\Logger::ALERT,
14+
'name' => 'stream',
15+
'level' => Logger::ALERT,
1116
'options' => [
1217
'stream' => __DIR__ . '/../../log/error-log-{Y}-{m}-{d}.log',
1318
// explicitly log all messages
14-
'filters' => [
19+
'filters' => [
1520
'allMessages' => [
16-
'name' => 'priority',
21+
'name' => 'level',
1722
'options' => [
1823
'operator' => '>=',
19-
'priority' => \Dot\Log\Logger::EMERG,
24+
'level' => Logger::EMERG,
2025
],
2126
],
2227
],
2328
'formatter' => [
24-
'name' => \Dot\Log\Formatter\Json::class,
29+
'name' => Json::class,
2530
],
2631
],
2732
],

docs/book/v4/extra/cookie.md

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# Log cookie data
2+
3+
Looking at `dot-errorhandler`'s config file, the array found at `CookieProvider::class` allows you to configure the behaviour of this provider:
4+
5+
- **enabled**: enabled/disable this provider
6+
- **processor**: an array configuring the data processor to be used by the **CookieProvider**:
7+
- **class**: data processor class implementing `Dot\ErrorHandler\Extra\Processor\ProcessorInterface`
8+
- **replacementStrategy**: whether to replace specific cookie values completely or partially
9+
- **sensitiveParameters**: an array of cookies names that may contain sensitive information so their value should be masked partially/completely
10+
11+
## Configure provider
12+
13+
By default, **CookieProvider** is disabled.
14+
It can be enabled only by setting **enabled** to **true**.
15+
16+
If **enabled** is set to **true**, your log file will contain an additional field under the `extra` key, called `cookie`.
17+
If **enabled** is set to **false**, no additional field is added under the `extra` key.
18+
19+
## Configure processor
20+
21+
From here, we assume that **enabled** is set to **true**.
22+
23+
If **processor** is missing/empty, the processor is ignored the provider will log the raw data available.
24+
If **processor** is specified, but **class** is missing/invalid, the processor is ignored and the provider will log the raw data available.
25+
26+
From here, we assume that **processor**.**class** is valid.
27+
28+
### Replacement strategy
29+
30+
This value should be an instance of `Dot\ErrorHandler\Extra\ReplacementStrategy`.
31+
32+
If **replacementStrategy** is missing/invalid, the default **replacementStrategy** is used, which is `ReplacementStrategy::Full`.
33+
Else, the value used should be one of:
34+
35+
- `ReplacementStrategy::Partial` for half-string replacements (e.g.: "abcdef" becomes "abc***")
36+
- `ReplacementStrategy::Full` for full-string replacements (e.g.: "abcdef" becomes "******")
37+
38+
### Sensitive parameters
39+
40+
If **sensitiveParameters** is missing/empty, the processor is ignored the provider will log the raw data available.
41+
This is because without a set of **sensitiveParameters**, the processor is unable to determine which key needs to be processed or left untouched.
42+
When specifying the array of **sensitiveParameters**, there are two possibilities:
43+
44+
- use the constant `ProcessorInterface::ALL`, meaning alter all cookie values using the strategy specified by the **replacementStrategy**
45+
46+
```php
47+
'sensitiveParameters' => [
48+
Dot\ErrorHandler\Extra\Processor\ProcessorInterface::ALL,
49+
],
50+
```
51+
52+
- use exact strings to list the cookies for which the values should be altered using the strategy specified by the **replacementStrategy**
53+
54+
```php
55+
'sensitiveParameters' => [
56+
'rememberMe',
57+
],
58+
```
59+
60+
> **CookieProcessor** uses EXACT cookie name lookups.
61+
> In order to alter the value of a cookie, you need to specify the exact cookie name.
62+
63+
> The config `sensitiveParameters` is case-insensitive.
64+
65+
## Why should I use a processor
66+
67+
Consider the following request cookies:
68+
69+
```text
70+
[
71+
"sessionId" => "feb21b39f9c54e3a49af1f862acc8300",
72+
"language" => "en",
73+
]
74+
```
75+
76+
Without a **CookieProcessor**, the plain text session cookie identifier would end up saved in the log file:
77+
78+
```text
79+
..."extra":{"file":"/path/to/some/class.php","line":314,"cookie":{"sessionId":"feb21b39f9c54e3a49af1f862acc8300","language":"en"},...
80+
```
81+
82+
But, with a properly configured **CookieProcessor**:
83+
84+
```php
85+
'processor' => [
86+
'class' => CookieProcessor::class,
87+
'replacementStrategy' => ReplacementStrategy::Full,
88+
'sensitiveParameters' => [
89+
'sessionId',
90+
],
91+
],
92+
```
93+
94+
the logged cookie data becomes:
95+
96+
```text
97+
..."extra":{"file":"/path/to/some/class.php","line":314,"cookie":{"sessionId":"********************************","language":"en"},...
98+
```
99+
100+
## Custom processor
101+
102+
If the existing processor does not offer enough features, you can create a custom processor.
103+
The custom processor must implement `Dot\ErrorHandler\Extra\Processor\ProcessorInterface` or extend `Dot\ErrorHandler\Extra\Processor\AbstractProcessor`, which already implements `Dot\ErrorHandler\Extra\Processor\ProcessorInterface`.
104+
Once the custom processor is ready, you need to configure **CookieProvider** to use it.
105+
For this, open `dot-errorhandler`'s config file and - under **CookieProvider::class** - set **processor**.**class** to the class string of your custom processor:
106+
107+
```php
108+
CookieProvider::class => [
109+
'enabled' => false,
110+
'processor' => [
111+
'class' => CustomCookieProcessor::class,
112+
'replacementStrategy' => ReplacementStrategy::Full,
113+
'sensitiveParameters' => [
114+
ProcessorInterface::ALL,
115+
],
116+
],
117+
],
118+
```
119+
120+
Using this, cookie data will be processed by `CustomCookieProcessor` and logged as provided by this new processor.

0 commit comments

Comments
 (0)