|
| 1 | +# Laravel HTTP Client Global Logger |
| 2 | + |
| 3 | +[](https://packagist.org/packages/onlime/laravel-http-client-global-logger) |
| 4 | +[](https://packagist.org/packages/onlime/laravel-http-client-global-logger) |
| 5 | +[](https://packagist.org/packages/onlime/laravel-http-client-global-logger) |
| 6 | +[](https://github.com/onlime/laravel-http-client-global-logger/blob/main/LICENSE) |
| 7 | + |
| 8 | +A super simple global logger for the [Laravel HTTP Client](https://laravel.com/docs/http-client). |
| 9 | + |
| 10 | +## Installation |
| 11 | + |
| 12 | +You can install the package via Composer: |
| 13 | + |
| 14 | +```bash |
| 15 | +$ composer require onlime/laravel-http-client-global-logger |
| 16 | +``` |
| 17 | + |
| 18 | +## Configuration |
| 19 | + |
| 20 | +This is a zero-configuration package. It is auto-discovered by Laravel and global logging is enabled by default. **No further configuration needed - you may skip directly to the [Usage](#usage) section below.** |
| 21 | + |
| 22 | +Optionally publish the config file with: |
| 23 | + |
| 24 | + ```bash |
| 25 | + $ php artisan vendor:publish --provider="Onlime\LaravelHttpClientGlobalLogger\Providers\ServiceProvider" |
| 26 | + ``` |
| 27 | + |
| 28 | +You may override its configuration in your `.env` - the following environment vars are supported: |
| 29 | + |
| 30 | +- `HTTP_CLIENT_GLOBAL_LOGGER_ENABLED` (bool) |
| 31 | +- `HTTP_CLIENT_GLOBAL_LOGGER_MIXIN` (bool) |
| 32 | +- `HTTP_CLIENT_GLOBAL_LOGGER_CHANNEL` (string) |
| 33 | +- `HTTP_CLIENT_GLOBAL_LOGGER_LOGFILE` (string) |
| 34 | +- `HTTP_CLIENT_GLOBAL_LOGGER_REQUEST_FORMAT` (string) |
| 35 | +- `HTTP_CLIENT_GLOBAL_LOGGER_RESPONSE_FORMAT` (string) |
| 36 | +- `HTTP_CLIENT_GLOBAL_LOGGER_OBFUSCATE_ENABLED` (bool) |
| 37 | +- `HTTP_CLIENT_GLOBAL_LOGGER_OBFUSCATE_REPLACEMENT` (string) |
| 38 | + |
| 39 | +(look into `config/http-client-global-logger.php` for further configuration and explanation) |
| 40 | + |
| 41 | +## Features |
| 42 | + |
| 43 | +Using the logger will log both the request and response of an external HTTP request made with the [Laravel HTTP Client](https://laravel.com/docs/http-client). |
| 44 | + |
| 45 | +- Multi-line log records that contain full request/response information (including all headers and body) |
| 46 | +- Logging into separate logfile `http-client.log`. You're free to override this and use your own logging channel or just log to a different logfile. |
| 47 | +- Full support of [Guzzle MessageFormatter](https://github.com/guzzle/guzzle/blob/master/src/MessageFormatter.php) variable substitutions for highly customized log messages. |
| 48 | +- **Variant 1: Global logging** (default) |
| 49 | + - Zero-configuration: Global logging is enabled by default in this package. |
| 50 | + - Simple and performant implementation using `RequestSending` / `ResponseReceived` event listeners |
| 51 | + - Obfuscation of common credentials passed in request (e.g. `Authorization` header's Bearer token) |
| 52 | +- **Variant 2: Mixin** (`HTTP_CLIENT_GLOBAL_LOGGER_MIXIN=true`) |
| 53 | + - Enabled only on individual HTTP Client instances, using `Http::log()` - no global logging. |
| 54 | + - Log channel name can be set per HTTP Client instance by passing a name to `Http::log($name)` |
| 55 | + |
| 56 | +## Usage |
| 57 | + |
| 58 | +### Variant 1: Global Logging |
| 59 | + |
| 60 | +**Just use Laravel HTTP Client as always - no need to configure anything!** |
| 61 | + |
| 62 | +```php |
| 63 | +Http::get('https://example.com'); |
| 64 | +``` |
| 65 | + |
| 66 | +Slightly more complex example: |
| 67 | + |
| 68 | +```php |
| 69 | +$client = Http::withOptions([ |
| 70 | + 'base_uri' => 'https://example.com', |
| 71 | + 'allow_redirects' => false, |
| 72 | +]); |
| 73 | +$response = $client->get('/user'); |
| 74 | +``` |
| 75 | + |
| 76 | +### Variant 2: Mixin Variant |
| 77 | + |
| 78 | +If you enable mixin variant, global logging will be turned off. Put this into your `.env`: |
| 79 | + |
| 80 | +```ini |
| 81 | +HTTP_CLIENT_GLOBAL_LOGGER_MIXIN=true |
| 82 | +``` |
| 83 | + |
| 84 | +You could then turn on logging individually on each HTTP Client instance, using the `log()` method: |
| 85 | + |
| 86 | +```php |
| 87 | +Http::log()->get('https://example.com'); |
| 88 | +``` |
| 89 | + |
| 90 | +Logging with custom channel name (if not specified, defaults to current environment, such as `production` or `local`): |
| 91 | + |
| 92 | +```php |
| 93 | +Http::log('my-api')->get('https://example.com'); |
| 94 | +``` |
| 95 | + |
| 96 | +Slightly more complex example: |
| 97 | + |
| 98 | +```php |
| 99 | +$client = Http::log('my-api')->withOptions([ |
| 100 | + 'base_uri' => 'https://example.com', |
| 101 | + 'allow_redirects' => false, |
| 102 | +]); |
| 103 | +$response = $client->get('/user'); |
| 104 | +``` |
| 105 | + |
| 106 | +## Logging example |
| 107 | + |
| 108 | +By default, logs are written to a separate logfile `http-client.log`. |
| 109 | + |
| 110 | +Log entry example: |
| 111 | + |
| 112 | +``` |
| 113 | +[2021-07-11 11:29:58] local.INFO: REQUEST: GET https://example.com/user |
| 114 | +GET /user HTTP/1.1 |
| 115 | +User-Agent: GuzzleHttp/7 |
| 116 | +Host: example.com |
| 117 | +Authorization: Bearer ******************* |
| 118 | +[2021-07-11 11:29:58] local.INFO: RESPONSE: HTTP/1.1 200 OK |
| 119 | +HTTP/1.1 200 OK |
| 120 | +Date: Fri, 18 Jun 2021 09:29:58 GMT |
| 121 | +Server: nginx |
| 122 | +Content-Type: application/json |
| 123 | +{"username":"foo","email":"foo@example.com"} |
| 124 | +``` |
| 125 | + |
| 126 | +## FAQ |
| 127 | + |
| 128 | +### How does this package differ from `bilfeldt/laravel-http-client-logger` ? |
| 129 | + |
| 130 | +Honestly, I did not really look into [bilfeldt/laravel-http-client-logger](https://github.com/bilfeldt/laravel-http-client-logger), as my primary goal was to build a global logger for Laravel HTTP Client without any added bulk. Global logging currently (as of July 2021) is still an open issue, see [bilfeldt/laravel-http-client-logger#2 - Add global logging](https://github.com/bilfeldt/laravel-http-client-logger/issues/2). |
| 131 | + |
| 132 | +Both packages provide a different feature set and have those advantages: |
| 133 | + |
| 134 | +- [onlime/laravel-http-client-global-logger](https://github.com/onlime/laravel-http-client-global-logger) (this package) |
| 135 | + - global logging |
| 136 | + - auto-configured log channel `http-client` to log to a separate `http-client.log` file |
| 137 | + - Full support of [Guzzle MessageFormatter](https://github.com/guzzle/guzzle/blob/master/src/MessageFormatter.php) variable substitutions for highly customized log messages. |
| 138 | + - obfuscation of credentials in HTTP Client requests |
| 139 | +- [bilfeldt/laravel-http-client-logger](https://github.com/bilfeldt/laravel-http-client-logger) |
| 140 | + - conditional logging using `logWhen($condition)` |
| 141 | + - filtering of logs by HTTP response codes |
| 142 | + - currently still supports PHP 7.4+ |
| 143 | + |
| 144 | +So, my recommendation: If you need global logging without any extra configuration and without changing a line of code in your project, go for my package. If you don't want to log everything and wish to filter by HTTP response code, go for [Bilfeldt](https://github.com/bilfeldt)'s package. **But don't install both!** |
| 145 | + |
| 146 | +## Caveats |
| 147 | + |
| 148 | +- This package currently uses two different implementations for logging. In the preferred variant 1 (global logging), it is currently not possible to configure the [log channel name](https://laravel.com/docs/logging#configuring-the-channel-name) which defaults to current environment, such as `production` or `local`. If you with to use Laravel HTTP Client to access multiple different external APIs, it is nice to explicitely distinguish between them by different log channel names. |
| 149 | + |
| 150 | + As a workaround, I have implemented another way of logging through `Http::log()` method as mixin. But of course, we should combine both variants into a single one for a cleaner codebase. |
| 151 | + |
| 152 | +- Very basic obfuscation support using regex with lookbehind assertions (e.g. `/(?<=Authorization:\sBearer ).*/m`, modifying formatted log output. It's currently not possible to directly modify request headers or JSON data in request body. |
| 153 | + |
| 154 | +- Obfuscation currently only works in variant 1 (global logging). |
| 155 | + |
| 156 | +## Testing |
| 157 | + |
| 158 | +TBD. |
| 159 | + |
| 160 | +(any help appreciated!) |
| 161 | + |
| 162 | +## Changes |
| 163 | + |
| 164 | +All changes are listed in [CHANGELOG](CHANGELOG.md) |
| 165 | + |
| 166 | +## Authors |
| 167 | + |
| 168 | +Author of this shitty little package is **[Philip Iezzi (Onlime GmbH)](https://www.onlime.ch/)**. |
| 169 | + |
| 170 | +## License |
| 171 | + |
| 172 | +This package is licenced under the [MIT license](LICENSE) however support is more than welcome. |
0 commit comments